Procházet zdrojové kódy

Merge pull request #3340 from IvanSavenko/crashfixes3

Crashfixes
Ivan Savenko před 1 rokem
rodič
revize
f40e711721

+ 5 - 0
lib/CGameInfoCallback.cpp

@@ -721,6 +721,11 @@ bool CGameInfoCallback::isPlayerMakingTurn(PlayerColor player) const
 	return gs->actingPlayers.count(player);
 }
 
+CGameInfoCallback::CGameInfoCallback():
+	gs(nullptr)
+{
+}
+
 CGameInfoCallback::CGameInfoCallback(CGameState * GS):
 	gs(GS)
 {

+ 1 - 1
lib/CGameInfoCallback.h

@@ -134,7 +134,7 @@ class DLL_LINKAGE CGameInfoCallback : public IGameInfoCallback
 protected:
 	CGameState * gs;//todo: replace with protected const getter, only actual Server and Client objects should hold game state
 
-	CGameInfoCallback() = default;
+	CGameInfoCallback();
 	CGameInfoCallback(CGameState * GS);
 	bool hasAccess(std::optional<PlayerColor> playerId) const;
 

+ 19 - 3
lib/mapObjectConstructors/AObjectTypeHandler.cpp

@@ -20,6 +20,19 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
+AObjectTypeHandler::AObjectTypeHandler() = default;
+
+AObjectTypeHandler::~AObjectTypeHandler()
+{
+	// FIXME: currently on Android there is a weird crash in destructor of 'base' member
+	// this code attempts to localize and fix this crash
+	if (base)
+	{
+		base->clear();
+		base.reset();
+	}
+}
+
 std::string AObjectTypeHandler::getJsonKey() const
 {
 	return modScope + ':' + subTypeName;
@@ -55,7 +68,8 @@ static ui32 loadJsonOrMax(const JsonNode & input)
 
 void AObjectTypeHandler::init(const JsonNode & input)
 {
-	base = input["base"];
+	if (!input["base"].isNull())
+		base = std::make_unique<JsonNode>(input["base"]);
 
 	if (!input["rmg"].isNull())
 	{
@@ -72,7 +86,8 @@ void AObjectTypeHandler::init(const JsonNode & input)
 	for (auto entry : input["templates"].Struct())
 	{
 		entry.second.setType(JsonNode::JsonType::DATA_STRUCT);
-		JsonUtils::inherit(entry.second, base);
+		if (base)
+			JsonUtils::inherit(entry.second, *base);
 
 		auto * tmpl = new ObjectTemplate;
 		tmpl->id = Obj(type);
@@ -171,7 +186,8 @@ void AObjectTypeHandler::addTemplate(const std::shared_ptr<const ObjectTemplate>
 void AObjectTypeHandler::addTemplate(JsonNode config)
 {
 	config.setType(JsonNode::JsonType::DATA_STRUCT); // ensure that input is not null
-	JsonUtils::inherit(config, base);
+	if (base)
+		JsonUtils::inherit(config, *base);
 	auto * tmpl = new ObjectTemplate;
 	tmpl->id = Obj(type);
 	tmpl->subid = subtype;

+ 3 - 2
lib/mapObjectConstructors/AObjectTypeHandler.h

@@ -27,7 +27,7 @@ class DLL_LINKAGE AObjectTypeHandler : public boost::noncopyable
 
 	RandomMapInfo rmgInfo;
 
-	JsonNode base; /// describes base template
+	std::unique_ptr<JsonNode> base; /// describes base template
 
 	std::vector<std::shared_ptr<const ObjectTemplate>> templates;
 
@@ -54,7 +54,8 @@ protected:
 	virtual void initTypeData(const JsonNode & input);
 public:
 
-	virtual ~AObjectTypeHandler() = default;
+	AObjectTypeHandler();
+	virtual ~AObjectTypeHandler();
 
 	si32 getIndex() const;
 	si32 getSubIndex() const;

+ 0 - 1
lib/mapObjectConstructors/CObjectClassesHandler.cpp

@@ -443,7 +443,6 @@ void CObjectClassesHandler::generateExtraMonolithsForRMG(ObjectClass * container
 		//deep copy of noncopyable object :?
 		auto newPortal = std::make_shared<CDefaultObjectTypeHandler<CGMonolith>>();
 		newPortal->rmgInfo = portal->getRMGInfo();
-		newPortal->base = portal->base; //not needed?
 		newPortal->templates = portal->getTemplates();
 		newPortal->sounds = portal->getSounds();
 		newPortal->aiValue = portal->getAiValue();

+ 6 - 1
lib/modding/CModInfo.cpp

@@ -49,7 +49,11 @@ CModInfo::CModInfo(const std::string & identifier, const JsonNode & local, const
 	validation(PENDING),
 	config(addMeta(config, identifier))
 {
-	verificationInfo.name = config["name"].String();
+	if (!config["name"].String().empty())
+		verificationInfo.name = config["name"].String();
+	else
+		verificationInfo.name = identifier;
+
 	verificationInfo.version = CModVersion::fromString(config["version"].String());
 	verificationInfo.parent = identifier.substr(0, identifier.find_last_of('.'));
 	if(verificationInfo.parent == identifier)
@@ -189,6 +193,7 @@ bool CModInfo::checkModGameplayAffecting() const
 
 const ModVerificationInfo & CModInfo::getVerificationInfo() const
 {
+	assert(!verificationInfo.name.empty());
 	return verificationInfo;
 }
 

+ 6 - 0
lib/serializer/Connection.cpp

@@ -148,6 +148,9 @@ void CConnection::flushBuffers()
 	if(!enableBufferedWrite)
 		return;
 
+	if (!socket)
+		throw std::runtime_error("Can't write to closed socket!");
+
 	try
 	{
 		asio::write(*socket, connectionBuffers->writeBuffer);
@@ -164,6 +167,9 @@ void CConnection::flushBuffers()
 
 int CConnection::write(const void * data, unsigned size)
 {
+	if (!socket)
+		throw std::runtime_error("Can't write to closed socket!");
+
 	try
 	{
 		if(enableBufferedWrite)

+ 1 - 5
server/CGameHandler.cpp

@@ -489,11 +489,6 @@ void CGameHandler::handleReceivedPack(CPackForServer * pack)
 	vstd::clear_pointer(pack);
 }
 
-
-CGameHandler::CGameHandler()
-	: turnTimerHandler(*this)
-{}
-
 CGameHandler::CGameHandler(CVCMIServer * lobby)
 	: lobby(lobby)
 	, heroPool(std::make_unique<HeroPoolProcessor>(this))
@@ -518,6 +513,7 @@ CGameHandler::~CGameHandler()
 {
 	delete spellEnv;
 	delete gs;
+	gs = nullptr;
 }
 
 void CGameHandler::reinitScripting()

+ 1 - 2
server/CGameHandler.h

@@ -92,8 +92,7 @@ public:
 	bool isAllowedExchange(ObjectInstanceID id1, ObjectInstanceID id2);
 	void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
 
-	CGameHandler();
-	CGameHandler(CVCMIServer * lobby);
+	explicit CGameHandler(CVCMIServer * lobby);
 	~CGameHandler();
 
 	//////////////////////////////////////////////////////////////////////////