1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Merge pull request #3147 from IvanSavenko/serialization_refactor

Serialization refactor - remove VLC from saved games
This commit is contained in:
Ivan Savenko 2023-11-11 17:35:01 +02:00 committed by GitHub
commit 07472d3b05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
94 changed files with 1236 additions and 2418 deletions

View File

@ -421,14 +421,14 @@ void AIGateway::requestRealized(PackageApplied * pa)
NET_EVENT_HANDLER;
if(status.haveTurn())
{
if(pa->packType == typeList.getTypeID<EndTurn>())
if(pa->packType == CTypeList::getInstance().getTypeID<EndTurn>(nullptr))
{
if(pa->result)
status.madeTurn();
}
}
if(pa->packType == typeList.getTypeID<QueryReply>())
if(pa->packType == CTypeList::getInstance().getTypeID<QueryReply>(nullptr))
{
status.receivedAnswerConfirmation(pa->requestID, pa->result);
}

View File

@ -505,14 +505,14 @@ void VCAI::requestRealized(PackageApplied * pa)
NET_EVENT_HANDLER;
if(status.haveTurn())
{
if(pa->packType == typeList.getTypeID<EndTurn>())
if(pa->packType == CTypeList::getInstance().getTypeID<EndTurn>(nullptr))
{
if(pa->result)
status.madeTurn();
}
}
if(pa->packType == typeList.getTypeID<QueryReply>())
if(pa->packType == CTypeList::getInstance().getTypeID<QueryReply>(nullptr))
{
status.receivedAnswerConfirmation(pa->requestID, pa->result);
}

View File

@ -1237,10 +1237,10 @@ void CPlayerInterface::showArtifactAssemblyDialog(const Artifact * artifact, con
void CPlayerInterface::requestRealized( PackageApplied *pa )
{
if(pa->packType == typeList.getTypeID<MoveHero>())
if(pa->packType == CTypeList::getInstance().getTypeID<MoveHero>(nullptr))
movementController->onMoveHeroApplied();
if(pa->packType == typeList.getTypeID<QueryReply>())
if(pa->packType == CTypeList::getInstance().getTypeID<QueryReply>(nullptr))
movementController->onQueryReplyApplied();
}

View File

@ -47,7 +47,7 @@
#include "../lib/modding/ModIncompatibility.h"
#include "../lib/rmg/CMapGenOptions.h"
#include "../lib/filesystem/Filesystem.h"
#include "../lib/registerTypes/RegisterTypes.h"
#include "../lib/registerTypes/RegisterTypesLobbyPacks.h"
#include "../lib/serializer/Connection.h"
#include "../lib/serializer/CMemorySerializer.h"
@ -94,7 +94,7 @@ public:
T * ptr = static_cast<T *>(pack);
ApplyOnLobbyHandlerNetPackVisitor visitor(*handler);
logNetwork->trace("\tImmediately apply on lobby: %s", typeList.getTypeInfo(ptr)->name());
logNetwork->trace("\tImmediately apply on lobby: %s", typeid(ptr).name());
ptr->visit(visitor);
return visitor.getResult();
@ -105,7 +105,7 @@ public:
T * ptr = static_cast<T *>(pack);
ApplyOnLobbyScreenNetPackVisitor visitor(*handler, lobby);
logNetwork->trace("\tApply on lobby from queue: %s", typeList.getTypeInfo(ptr)->name());
logNetwork->trace("\tApply on lobby from queue: %s", typeid(ptr).name());
ptr->visit(visitor);
}
};
@ -298,7 +298,7 @@ void CServerHandler::applyPacksOnLobbyScreen()
boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
CPackForLobby * pack = packsForLobbyScreen.front();
packsForLobbyScreen.pop_front();
CBaseForLobbyApply * apply = applier->getApplier(typeList.getTypeID(pack)); //find the applier
CBaseForLobbyApply * apply = applier->getApplier(CTypeList::getInstance().getTypeID(pack)); //find the applier
apply->applyOnLobbyScreen(dynamic_cast<CLobbyScreen *>(SEL), this, pack);
GH.windows().totalRedraw();
delete pack;
@ -953,7 +953,7 @@ void CServerHandler::threadHandleConnection()
void CServerHandler::visitForLobby(CPackForLobby & lobbyPack)
{
if(applier->getApplier(typeList.getTypeID(&lobbyPack))->applyOnLobbyHandler(this, &lobbyPack))
if(applier->getApplier(CTypeList::getInstance().getTypeID(&lobbyPack))->applyOnLobbyHandler(this, &lobbyPack))
{
if(!settings["session"]["headless"].Bool())
{

View File

@ -24,6 +24,7 @@
#include "../CCallback.h"
#include "../lib/CConfigHandler.h"
#include "../lib/gameState/CGameState.h"
#include "../lib/CPlayerState.h"
#include "../lib/CThreadHelper.h"
#include "../lib/VCMIDirs.h"
#include "../lib/UnlockGuard.h"
@ -32,7 +33,7 @@
#include "../lib/mapping/CMapService.h"
#include "../lib/pathfinder/CGPathNode.h"
#include "../lib/filesystem/Filesystem.h"
#include "../lib/registerTypes/RegisterTypes.h"
#include "../lib/registerTypes/RegisterTypesClientPacks.h"
#include "../lib/serializer/Connection.h"
#include <memory>
@ -137,8 +138,7 @@ CClient::CClient()
{
waitingRequest.clear();
applier = std::make_shared<CApplier<CBaseForCLApply>>();
registerTypesClientPacks1(*applier);
registerTypesClientPacks2(*applier);
registerTypesClientPacks(*applier);
IObjectInterface::cb = this;
gs = nullptr;
}
@ -523,20 +523,20 @@ void CClient::installNewBattleInterface(std::shared_ptr<CBattleGameInterface> ba
void CClient::handlePack(CPack * pack)
{
CBaseForCLApply * apply = applier->getApplier(typeList.getTypeID(pack)); //find the applier
CBaseForCLApply * apply = applier->getApplier(CTypeList::getInstance().getTypeID(pack)); //find the applier
if(apply)
{
boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
apply->applyOnClBefore(this, pack);
logNetwork->trace("\tMade first apply on cl: %s", typeList.getTypeInfo(pack)->name());
logNetwork->trace("\tMade first apply on cl: %s", typeid(pack).name());
gs->apply(pack);
logNetwork->trace("\tApplied on gs: %s", typeList.getTypeInfo(pack)->name());
logNetwork->trace("\tApplied on gs: %s", typeid(pack).name());
apply->applyOnClAfter(this, pack);
logNetwork->trace("\tMade second apply on cl: %s", typeList.getTypeInfo(pack)->name());
logNetwork->trace("\tMade second apply on cl: %s", typeid(pack).name());
}
else
{
logNetwork->error("Message %s cannot be applied, cannot find applier!", typeList.getTypeInfo(pack)->name());
logNetwork->error("Message %s cannot be applied, cannot find applier!", typeid(pack).name());
}
delete pack;
}

View File

@ -74,6 +74,10 @@ std::string CMapHandler::getTerrainDescr(const int3 & pos, bool rightClick) cons
bool CMapHandler::compareObjectBlitOrder(const CGObjectInstance * a, const CGObjectInstance * b)
{
//FIXME: Optimize
// this method is called A LOT on game start and some parts, e.g. for loops are too slow for that
assert(a && b);
if(!a)
return true;
if(!b)

View File

@ -39,7 +39,7 @@
#include "../../lib/TerrainHandler.h"
#include "../../lib/filesystem/Filesystem.h"
#include "../../lib/serializer/BinaryDeserializer.h"
#include "../../lib/serializer/CLoadFile.h"
#include "../../lib/StartInfo.h"
#include "../../lib/rmg/CMapGenOptions.h"

View File

@ -116,6 +116,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/mapping/MapFormatJson.cpp
${MAIN_LIB_DIR}/mapping/ObstacleProxy.cpp
${MAIN_LIB_DIR}/modding/ActiveModsInSaveList.cpp
${MAIN_LIB_DIR}/modding/CModHandler.cpp
${MAIN_LIB_DIR}/modding/CModInfo.cpp
${MAIN_LIB_DIR}/modding/CModVersion.cpp
@ -132,15 +133,6 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/pathfinder/PathfindingRules.cpp
${MAIN_LIB_DIR}/pathfinder/TurnInfo.cpp
${MAIN_LIB_DIR}/registerTypes/RegisterTypes.cpp
${MAIN_LIB_DIR}/registerTypes/TypesClientPacks1.cpp
${MAIN_LIB_DIR}/registerTypes/TypesClientPacks2.cpp
${MAIN_LIB_DIR}/registerTypes/TypesMapObjects1.cpp
${MAIN_LIB_DIR}/registerTypes/TypesMapObjects2.cpp
${MAIN_LIB_DIR}/registerTypes/TypesMapObjects3.cpp
${MAIN_LIB_DIR}/registerTypes/TypesLobbyPacks.cpp
${MAIN_LIB_DIR}/registerTypes/TypesServerPacks.cpp
${MAIN_LIB_DIR}/rewardable/Configuration.cpp
${MAIN_LIB_DIR}/rewardable/Info.cpp
${MAIN_LIB_DIR}/rewardable/Interface.cpp
@ -180,9 +172,10 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/serializer/BinaryDeserializer.cpp
${MAIN_LIB_DIR}/serializer/BinarySerializer.cpp
${MAIN_LIB_DIR}/serializer/CLoadIntegrityValidator.cpp
${MAIN_LIB_DIR}/serializer/CLoadFile.cpp
${MAIN_LIB_DIR}/serializer/CMemorySerializer.cpp
${MAIN_LIB_DIR}/serializer/Connection.cpp
${MAIN_LIB_DIR}/serializer/CSaveFile.cpp
${MAIN_LIB_DIR}/serializer/CSerializer.cpp
${MAIN_LIB_DIR}/serializer/CTypeList.cpp
${MAIN_LIB_DIR}/serializer/JsonDeserializer.cpp
@ -467,6 +460,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/mapping/MapFormatJson.h
${MAIN_LIB_DIR}/mapping/ObstacleProxy.h
${MAIN_LIB_DIR}/modding/ActiveModsInSaveList.h
${MAIN_LIB_DIR}/modding/CModHandler.h
${MAIN_LIB_DIR}/modding/CModInfo.h
${MAIN_LIB_DIR}/modding/CModVersion.h
@ -475,6 +469,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/modding/ModIncompatibility.h
${MAIN_LIB_DIR}/modding/ModScope.h
${MAIN_LIB_DIR}/modding/ModUtility.h
${MAIN_LIB_DIR}/modding/ModVerificationInfo.h
${MAIN_LIB_DIR}/networkPacks/ArtifactLocation.h
${MAIN_LIB_DIR}/networkPacks/BattleChanges.h
@ -503,6 +498,10 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/pathfinder/TurnInfo.h
${MAIN_LIB_DIR}/registerTypes/RegisterTypes.h
${MAIN_LIB_DIR}/registerTypes/RegisterTypesClientPacks.h
${MAIN_LIB_DIR}/registerTypes/RegisterTypesLobbyPacks.h
${MAIN_LIB_DIR}/registerTypes/RegisterTypesMapObjects.h
${MAIN_LIB_DIR}/registerTypes/RegisterTypesServerPacks.h
${MAIN_LIB_DIR}/rewardable/Configuration.h
${MAIN_LIB_DIR}/rewardable/Info.h
@ -546,9 +545,10 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/serializer/BinaryDeserializer.h
${MAIN_LIB_DIR}/serializer/BinarySerializer.h
${MAIN_LIB_DIR}/serializer/CLoadIntegrityValidator.h
${MAIN_LIB_DIR}/serializer/CLoadFile.h
${MAIN_LIB_DIR}/serializer/CMemorySerializer.h
${MAIN_LIB_DIR}/serializer/Connection.h
${MAIN_LIB_DIR}/serializer/CSaveFile.h
${MAIN_LIB_DIR}/serializer/CSerializer.h
${MAIN_LIB_DIR}/serializer/CTypeList.h
${MAIN_LIB_DIR}/serializer/JsonDeserializer.h

View File

@ -50,6 +50,8 @@ template <typename IdType>
class DLL_LINKAGE EntityT : public Entity
{
public:
using IdentifierType = IdType;
virtual IdType getId() const = 0;
};

View File

@ -53,19 +53,6 @@ public:
std::string getNameTranslated() const override;
void registerIcons(const IconRegistar & cb) const override;
BattleField getId() const override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & name;
h & identifier;
h & isSpecial;
h & graphics;
h & icon;
h & iconIndex;
h & battlefield;
h & impassableHexes;
}
};
class DLL_LINKAGE BattleFieldService : public EntityServiceT<BattleField, BattleFieldInfo>
@ -85,11 +72,6 @@ public:
virtual const std::vector<std::string> & getTypeNames() const override;
virtual std::vector<JsonNode> loadLegacyData() override;
virtual std::vector<bool> getDefaultAllowed() const override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & objects;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -607,75 +607,6 @@ void CArtHandler::loadComponents(CArtifact * art, const JsonNode & node)
}
}
ArtifactID CArtHandler::pickRandomArtifact(CRandomGenerator & rand, int flags, std::function<bool(ArtifactID)> accepts)
{
std::set<ArtifactID> potentialPicks;
// Select artifacts that satisfy provided criterias
for (auto const * artifact : allowedArtifacts)
{
assert(artifact->aClass != CArtifact::ART_SPECIAL); // should be filtered out when allowedArtifacts is initialized
if ((flags & CArtifact::ART_TREASURE) == 0 && artifact->aClass == CArtifact::ART_TREASURE)
continue;
if ((flags & CArtifact::ART_MINOR) == 0 && artifact->aClass == CArtifact::ART_MINOR)
continue;
if ((flags & CArtifact::ART_MAJOR) == 0 && artifact->aClass == CArtifact::ART_MAJOR)
continue;
if ((flags & CArtifact::ART_RELIC) == 0 && artifact->aClass == CArtifact::ART_RELIC)
continue;
if (!accepts(artifact->id))
continue;
potentialPicks.insert(artifact->id);
}
return pickRandomArtifact(rand, potentialPicks);
}
ArtifactID CArtHandler::pickRandomArtifact(CRandomGenerator & rand, std::set<ArtifactID> potentialPicks)
{
// No allowed artifacts at all - give Grail - this can't be banned (hopefully)
// FIXME: investigate how such cases are handled by H3 - some heavily customized user-made maps likely rely on H3 behavior
if (potentialPicks.empty())
{
logGlobal->warn("Failed to find artifact that matches requested parameters!");
return ArtifactID::GRAIL;
}
// Find how many times least used artifacts were picked by randomizer
int leastUsedTimes = std::numeric_limits<int>::max();
for (auto const & artifact : potentialPicks)
if (allocatedArtifacts[artifact] < leastUsedTimes)
leastUsedTimes = allocatedArtifacts[artifact];
// Pick all artifacts that were used least number of times
std::set<ArtifactID> preferredPicks;
for (auto const & artifact : potentialPicks)
if (allocatedArtifacts[artifact] == leastUsedTimes)
preferredPicks.insert(artifact);
assert(!preferredPicks.empty());
ArtifactID artID = *RandomGeneratorUtil::nextItem(preferredPicks, rand);
allocatedArtifacts[artID] += 1; // record +1 more usage
return artID;
}
ArtifactID CArtHandler::pickRandomArtifact(CRandomGenerator & rand, std::function<bool(ArtifactID)> accepts)
{
return pickRandomArtifact(rand, 0xff, std::move(accepts));
}
ArtifactID CArtHandler::pickRandomArtifact(CRandomGenerator & rand, int flags)
{
return pickRandomArtifact(rand, flags, [](const ArtifactID &) { return true; });
}
void CArtHandler::makeItCreatureArt(CArtifact * a, bool onlyCreature)
{
if (onlyCreature)
@ -723,7 +654,6 @@ bool CArtHandler::legalArtifact(const ArtifactID & id)
void CArtHandler::initAllowedArtifactsList(const std::vector<bool> &allowed)
{
allowedArtifacts.clear();
allocatedArtifacts.clear();
for (ArtifactID i=ArtifactID::SPELLBOOK; i < ArtifactID(static_cast<si32>(objects.size())); i.advance(1))
{

View File

@ -53,12 +53,6 @@ public:
bool isCombined() const;
const std::vector<CArtifact*> & getConstituents() const;
const std::vector<CArtifact*> & getPartOf() const;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & constituents;
h & partOf;
}
};
class DLL_LINKAGE CScrollArtifact
@ -83,12 +77,6 @@ public:
const std::vector <std::pair<ui16, Bonus>> & getBonusesPerLevel() const;
std::vector <std::pair<ui16, Bonus>> & getThresholdBonuses();
const std::vector <std::pair<ui16, Bonus>> & getThresholdBonuses() const;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & bonusesPerLevel;
h & thresholdBonuses;
}
};
// Container for artifacts. Not for instances.
@ -144,25 +132,6 @@ public:
// Is used for testing purposes only
void setImage(int32_t iconIndex, std::string image, std::string large);
template <typename Handler> void serialize(Handler & h, const int version)
{
h & static_cast<CBonusSystemNode&>(*this);
h & static_cast<CCombinedArtifact&>(*this);
h & static_cast<CGrowingArtifact&>(*this);
h & image;
h & large;
h & advMapDef;
h & iconIndex;
h & price;
h & possibleSlots;
h & aClass;
h & id;
h & modScope;
h & identifier;
h & warMachine;
h & onlyOnWaterMap;
}
CArtifact();
~CArtifact();
@ -172,9 +141,6 @@ public:
class DLL_LINKAGE CArtHandler : public CHandlerBase<ArtifactID, Artifact, CArtifact, ArtifactService>
{
public:
/// Stores number of times each artifact was placed on map via randomization
std::map<ArtifactID, int> allocatedArtifacts;
/// List of artifacts allowed on the map
std::vector<CArtifact *> allowedArtifacts;
@ -182,12 +148,6 @@ public:
static CArtifact::EartClass stringToClass(const std::string & className); //TODO: rework EartClass to make this a constructor
/// Gets a artifact ID randomly and removes the selected artifact from this handler.
ArtifactID pickRandomArtifact(CRandomGenerator & rand, int flags);
ArtifactID pickRandomArtifact(CRandomGenerator & rand, std::function<bool(ArtifactID)> accepts);
ArtifactID pickRandomArtifact(CRandomGenerator & rand, int flags, std::function<bool(ArtifactID)> accepts);
ArtifactID pickRandomArtifact(CRandomGenerator & rand, std::set<ArtifactID> filtered);
bool legalArtifact(const ArtifactID & id);
void initAllowedArtifactsList(const std::vector<bool> &allowed); //allowed[art_id] -> 0 if not allowed, 1 if allowed
static void makeItCreatureArt(CArtifact * a, bool onlyCreature = true);
@ -203,13 +163,6 @@ public:
std::vector<bool> getDefaultAllowed() const override;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & objects;
h & allowedArtifacts;
h & allocatedArtifacts;
}
protected:
const std::vector<std::string> & getTypeNames() const override;
CArtifact * loadFromJson(const std::string & scope, const JsonNode & json, const std::string & identifier, size_t index) override;

View File

@ -83,11 +83,6 @@ public:
struct RayColor {
ColorRGBA start;
ColorRGBA end;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & start & end;
}
};
double timeBetweenFidgets, idleAnimationTime,
@ -100,25 +95,7 @@ public:
AnimationPath projectileImageName;
std::vector<RayColor> projectileRay;
//bool projectileSpin; //if true, appropriate projectile is spinning during flight
template <typename Handler> void serialize(Handler &h, const int version)
{
h & timeBetweenFidgets;
h & idleAnimationTime;
h & walkAnimationTime;
h & attackAnimationTime;
h & upperRightMissleOffsetX;
h & rightMissleOffsetX;
h & lowerRightMissleOffsetX;
h & upperRightMissleOffsetY;
h & rightMissleOffsetY;
h & lowerRightMissleOffsetY;
h & missleFrameAngles;
h & attackClimaxFrame;
h & projectileImageName;
h & projectileRay;
}
} animation;
//sound info
@ -132,18 +109,6 @@ public:
AudioPath wince; // attacked but did not die
AudioPath startMoving;
AudioPath endMoving;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & attack;
h & defend;
h & killed;
h & move;
h & shoot;
h & wince;
h & startMoving;
h & endMoving;
}
} sounds;
ArtifactID warMachine;
@ -210,35 +175,6 @@ public:
void updateFrom(const JsonNode & data);
void serializeJson(JsonSerializeFormat & handler);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CBonusSystemNode&>(*this);
h & cost;
h & upgrades;
h & fightValue;
h & AIValue;
h & growth;
h & hordeGrowth;
h & ammMin;
h & ammMax;
h & level;
h & animDefName;
h & iconIndex;
h & smallIconName;
h & largeIconName;
h & idNumber;
h & faction;
h & sounds;
h & animation;
h & doubleWide;
h & special;
h & identifier;
h & modScope;
h & warMachine;
}
CCreature();
private:
@ -303,19 +239,6 @@ public:
std::vector<JsonNode> loadLegacyData() override;
std::vector<bool> getDefaultAllowed() const override;
template <typename Handler> void serialize(Handler &h, const int version)
{
//TODO: should be optimized, not all these informations needs to be serialized (same for ccreature)
h & doubledCreatures;
h & objects;
h & expRanks;
h & maxExpPerBattle;
h & expAfterUpgrade;
h & skillLevels;
h & skillRequirements;
h & commanderLevelPremy;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -52,13 +52,6 @@ public:
ui32 minAmount;
ui32 maxAmount;
CreatureID creature;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & minAmount;
h & maxAmount;
h & creature;
}
};
si32 imageIndex = 0;
@ -104,29 +97,6 @@ public:
void updateFrom(const JsonNode & data);
void serializeJson(JsonSerializeFormat & handler);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & ID;
h & imageIndex;
h & initialArmy;
h & heroClass;
h & secSkillsInit;
h & specialty;
h & spells;
h & haveSpellBook;
h & gender;
h & special;
h & onlyOnWaterMap;
h & onlyOnMapWithoutWater;
h & iconSpecSmall;
h & iconSpecLarge;
h & portraitSmall;
h & portraitLarge;
h & identifier;
h & modScope;
h & battleImage;
}
};
class DLL_LINKAGE CHeroClass : public HeroClass
@ -183,25 +153,6 @@ public:
void updateFrom(const JsonNode & data);
void serializeJson(JsonSerializeFormat & handler);
template <typename Handler> void serialize(Handler & h, const int version)
{
h & modScope;
h & identifier;
h & faction;
h & id;
h & defaultTavernChance;
h & primarySkillInitial;
h & primarySkillLowLevel;
h & primarySkillHighLevel;
h & secSkillProbability;
h & selectionProbability;
h & affinity;
h & commander;
h & imageBattleMale;
h & imageBattleFemale;
h & imageMapMale;
h & imageMapFemale;
}
EAlignment getAlignment() const;
};
@ -218,11 +169,6 @@ public:
~CHeroClassHandler();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & objects;
}
protected:
const std::vector<std::string> & getTypeNames() const override;
CHeroClass * loadFromJson(const std::string & scope, const JsonNode & node, const std::string & identifier, size_t index) override;
@ -262,13 +208,6 @@ public:
std::vector<bool> getDefaultAllowed() const override;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & classes;
h & objects;
h & expPerLevel;
}
protected:
const std::vector<std::string> & getTypeNames() const override;
CHero * loadFromJson(const std::string & scope, const JsonNode & node, const std::string & identifier, size_t index) override;

View File

@ -29,14 +29,6 @@ public:
std::string iconMedium;
std::string iconLarge;
std::vector<std::shared_ptr<Bonus>> effects;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & iconSmall;
h & iconMedium;
h & iconLarge;
h & effects;
}
};
private:
@ -82,17 +74,6 @@ public:
bool onlyOnWaterMap;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & id;
h & identifier;
h & gainChance;
h & levels;
h & obligatoryMajor;
h & obligatoryMinor;
h & onlyOnWaterMap;
}
friend class CSkillHandler;
friend DLL_LINKAGE std::ostream & operator<<(std::ostream & out, const CSkill & skill);
friend DLL_LINKAGE std::ostream & operator<<(std::ostream & out, const CSkill::LevelInfo & info);
@ -111,11 +92,6 @@ public:
std::vector<bool> getDefaultAllowed() const override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & objects;
}
protected:
const std::vector<std::string> & getTypeNames() const override;
CSkill * loadFromJson(const std::string & scope, const JsonNode & json, const std::string & identifier, size_t index) override;

View File

@ -123,25 +123,6 @@ public:
void addNewBonus(const std::shared_ptr<Bonus> & b, BonusList & bonusList) const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & modScope;
h & identifier;
h & town;
h & bid;
h & resources;
h & produce;
h & requirements;
h & upgrade;
h & mode;
h & subId;
h & height;
h & overrideBids;
h & buildingBonuses;
h & onVisitBonuses;
h & rewardableObjectInfo;
}
friend class CTownHandler;
};
@ -160,17 +141,6 @@ struct DLL_LINKAGE CStructure
std::string identifier;
bool hiddenUpgrade; // used only if "building" is upgrade, if true - structure on town screen will behave exactly like parent (mouse clicks, hover texts, etc)
template <typename Handler> void serialize(Handler &h, const int version)
{
h & pos;
h & defName;
h & borderName;
h & areaName;
h & identifier;
h & building;
h & buildable;
h & hiddenUpgrade;
}
};
struct DLL_LINKAGE SPuzzleInfo
@ -179,15 +149,6 @@ struct DLL_LINKAGE SPuzzleInfo
si16 x, y; //position
ui16 whenUncovered; //determines the sequnce of discovering (the lesser it is the sooner puzzle will be discovered)
ImagePath filename; //file with graphic of this puzzle
template <typename Handler> void serialize(Handler &h, const int version)
{
h & number;
h & x;
h & y;
h & whenUncovered;
h & filename;
}
};
class DLL_LINKAGE CFaction : public Faction
@ -238,20 +199,6 @@ public:
void updateFrom(const JsonNode & data);
void serializeJson(JsonSerializeFormat & handler);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & modScope;
h & identifier;
h & index;
h & nativeTerrain;
h & boatType;
h & alignment;
h & town;
h & creatureBg120;
h & creatureBg130;
h & puzzleMap;
}
};
class DLL_LINKAGE CTown
@ -323,44 +270,7 @@ public:
std::string towerIconSmall;
std::string towerIconLarge;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & icons;
h & iconSmall;
h & iconLarge;
h & tavernVideo;
h & musicTheme;
h & townBackground;
h & guildBackground;
h & guildWindow;
h & buildingsIcons;
h & hallBackground;
h & hallSlots;
h & structures;
h & siegePrefix;
h & siegePositions;
h & siegeShooter;
h & towerIconSmall;
h & towerIconLarge;
}
} clientInfo;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & namesCount;
h & faction;
h & creatures;
h & dwellings;
h & dwellingNames;
h & buildings;
h & hordeLvl;
h & mageLevel;
h & primaryRes;
h & warMachine;
h & clientInfo;
h & moatAbility;
h & defaultTavernChance;
}
private:
///generated bonusing buildings messages for all towns of this type.
@ -445,12 +355,6 @@ public:
static void loadSpecialBuildingBonuses(const JsonNode & source, BonusList & bonusList, CBuilding * building);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & objects;
h & randomTown;
}
protected:
const std::vector<std::string> & getTypeNames() const override;
CFaction * loadFromJson(const std::string & scope, const JsonNode & data, const std::string & identifier, size_t index) override;

View File

@ -21,10 +21,8 @@
#include "bonuses/Propagators.h"
#include "bonuses/Updaters.h"
#include "serializer/CSerializer.h" // for SAVEGAME_MAGIC
#include "serializer/BinaryDeserializer.h"
#include "serializer/BinarySerializer.h"
#include "serializer/CLoadIntegrityValidator.h"
#include "serializer/CLoadFile.h"
#include "serializer/CSaveFile.h"
#include "rmg/CMapGenOptions.h"
#include "mapObjectConstructors/AObjectTypeHandler.h"
#include "mapObjectConstructors/CObjectClassesHandler.h"
@ -41,6 +39,7 @@
#include "modding/CModInfo.h"
#include "modding/IdentifierStorage.h"
#include "modding/CModVersion.h"
#include "modding/ActiveModsInSaveList.h"
#include "CPlayerState.h"
#include "GameSettings.h"
#include "ScriptHandler.h"
@ -145,14 +144,14 @@ void CPrivilegedInfoCallback::getAllTiles(std::unordered_set<int3> & tiles, std:
}
}
void CPrivilegedInfoCallback::pickAllowedArtsSet(std::vector<const CArtifact *> & out, CRandomGenerator & rand) const
void CPrivilegedInfoCallback::pickAllowedArtsSet(std::vector<const CArtifact *> & out, CRandomGenerator & rand)
{
for (int j = 0; j < 3 ; j++)
out.push_back(VLC->arth->pickRandomArtifact(rand, CArtifact::ART_TREASURE).toArtifact());
out.push_back(gameState()->pickRandomArtifact(rand, CArtifact::ART_TREASURE).toArtifact());
for (int j = 0; j < 3 ; j++)
out.push_back(VLC->arth->pickRandomArtifact(rand, CArtifact::ART_MINOR).toArtifact());
out.push_back(gameState()->pickRandomArtifact(rand, CArtifact::ART_MINOR).toArtifact());
out.push_back(VLC->arth->pickRandomArtifact(rand, CArtifact::ART_MAJOR).toArtifact());
out.push_back(gameState()->pickRandomArtifact(rand, CArtifact::ART_MAJOR).toArtifact());
}
void CPrivilegedInfoCallback::getAllowedSpells(std::vector<SpellID> & out, std::optional<ui16> level)
@ -184,6 +183,7 @@ void CPrivilegedInfoCallback::loadCommonState(Loader & in)
CMapHeader dum;
StartInfo * si = nullptr;
ActiveModsInSaveList activeMods;
logGlobal->info("\tReading header");
in.serializer & dum;
@ -191,8 +191,8 @@ void CPrivilegedInfoCallback::loadCommonState(Loader & in)
logGlobal->info("\tReading options");
in.serializer & si;
logGlobal->info("\tReading handlers");
in.serializer & *VLC;
logGlobal->info("\tReading mod list");
in.serializer & activeMods;
logGlobal->info("\tReading gamestate");
in.serializer & gs;
@ -201,20 +201,21 @@ void CPrivilegedInfoCallback::loadCommonState(Loader & in)
template<typename Saver>
void CPrivilegedInfoCallback::saveCommonState(Saver & out) const
{
ActiveModsInSaveList activeMods;
logGlobal->info("Saving lib part of game...");
out.putMagicBytes(SAVEGAME_MAGIC);
logGlobal->info("\tSaving header");
out.serializer & static_cast<CMapHeader&>(*gs->map);
logGlobal->info("\tSaving options");
out.serializer & gs->scenarioOps;
logGlobal->info("\tSaving handlers");
out.serializer & *VLC;
logGlobal->info("\tSaving mod list");
out.serializer & activeMods;
logGlobal->info("\tSaving gamestate");
out.serializer & gs;
}
// hardly memory usage for `-gdwarf-4` flag
template DLL_LINKAGE void CPrivilegedInfoCallback::loadCommonState<CLoadIntegrityValidator>(CLoadIntegrityValidator &);
template DLL_LINKAGE void CPrivilegedInfoCallback::loadCommonState<CLoadFile>(CLoadFile &);
template DLL_LINKAGE void CPrivilegedInfoCallback::saveCommonState<CSaveFile>(CSaveFile &) const;

View File

@ -61,7 +61,7 @@ public:
void getAllTiles(std::unordered_set<int3> &tiles, std::optional<PlayerColor> player, int level, std::function<bool(const TerrainTile *)> filter) const;
//gives 3 treasures, 3 minors, 1 major -> used by Black Market and Artifact Merchant
void pickAllowedArtsSet(std::vector<const CArtifact *> & out, CRandomGenerator & rand) const;
void pickAllowedArtsSet(std::vector<const CArtifact *> & out, CRandomGenerator & rand);
void getAllowedSpells(std::vector<SpellID> &out, std::optional<ui16> level = std::nullopt);
template<typename Saver>

View File

@ -247,8 +247,8 @@ namespace JsonDetail
static Type convert(const JsonNode & node)
{
///this should be triggered only for numeric types and enums
static_assert(boost::mpl::or_<std::is_arithmetic<Type>, std::is_enum<Type>, boost::is_class<Type> >::value, "Unsupported type for JsonNode::convertTo()!");
return JsonConvImpl<Type, boost::mpl::or_<std::is_enum<Type>, boost::is_class<Type> >::value >::convertImpl(node);
static_assert(std::is_arithmetic_v<Type> || std::is_enum_v<Type> || std::is_class_v<Type>, "Unsupported type for JsonNode::convertTo()!");
return JsonConvImpl<Type, std::is_enum_v<Type> || std::is_class_v<Type> >::convertImpl(node);
}
};

View File

@ -24,6 +24,7 @@
#include "CSkillHandler.h"
#include "CHeroHandler.h"
#include "IGameCallback.h"
#include "gameState/CGameState.h"
#include "mapObjects/IObjectInterface.h"
#include "modding/IdentifierStorage.h"
#include "modding/ModScope.h"
@ -388,7 +389,7 @@ namespace JsonRandom
std::set<ArtifactID> potentialPicks = filterKeys(value, allowedArts, variables);
return VLC->arth->pickRandomArtifact(rng, potentialPicks);
return IObjectInterface::cb->gameState()->pickRandomArtifact(rng, potentialPicks);
}
std::vector<ArtifactID> loadArtifacts(const JsonNode & value, CRandomGenerator & rng, const Variables & variables)

View File

@ -54,23 +54,6 @@ public:
std::vector<BattleHex> getBlocked(BattleHex hex) const; //returns vector of hexes blocked by obstacle when it's placed on hex 'hex'
bool isAppropriate(const TerrainId terrainType, const BattleField & specialBattlefield) const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & obstacle;
h & iconIndex;
h & identifier;
h & animation;
h & appearAnimation;
h & appearSound;
h & allowedTerrains;
h & allowedSpecialBfields;
h & isAbsoluteObstacle;
h & isForegroundObstacle;
h & width;
h & height;
h & blockedTiles;
}
};
class DLL_LINKAGE ObstacleService : public EntityServiceT<Obstacle, ObstacleInfo>
@ -89,11 +72,6 @@ public:
const std::vector<std::string> & getTypeNames() const override;
std::vector<JsonNode> loadLegacyData() override;
std::vector<bool> getDefaultAllowed() const override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & objects;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -24,12 +24,6 @@ struct DLL_LINKAGE RiverPaletteAnimation
int32_t start;
/// total numbers of colors to cycle
int32_t length;
template <typename Handler> void serialize(Handler& h, const int version)
{
h & start;
h & length;
}
};
class DLL_LINKAGE RiverType : public EntityT<RiverId>
@ -57,16 +51,6 @@ public:
std::vector<RiverPaletteAnimation> paletteAnimation;
RiverType();
template <typename Handler> void serialize(Handler& h, const int version)
{
h & tilesFilename;
h & identifier;
h & modScope;
h & deltaName;
h & id;
h & paletteAnimation;
}
};
class DLL_LINKAGE RiverTypeService : public EntityServiceT<RiverId, RiverType>
@ -88,11 +72,6 @@ public:
virtual const std::vector<std::string> & getTypeNames() const override;
virtual std::vector<JsonNode> loadLegacyData() override;
virtual std::vector<bool> getDefaultAllowed() const override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & objects;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -41,15 +41,6 @@ public:
ui8 movementCost;
RoadType();
template <typename Handler> void serialize(Handler& h, const int version)
{
h & tilesFilename;
h & identifier;
h & modScope;
h & id;
h & movementCost;
}
};
class DLL_LINKAGE RoadTypeService : public EntityServiceT<RoadId, RoadType>
@ -71,11 +62,6 @@ public:
virtual const std::vector<std::string> & getTypeNames() const override;
virtual std::vector<JsonNode> loadLegacyData() override;
virtual std::vector<bool> getDefaultAllowed() const override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & objects;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -91,30 +91,6 @@ public:
bool isSurface() const;
bool isUnderground() const;
bool isTransitionRequired() const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & battleFields;
h & prohibitTransitions;
h & minimapBlocked;
h & minimapUnblocked;
h & modScope;
h & identifier;
h & musicFilename;
h & tilesFilename;
h & shortIdentifier;
h & terrainViewPatterns;
h & rockTerrain;
h & river;
h & paletteAnimation;
h & id;
h & moveCost;
h & horseSound;
h & horseSoundPenalty;
h & passabilityType;
h & transitionRequired;
}
};
class DLL_LINKAGE TerrainTypeService : public EntityServiceT<TerrainId, TerrainType>
@ -134,11 +110,6 @@ public:
virtual const std::vector<std::string> & getTypeNames() const override;
virtual std::vector<JsonNode> loadLegacyData() override;
virtual std::vector<bool> getDefaultAllowed() const override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & objects;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -120,51 +120,6 @@ public:
#if SCRIPTING_ENABLED
void scriptsLoaded();
#endif
template <typename Handler> void serialize(Handler &h, const int version)
{
h & identifiersHandler; // must be first - identifiers registry is used for handlers loading
#if SCRIPTING_ENABLED
h & scriptHandler;//must be first (or second after identifiers), it can modify factories other handlers depends on
if(!h.saving)
{
scriptsLoaded();
}
#endif
h & settingsHandler;
h & heroh;
h & arth;
h & creh;
h & townh;
h & objh;
h & objtypeh;
h & spellh;
h & skillh;
h & battlefieldsHandler;
h & obstacleHandler;
h & roadTypeHandler;
h & riverTypeHandler;
h & terrainTypeHandler;
if(!h.saving)
{
//modh will be changed and modh->content will be empty after deserialization
auto content = getContent();
h & modh;
setContent(content);
}
else
h & modh;
h & IS_AI_ENABLED;
h & bth;
if(!h.saving)
{
callWhenDeserializing();
}
}
};
extern DLL_LINKAGE LibClasses * VLC;

View File

@ -22,7 +22,7 @@ public:
template<typename T>
CSelector(const T &t, //SFINAE trick -> include this c-tor in overload resolution only if parameter is class
//(includes functors, lambdas) or function. Without that VC is going mad about ambiguities.
typename std::enable_if < boost::mpl::or_ < std::is_class<T>, std::is_function<T >> ::value>::type *dummy = nullptr)
typename std::enable_if_t < std::is_class_v<T> || std::is_function_v<T> > *dummy = nullptr)
: TBase(t)
{}

View File

@ -37,6 +37,8 @@
#include "constants/StringConstants.h"
#include "CGeneralTextHandler.h"
#include "TerrainHandler.h" //TODO: remove
#include "RiverHandler.h"
#include "RoadHandler.h"
#include "BattleFieldHandler.h"
#include "ObstacleHandler.h"
#include "CTownHandler.h"
@ -404,6 +406,11 @@ std::string FactionID::entityType()
return "faction";
}
const Faction * FactionID::toEntity(const Services * service) const
{
return service->factions()->getByIndex(num);
}
si32 TerrainId::decode(const std::string & identifier)
{
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), entityType(), identifier);
@ -423,6 +430,21 @@ std::string TerrainId::entityType()
return "terrain";
}
const TerrainType * TerrainId::toEntity(const Services * service) const
{
return VLC->terrainTypeHandler->getByIndex(num);
}
const RoadType * RoadId::toEntity(const Services * service) const
{
return VLC->roadTypeHandler->getByIndex(num);
}
const RiverType * RiverId::toEntity(const Services * service) const
{
return VLC->riverTypeHandler->getByIndex(num);
}
const BattleField BattleField::NONE;
const BattleFieldInfo * BattleField::getInfo() const

View File

@ -22,6 +22,10 @@ class CreatureService;
class HeroType;
class CHero;
class HeroTypeService;
class Faction;
class RoadType;
class RiverType;
class TerrainType;
namespace spells
{
@ -181,20 +185,20 @@ public:
static std::string entityType();
};
class HeroTypeID : public Identifier<HeroTypeID>
class DLL_LINKAGE HeroTypeID : public Identifier<HeroTypeID>
{
public:
using Identifier<HeroTypeID>::Identifier;
///json serialization helpers
DLL_LINKAGE static si32 decode(const std::string & identifier);
DLL_LINKAGE static std::string encode(const si32 index);
static si32 decode(const std::string & identifier);
static std::string encode(const si32 index);
static std::string entityType();
const CHero * toHeroType() const;
const HeroType * toEntity(const Services * services) const;
DLL_LINKAGE static const HeroTypeID NONE;
DLL_LINKAGE static const HeroTypeID RANDOM;
static const HeroTypeID NONE;
static const HeroTypeID RANDOM;
bool isValid() const
{
@ -349,6 +353,7 @@ public:
static si32 decode(const std::string& identifier);
static std::string encode(const si32 index);
const Faction * toEntity(const Services * service) const;
static std::string entityType();
bool isValid() const
@ -596,6 +601,8 @@ public:
static const RoadId DIRT_ROAD;
static const RoadId GRAVEL_ROAD;
static const RoadId COBBLESTONE_ROAD;
const RoadType * toEntity(const Services * service) const;
};
class DLL_LINKAGE RiverId : public Identifier<RiverId>
@ -608,6 +615,8 @@ public:
static const RiverId ICY_RIVER;
static const RiverId MUD_RIVER;
static const RiverId LAVA_RIVER;
const RiverType * toEntity(const Services * service) const;
};
class DLL_LINKAGE EPathfindingLayerBase : public IdentifierBase
@ -912,6 +921,7 @@ public:
DLL_LINKAGE static si32 decode(const std::string & identifier);
DLL_LINKAGE static std::string encode(const si32 index);
static std::string entityType();
const TerrainType * toEntity(const Services * service) const;
};
class ObstacleInfo;

View File

@ -42,7 +42,7 @@
#include "../modding/IdentifierStorage.h"
#include "../pathfinder/CPathfinder.h"
#include "../pathfinder/PathfinderOptions.h"
#include "../registerTypes/RegisterTypes.h"
#include "../registerTypes/RegisterTypesClientPacks.h"
#include "../rmg/CMapGenerator.h"
#include "../serializer/CMemorySerializer.h"
#include "../serializer/CTypeList.h"
@ -157,8 +157,7 @@ CGameState::CGameState()
gs = this;
heroesPool = std::make_unique<TavernHeroesPool>();
applier = std::make_shared<CApplier<CBaseForGSApply>>();
registerTypesClientPacks1(*applier);
registerTypesClientPacks2(*applier);
registerTypesClientPacks(*applier);
globalEffects.setNodeType(CBonusSystemNode::GLOBAL_EFFECTS);
}
@ -760,7 +759,7 @@ void CGameState::initStartingBonus()
logGlobal->error("Cannot give starting artifact - no heroes!");
break;
}
const Artifact * toGive = VLC->arth->pickRandomArtifact(getRandomGenerator(), CArtifact::ART_TREASURE).toEntity(VLC);
const Artifact * toGive = pickRandomArtifact(getRandomGenerator(), CArtifact::ART_TREASURE).toEntity(VLC);
CGHeroInstance *hero = elem.second.heroes[0];
if(!giveHeroArtifact(hero, toGive->getId()))
@ -921,11 +920,9 @@ void CGameState::initMapObjects()
for(CGObjectInstance *obj : map->objects)
{
if(obj)
{
logGlobal->trace("Calling Init for object %d, %s, %s", obj->id.getNum(), obj->typeName, obj->subTypeName);
obj->initObj(getRandomGenerator());
}
}
logGlobal->debug("\tObject initialization done");
for(CGObjectInstance *obj : map->objects)
{
if(!obj)
@ -1136,7 +1133,7 @@ PlayerRelations CGameState::getPlayerRelations( PlayerColor color1, PlayerColor
void CGameState::apply(CPack *pack)
{
ui16 typ = typeList.getTypeID(pack);
ui16 typ = CTypeList::getInstance().getTypeID(pack);
applier->getApplier(typ)->applyOnGS(this, pack);
}
@ -1971,4 +1968,73 @@ CRandomGenerator & CGameState::getRandomGenerator()
return rand;
}
ArtifactID CGameState::pickRandomArtifact(CRandomGenerator & rand, int flags, std::function<bool(ArtifactID)> accepts)
{
std::set<ArtifactID> potentialPicks;
// Select artifacts that satisfy provided criterias
for (auto const * artifact : VLC->arth->allowedArtifacts)
{
assert(artifact->aClass != CArtifact::ART_SPECIAL); // should be filtered out when allowedArtifacts is initialized
if ((flags & CArtifact::ART_TREASURE) == 0 && artifact->aClass == CArtifact::ART_TREASURE)
continue;
if ((flags & CArtifact::ART_MINOR) == 0 && artifact->aClass == CArtifact::ART_MINOR)
continue;
if ((flags & CArtifact::ART_MAJOR) == 0 && artifact->aClass == CArtifact::ART_MAJOR)
continue;
if ((flags & CArtifact::ART_RELIC) == 0 && artifact->aClass == CArtifact::ART_RELIC)
continue;
if (!accepts(artifact->getId()))
continue;
potentialPicks.insert(artifact->getId());
}
return pickRandomArtifact(rand, potentialPicks);
}
ArtifactID CGameState::pickRandomArtifact(CRandomGenerator & rand, std::set<ArtifactID> potentialPicks)
{
// No allowed artifacts at all - give Grail - this can't be banned (hopefully)
// FIXME: investigate how such cases are handled by H3 - some heavily customized user-made maps likely rely on H3 behavior
if (potentialPicks.empty())
{
logGlobal->warn("Failed to find artifact that matches requested parameters!");
return ArtifactID::GRAIL;
}
// Find how many times least used artifacts were picked by randomizer
int leastUsedTimes = std::numeric_limits<int>::max();
for (auto const & artifact : potentialPicks)
if (allocatedArtifacts[artifact] < leastUsedTimes)
leastUsedTimes = allocatedArtifacts[artifact];
// Pick all artifacts that were used least number of times
std::set<ArtifactID> preferredPicks;
for (auto const & artifact : potentialPicks)
if (allocatedArtifacts[artifact] == leastUsedTimes)
preferredPicks.insert(artifact);
assert(!preferredPicks.empty());
ArtifactID artID = *RandomGeneratorUtil::nextItem(preferredPicks, rand);
allocatedArtifacts[artID] += 1; // record +1 more usage
return artID;
}
ArtifactID CGameState::pickRandomArtifact(CRandomGenerator & rand, std::function<bool(ArtifactID)> accepts)
{
return pickRandomArtifact(rand, 0xff, std::move(accepts));
}
ArtifactID CGameState::pickRandomArtifact(CRandomGenerator & rand, int flags)
{
return pickRandomArtifact(rand, flags, [](const ArtifactID &) { return true; });
}
VCMI_LIB_NAMESPACE_END

View File

@ -83,6 +83,9 @@ class DLL_LINKAGE CGameState : public CNonConstInfoCallback
friend class CGameStateCampaign;
public:
/// Stores number of times each artifact was placed on map via randomization
std::map<ArtifactID, int> allocatedArtifacts;
/// List of currently ongoing battles
std::vector<std::unique_ptr<BattleInfo>> currentBattles;
/// ID that can be allocated to next battle
@ -130,6 +133,12 @@ public:
std::vector<CGObjectInstance*> guardingCreatures (int3 pos) const;
void updateRumor();
/// Gets a artifact ID randomly and removes the selected artifact from this handler.
ArtifactID pickRandomArtifact(CRandomGenerator & rand, int flags);
ArtifactID pickRandomArtifact(CRandomGenerator & rand, std::function<bool(ArtifactID)> accepts);
ArtifactID pickRandomArtifact(CRandomGenerator & rand, int flags, std::function<bool(ArtifactID)> accepts);
ArtifactID pickRandomArtifact(CRandomGenerator & rand, std::set<ArtifactID> filtered);
/// Returns battle in which selected player is engaged, or nullptr if none.
/// Can NOT be used with neutral player, use battle by ID instead
const BattleInfo * getBattle(const PlayerColor & player) const;
@ -176,6 +185,7 @@ public:
h & rand;
h & rumor;
h & campaign;
h & allocatedArtifacts;
BONUS_TREE_DESERIALIZATION_FIX
}

View File

@ -16,7 +16,7 @@
#include "../campaign/CampaignState.h"
#include "../mapping/CMapEditManager.h"
#include "../mapObjects/CGHeroInstance.h"
#include "../registerTypes/RegisterTypes.h"
#include "../networkPacks/ArtifactLocation.h"
#include "../mapObjectConstructors/AObjectTypeHandler.h"
#include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../StartInfo.h"

View File

@ -112,20 +112,6 @@ public:
/// Returns object configuration, if available. Otherwise returns NULL
virtual std::unique_ptr<IObjectInfo> getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & type;
h & subtype;
h & templates;
h & rmgInfo;
h & modScope;
h & typeName;
h & subTypeName;
h & sounds;
h & aiValue;
h & battlefield;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -92,15 +92,6 @@ public:
bool hasNameTextID() const override;
std::unique_ptr<IObjectInfo> getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const override;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & levels;
h & bankResetDuration;
h & blockVisit;
h & coastVisitable;
h & static_cast<CDefaultObjectTypeHandler<CBank>&>(*this);
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -62,16 +62,6 @@ public:
std::string getJsonKey() const;
std::string getNameTextID() const;
std::string getNameTranslated() const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & id;
h & handlerName;
h & base;
h & objects;
h & identifier;
h & modScope;
}
};
/// Main class responsible for creation of all adventure map objects
@ -130,11 +120,6 @@ public:
std::string getObjectHandlerName(MapObjectID type) const;
std::string getJsonKey(MapObjectID type) const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & objects;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -30,13 +30,6 @@ public:
void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const override;
std::unique_ptr<IObjectInfo> getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const override;
template <typename Handler> void serialize(Handler &h, const int version)
{
AObjectTypeHandler::serialize(h, version);
h & objectInfo;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -66,14 +66,6 @@ public:
bool hasNameTextID() const override;
std::string getNameTextID() const override;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & filtersJson;
h & faction;
h & filters;
h & static_cast<CDefaultObjectTypeHandler<CGTownInstance>&>(*this);
}
};
class CHeroInstanceConstructor : public CDefaultObjectTypeHandler<CGHeroInstance>
@ -93,14 +85,6 @@ public:
bool hasNameTextID() const override;
std::string getNameTextID() const override;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & filtersJson;
h & heroClass;
h & filters;
h & static_cast<CDefaultObjectTypeHandler<CGHeroInstance>&>(*this);
}
};
class DLL_LINKAGE BoatInstanceConstructor : public CDefaultObjectTypeHandler<CGBoat>
@ -122,18 +106,6 @@ public:
/// Returns boat preview animation, for use in Shipyards
AnimationPath getBoatAnimationName() const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CDefaultObjectTypeHandler<CGBoat>&>(*this);
h & layer;
h & onboardAssaultAllowed;
h & onboardVisitAllowed;
h & bonuses;
h & actualAnimation;
h & overlayAnimation;
h & flagAnimations;
}
};
class MarketInstanceConstructor : public CDefaultObjectTypeHandler<CGMarket>
@ -152,12 +124,6 @@ public:
void initializeObject(CGMarket * object) const override;
void randomizeObject(CGMarket * object, CRandomGenerator & rng) const override;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CDefaultObjectTypeHandler<CGMarket>&>(*this);
h & marketModes;
h & marketEfficiency;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -33,13 +33,6 @@ public:
bool producesCreature(const CCreature * crea) const;
std::vector<const CCreature *> getProducedCreatures() const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & availableCreatures;
h & guards;
h & static_cast<CDefaultObjectTypeHandler<CGDwelling>&>(*this);
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -24,11 +24,6 @@ protected:
void initializeObject(HillFort * object) const override;
public:
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<AObjectTypeHandler&>(*this);
h & parameters;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -33,14 +33,6 @@ struct DLL_LINKAGE RandomMapInfo
{}
void setMapLimit(ui32 val) { mapLimit = val; }
template <typename Handler> void serialize(Handler &h, const int version)
{
h & value;
h & mapLimit;
h & zoneLimit;
h & rarity;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -18,13 +18,6 @@ struct SObjectSounds
std::vector<AudioPath> ambient;
std::vector<AudioPath> visit;
std::vector<AudioPath> removal;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & ambient;
h & visit;
h & removal;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -24,11 +24,6 @@ protected:
void initializeObject(CGShipyard * object) const override;
public:
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<AObjectTypeHandler&>(*this);
h & parameters;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -117,7 +117,7 @@ std::set<int3> CGObjectInstance::getBlockedPos() const
return ret;
}
std::set<int3> CGObjectInstance::getBlockedOffsets() const
const std::set<int3> & CGObjectInstance::getBlockedOffsets() const
{
return appearance->getBlockedOffsets();
}

View File

@ -77,7 +77,7 @@ public:
bool coveringAt (const int3 & pos) const; //returns true if object covers with picture location (x, y) (h3m pos)
std::set<int3> getBlockedPos() const; //returns set of positions blocked by this object
std::set<int3> getBlockedOffsets() const; //returns set of relative positions blocked by this object
const std::set<int3> & getBlockedOffsets() const; //returns set of relative positions blocked by this object
/// returns true if object is visitable
bool isVisitable() const;

View File

@ -92,7 +92,18 @@ public:
for(auto * bonusingBuilding : bonusingBuildings)
bonusingBuilding->town = this;
h & town;
if (h.saving)
{
CFaction * faction = town ? town->faction : nullptr;
h & faction;
}
else
{
CFaction * faction = nullptr;
h & faction;
town = faction ? faction->town : nullptr;
}
h & townAndVis;
BONUS_TREE_DESERIALIZATION_FIX

View File

@ -22,11 +22,6 @@ public:
std::vector<ui32> resVals; //default values of resources in gold
CObjectHandler();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & resVals;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -724,19 +724,19 @@ void CGArtifact::pickRandomObject(CRandomGenerator & rand)
switch(ID.toEnum())
{
case MapObjectID::RANDOM_ART:
subID = VLC->arth->pickRandomArtifact(rand, CArtifact::ART_TREASURE | CArtifact::ART_MINOR | CArtifact::ART_MAJOR | CArtifact::ART_RELIC);
subID = cb->gameState()->pickRandomArtifact(rand, CArtifact::ART_TREASURE | CArtifact::ART_MINOR | CArtifact::ART_MAJOR | CArtifact::ART_RELIC);
break;
case MapObjectID::RANDOM_TREASURE_ART:
subID = VLC->arth->pickRandomArtifact(rand, CArtifact::ART_TREASURE);
subID = cb->gameState()->pickRandomArtifact(rand, CArtifact::ART_TREASURE);
break;
case MapObjectID::RANDOM_MINOR_ART:
subID = VLC->arth->pickRandomArtifact(rand, CArtifact::ART_MINOR);
subID = cb->gameState()->pickRandomArtifact(rand, CArtifact::ART_MINOR);
break;
case MapObjectID::RANDOM_MAJOR_ART:
subID = VLC->arth->pickRandomArtifact(rand, CArtifact::ART_MAJOR);
subID = cb->gameState()->pickRandomArtifact(rand, CArtifact::ART_MAJOR);
break;
case MapObjectID::RANDOM_RELIC_ART:
subID = VLC->arth->pickRandomArtifact(rand, CArtifact::ART_RELIC);
subID = cb->gameState()->pickRandomArtifact(rand, CArtifact::ART_RELIC);
break;
}

View File

@ -80,7 +80,7 @@ public:
bool isVisibleAt(si32 X, si32 Y) const;
bool isBlockedAt(si32 X, si32 Y) const;
inline std::set<int3> getBlockedOffsets() const
inline const std::set<int3> & getBlockedOffsets() const
{
return blockedOffsets;
};

View File

@ -20,7 +20,7 @@ VCMI_LIB_NAMESPACE_BEGIN
class CGObjectInstance;
enum class EMapFormat : uint8_t;
using ModCompatibilityInfo = std::map<std::string, CModInfo::VerificationInfo>;
using ModCompatibilityInfo = std::map<std::string, ModVerificationInfo>;
/// The hero name struct consists of the hero id and the hero name.
struct DLL_LINKAGE SHeroName

View File

@ -21,7 +21,7 @@
#include "../campaign/CampaignHandler.h"
#include "../filesystem/Filesystem.h"
#include "../serializer/CMemorySerializer.h"
#include "../serializer/CLoadFile.h"
#include "../CGeneralTextHandler.h"
#include "../rmg/CMapGenOptions.h"
#include "../CCreatureHandler.h"

View File

@ -23,7 +23,7 @@ class CInputStream;
class IMapLoader;
class IMapPatcher;
using ModCompatibilityInfo = std::map<std::string, CModInfo::VerificationInfo>;
using ModCompatibilityInfo = std::map<std::string, ModVerificationInfo>;
/**
* The map service provides loading of VCMI/H3 map files. It can

View File

@ -966,7 +966,7 @@ void CMapLoaderJson::readHeader(const bool complete)
{
for(auto & mod : header["mods"].Vector())
{
CModInfo::VerificationInfo info;
ModVerificationInfo info;
info.version = CModVersion::fromString(mod["version"].String());
info.checksum = mod["checksum"].Integer();
info.name = mod["name"].String();

View File

@ -0,0 +1,112 @@
/*
* ActiveModsInSaveList.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "ActiveModsInSaveList.h"
#include "../VCMI_Lib.h"
#include "CModInfo.h"
#include "CModHandler.h"
#include "ModIncompatibility.h"
VCMI_LIB_NAMESPACE_BEGIN
std::vector<TModID> ActiveModsInSaveList::getActiveMods()
{
return VLC->modh->getActiveMods();
}
const ModVerificationInfo & ActiveModsInSaveList::getVerificationInfo(TModID mod)
{
return VLC->modh->getModInfo(mod).getVerificationInfo();
}
void ActiveModsInSaveList::verifyActiveMods(const std::vector<std::pair<TModID, ModVerificationInfo>> & modList)
{
auto searchVerificationInfo = [&modList](const TModID & m) -> const ModVerificationInfo*
{
for(auto & i : modList)
if(i.first == m)
return &i.second;
return nullptr;
};
std::vector<TModID> missingMods, excessiveMods;
ModIncompatibility::ModListWithVersion missingModsResult;
ModIncompatibility::ModList excessiveModsResult;
for(const auto & m : VLC->modh->getActiveMods())
{
if(searchVerificationInfo(m))
continue;
//TODO: support actual disabling of these mods
if(VLC->modh->getModInfo(m).checkModGameplayAffecting())
excessiveMods.push_back(m);
}
for(const auto & infoPair : modList)
{
auto & remoteModId = infoPair.first;
auto & remoteModInfo = infoPair.second;
bool modAffectsGameplay = remoteModInfo.impactsGameplay;
//parent mod affects gameplay if child affects too
for(const auto & subInfoPair : modList)
modAffectsGameplay |= (subInfoPair.second.impactsGameplay && subInfoPair.second.parent == remoteModId);
if(!vstd::contains(VLC->modh->getAllMods(), remoteModId))
{
if(modAffectsGameplay)
missingMods.push_back(remoteModId); //mod is not installed
continue;
}
auto & localModInfo = VLC->modh->getModInfo(remoteModId).getVerificationInfo();
modAffectsGameplay |= VLC->modh->getModInfo(remoteModId).checkModGameplayAffecting();
bool modVersionCompatible = localModInfo.version.isNull()
|| remoteModInfo.version.isNull()
|| localModInfo.version.compatible(remoteModInfo.version);
bool modLocalyEnabled = vstd::contains(VLC->modh->getActiveMods(), remoteModId);
if(modVersionCompatible && modAffectsGameplay && modLocalyEnabled)
continue;
if(modAffectsGameplay)
missingMods.push_back(remoteModId); //incompatible mod impacts gameplay
}
//filter mods
for(auto & m : missingMods)
{
if(auto * vInfo = searchVerificationInfo(m))
{
assert(vInfo->parent != m);
if(!vInfo->parent.empty() && vstd::contains(missingMods, vInfo->parent))
continue;
missingModsResult.push_back({vInfo->name, vInfo->version.toString()});
}
}
for(auto & m : excessiveMods)
{
auto & vInfo = VLC->modh->getModInfo(m).getVerificationInfo();
assert(vInfo.parent != m);
if(!vInfo.parent.empty() && vstd::contains(excessiveMods, vInfo.parent))
continue;
excessiveModsResult.push_back(vInfo.name);
}
if(!missingModsResult.empty() || !excessiveModsResult.empty())
throw ModIncompatibility(missingModsResult, excessiveModsResult);
//TODO: support actual enabling of required mods
}
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,51 @@
/*
* ActiveModsInSaveList.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include "ModVerificationInfo.h"
VCMI_LIB_NAMESPACE_BEGIN
class ActiveModsInSaveList
{
std::vector<TModID> getActiveMods();
const ModVerificationInfo & getVerificationInfo(TModID mod);
/// Checks whether provided mod list is compatible with current VLC and throws on failure
void verifyActiveMods(const std::vector<std::pair<TModID, ModVerificationInfo>> & modList);
public:
template <typename Handler> void serialize(Handler &h, const int version)
{
if(h.saving)
{
std::vector<TModID> activeMods = getActiveMods();
h & activeMods;
for(const auto & m : activeMods)
h & getVerificationInfo(m);
}
else
{
std::vector<TModID> saveActiveMods;
h & saveActiveMods;
std::vector<std::pair<TModID, ModVerificationInfo>> saveModInfos(saveActiveMods.size());
for(int i = 0; i < saveActiveMods.size(); ++i)
{
saveModInfos[i].first = saveActiveMods[i];
h & saveModInfos[i].second;
}
verifyActiveMods(saveModInfos);
}
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -491,88 +491,6 @@ void CModHandler::afterLoad(bool onlyEssential)
std::fstream file(CResourceHandler::get()->getResourceName(ResourcePath("config/modSettings.json"))->c_str(), std::ofstream::out | std::ofstream::trunc);
file << modSettings.toJson();
}
}
void CModHandler::trySetActiveMods(const std::vector<std::pair<TModID, CModInfo::VerificationInfo>> & modList)
{
auto searchVerificationInfo = [&modList](const TModID & m) -> const CModInfo::VerificationInfo*
{
for(auto & i : modList)
if(i.first == m)
return &i.second;
return nullptr;
};
std::vector<TModID> missingMods, excessiveMods;
ModIncompatibility::ModListWithVersion missingModsResult;
ModIncompatibility::ModList excessiveModsResult;
for(const auto & m : activeMods)
{
if(searchVerificationInfo(m))
continue;
//TODO: support actual disabling of these mods
if(getModInfo(m).checkModGameplayAffecting())
excessiveMods.push_back(m);
}
for(const auto & infoPair : modList)
{
auto & remoteModId = infoPair.first;
auto & remoteModInfo = infoPair.second;
bool modAffectsGameplay = remoteModInfo.impactsGameplay;
//parent mod affects gameplay if child affects too
for(const auto & subInfoPair : modList)
modAffectsGameplay |= (subInfoPair.second.impactsGameplay && subInfoPair.second.parent == remoteModId);
if(!allMods.count(remoteModId))
{
if(modAffectsGameplay)
missingMods.push_back(remoteModId); //mod is not installed
continue;
}
auto & localModInfo = getModInfo(remoteModId).getVerificationInfo();
modAffectsGameplay |= getModInfo(remoteModId).checkModGameplayAffecting();
bool modVersionCompatible = localModInfo.version.isNull()
|| remoteModInfo.version.isNull()
|| localModInfo.version.compatible(remoteModInfo.version);
bool modLocalyEnabled = vstd::contains(activeMods, remoteModId);
if(modVersionCompatible && modAffectsGameplay && modLocalyEnabled)
continue;
if(modAffectsGameplay)
missingMods.push_back(remoteModId); //incompatible mod impacts gameplay
}
//filter mods
for(auto & m : missingMods)
{
if(auto * vInfo = searchVerificationInfo(m))
{
assert(vInfo->parent != m);
if(!vInfo->parent.empty() && vstd::contains(missingMods, vInfo->parent))
continue;
missingModsResult.push_back({vInfo->name, vInfo->version.toString()});
}
}
for(auto & m : excessiveMods)
{
auto & vInfo = getModInfo(m).getVerificationInfo();
assert(vInfo.parent != m);
if(!vInfo.parent.empty() && vstd::contains(excessiveMods, vInfo.parent))
continue;
excessiveModsResult.push_back(vInfo.name);
}
if(!missingModsResult.empty() || !excessiveModsResult.empty())
throw ModIncompatibility(missingModsResult, excessiveModsResult);
//TODO: support actual enabling of required mods
}
VCMI_LIB_NAMESPACE_END

View File

@ -9,21 +9,22 @@
*/
#pragma once
#include "CModInfo.h"
VCMI_LIB_NAMESPACE_BEGIN
class CModHandler;
class CModIndentifier;
class CModInfo;
struct CModVersion;
class JsonNode;
class IHandlerBase;
class CIdentifierStorage;
class CContentHandler;
struct ModVerificationInfo;
class ResourcePath;
using TModID = std::string;
class DLL_LINKAGE CModHandler : boost::noncopyable
class DLL_LINKAGE CModHandler final : boost::noncopyable
{
std::map <TModID, CModInfo> allMods;
std::vector <TModID> activeMods;//active mods, in order in which they were loaded
@ -50,9 +51,6 @@ class DLL_LINKAGE CModHandler : boost::noncopyable
CModVersion getModVersion(TModID modName) const;
/// Attempt to set active mods according to provided list of mods from save, throws on failure
void trySetActiveMods(const std::vector<std::pair<TModID, CModInfo::VerificationInfo>> & modList);
public:
std::shared_ptr<CContentHandler> content; //(!)Do not serialize FIXME: make private
@ -79,32 +77,7 @@ public:
void afterLoad(bool onlyEssential);
CModHandler();
virtual ~CModHandler();
template <typename Handler> void serialize(Handler &h, const int version)
{
if(h.saving)
{
h & activeMods;
for(const auto & m : activeMods)
h & getModInfo(m).getVerificationInfo();
}
else
{
loadMods();
std::vector<TModID> saveActiveMods;
h & saveActiveMods;
std::vector<std::pair<TModID, CModInfo::VerificationInfo>> saveModInfos(saveActiveMods.size());
for(int i = 0; i < saveActiveMods.size(); ++i)
{
saveModInfos[i].first = saveActiveMods[i];
h & saveModInfos[i].second;
}
trySetActiveMods(saveModInfos);
}
}
~CModHandler();
};
VCMI_LIB_NAMESPACE_END

View File

@ -177,7 +177,7 @@ bool CModInfo::checkModGameplayAffecting() const
return *modGameplayAffecting;
}
const CModInfo::VerificationInfo & CModInfo::getVerificationInfo() const
const ModVerificationInfo & CModInfo::getVerificationInfo() const
{
return verificationInfo;
}

View File

@ -10,12 +10,10 @@
#pragma once
#include "../JsonNode.h"
#include "CModVersion.h"
#include "ModVerificationInfo.h"
VCMI_LIB_NAMESPACE_BEGIN
using TModID = std::string;
class DLL_LINKAGE CModInfo
{
/// cached result of checkModGameplayAffecting() call
@ -30,34 +28,6 @@ public:
PASSED
};
struct VerificationInfo
{
/// human-readable mod name
std::string name;
/// version of the mod
CModVersion version;
/// CRC-32 checksum of the mod
ui32 checksum = 0;
/// parent mod ID, empty if root-level mod
TModID parent;
/// for serialization purposes
bool impactsGameplay = true;
template <typename Handler>
void serialize(Handler & h, const int v)
{
h & name;
h & version;
h & checksum;
h & parent;
h & impactsGameplay;
}
};
/// identifier, identical to name of folder with mod
std::string identifier;
@ -94,7 +64,7 @@ public:
/// return true if this mod can affect gameplay, e.g. adds or modifies any game objects
bool checkModGameplayAffecting() const;
const VerificationInfo & getVerificationInfo() const;
const ModVerificationInfo & getVerificationInfo() const;
private:
/// true if mod is enabled by user, e.g. in Launcher UI
@ -103,7 +73,7 @@ private:
/// true if mod can be loaded - compatible and has no missing deps
bool implicitlyEnabled;
VerificationInfo verificationInfo;
ModVerificationInfo verificationInfo;
void loadLocalData(const JsonNode & data);
};

View File

@ -18,6 +18,8 @@
VCMI_LIB_NAMESPACE_BEGIN
using TModID = std::string;
struct DLL_LINKAGE CModVersion
{
static const int Any = -1;

View File

@ -52,12 +52,6 @@ class DLL_LINKAGE CIdentifierStorage
{
return id == other.id && scope == other.scope;
}
template <typename Handler> void serialize(Handler &h, const int version)
{
h & id;
h & scope;
}
};
std::multimap<std::string, ObjectData> registeredObjects;
@ -102,12 +96,6 @@ public:
/// called at the very end of loading to check for any missing ID's
void finalize();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & registeredObjects;
h & state;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,44 @@
/*
* ModVerificationInfo.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include "CModVersion.h"
VCMI_LIB_NAMESPACE_BEGIN
struct ModVerificationInfo
{
/// human-readable mod name
std::string name;
/// version of the mod
CModVersion version;
/// CRC-32 checksum of the mod
ui32 checksum = 0;
/// parent mod ID, empty if root-level mod
TModID parent;
/// for serialization purposes
bool impactsGameplay = true;
template <typename Handler>
void serialize(Handler & h, const int v)
{
h & name;
h & version;
h & checksum;
h & parent;
h & impactsGameplay;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -858,7 +858,7 @@ void AddQuest::applyGs(CGameState * gs) const
void UpdateArtHandlerLists::applyGs(CGameState * gs) const
{
VLC->arth->allocatedArtifacts = allocatedArtifacts;
gs->allocatedArtifacts = allocatedArtifacts;
}
void UpdateMapEvents::applyGs(CGameState * gs) const

View File

@ -1,52 +0,0 @@
/*
* RegisterTypes.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#define INSTANTIATE_REGISTER_TYPES_HERE
#include "RegisterTypes.h"
#include "../mapping/CMapInfo.h"
#include "../StartInfo.h"
#include "../mapObjects/CObjectHandler.h"
#include "../CCreatureHandler.h"
#include "../spells/CSpellHandler.h"
#include "../serializer/BinaryDeserializer.h"
#include "../serializer/BinarySerializer.h"
#include "../serializer/CTypeList.h"
VCMI_LIB_NAMESPACE_BEGIN
// For reference: peak memory usage by gcc during compilation of register type templates
// registerTypesMapObjects: 1.9 Gb
// registerTypes2: 2.2 Gb
// registerTypesClientPacks1 1.6 Gb
// registerTypesClientPacks2 1.6 Gb
// registerTypesServerPacks: 1.3 Gb
// registerTypes4: 1.3 Gb
#define DEFINE_EXTERNAL_METHOD(METHODNAME) \
extern template DLL_LINKAGE void METHODNAME<BinaryDeserializer>(BinaryDeserializer & s); \
extern template DLL_LINKAGE void METHODNAME<BinarySerializer>(BinarySerializer & s); \
extern template DLL_LINKAGE void METHODNAME<CTypeList>(CTypeList & s); \
//DEFINE_EXTERNAL_METHOD(registerTypesMapObjects)
DEFINE_EXTERNAL_METHOD(registerTypesMapObjects1)
DEFINE_EXTERNAL_METHOD(registerTypesMapObjects2)
DEFINE_EXTERNAL_METHOD(registerTypesClientPacks1)
DEFINE_EXTERNAL_METHOD(registerTypesClientPacks2)
DEFINE_EXTERNAL_METHOD(registerTypesServerPacks)
DEFINE_EXTERNAL_METHOD(registerTypesLobbyPacks)
template void registerTypes<BinaryDeserializer>(BinaryDeserializer & s);
template void registerTypes<BinarySerializer>(BinarySerializer & s);
template void registerTypes<CTypeList>(CTypeList & s);
VCMI_LIB_NAMESPACE_END

View File

@ -9,413 +9,20 @@
*/
#pragma once
#include "../networkPacks/PacksForClient.h"
#include "../networkPacks/PacksForClientBattle.h"
#include "../networkPacks/PacksForServer.h"
#include "../networkPacks/PacksForLobby.h"
#include "../networkPacks/SetStackEffect.h"
#include "../VCMI_Lib.h"
#include "../CArtHandler.h"
#include "../CCreatureSet.h"
#include "../CPlayerState.h"
#include "../CHeroHandler.h"
#include "../CTownHandler.h"
#include "../mapObjectConstructors/CRewardableConstructor.h"
#include "../mapObjectConstructors/CommonConstructors.h"
#include "../mapObjectConstructors/CBankInstanceConstructor.h"
#include "../mapObjectConstructors/DwellingInstanceConstructor.h"
#include "../mapObjectConstructors/HillFortInstanceConstructor.h"
#include "../mapObjectConstructors/ShipyardInstanceConstructor.h"
#include "../mapObjects/MapObjects.h"
#include "../mapObjects/CGCreature.h"
#include "../mapObjects/CGTownBuilding.h"
#include "../mapObjects/ObjectTemplate.h"
#include "../battle/CObstacleInstance.h"
#include "../bonuses/CBonusSystemNode.h"
#include "../bonuses/Limiters.h"
#include "../bonuses/Updaters.h"
#include "../bonuses/Propagators.h"
#include "../CStack.h"
#include "RegisterTypesClientPacks.h"
#include "RegisterTypesLobbyPacks.h"
#include "RegisterTypesMapObjects.h"
#include "RegisterTypesServerPacks.h"
VCMI_LIB_NAMESPACE_BEGIN
class BinarySerializer;
class BinaryDeserializer;
class CTypeList;
template<typename Serializer>
void registerTypesMapObjects1(Serializer &s)
{
//////////////////////////////////////////////////////////////////////////
// Adventure map objects
//////////////////////////////////////////////////////////////////////////
s.template registerType<IObjectInterface, CGObjectInstance>();
// Non-armed objects
s.template registerType<CGObjectInstance, CGTeleport>();
s.template registerType<CGTeleport, CGMonolith>();
s.template registerType<CGMonolith, CGSubterraneanGate>();
s.template registerType<CGMonolith, CGWhirlpool>();
s.template registerType<CGObjectInstance, CGSignBottle>();
s.template registerType<CGObjectInstance, CGKeys>();
s.template registerType<CGKeys, CGKeymasterTent>();
s.template registerType<CGKeys, CGBorderGuard>(); s.template registerType<IQuestObject, CGBorderGuard>();
s.template registerType<CGBorderGuard, CGBorderGate>();
s.template registerType<CGObjectInstance, CGBoat>();
s.template registerType<CGObjectInstance, CGMagi>();
s.template registerType<CGObjectInstance, CGSirens>();
s.template registerType<CGObjectInstance, CGShipyard>();
s.template registerType<CGObjectInstance, CGDenOfthieves>();
s.template registerType<CGObjectInstance, CGLighthouse>();
s.template registerType<CGObjectInstance, CGTerrainPatch>();
s.template registerType<CGObjectInstance, HillFort>();
s.template registerType<CGObjectInstance, CGMarket>();
s.template registerType<CGMarket, CGBlackMarket>();
s.template registerType<CGMarket, CGUniversity>();
s.template registerType<CGObjectInstance, CGHeroPlaceholder>();
s.template registerType<CGObjectInstance, CArmedInstance>(); s.template registerType<CBonusSystemNode, CArmedInstance>(); s.template registerType<CCreatureSet, CArmedInstance>();
// Armed objects
s.template registerType<CArmedInstance, CGHeroInstance>(); s.template registerType<CArtifactSet, CGHeroInstance>();
s.template registerType<CArmedInstance, CGDwelling>();
s.template registerType<CGDwelling, CGTownInstance>();
s.template registerType<CArmedInstance, CGPandoraBox>();
s.template registerType<CGPandoraBox, CGEvent>();
s.template registerType<CArmedInstance, CGCreature>();
s.template registerType<CArmedInstance, CGGarrison>();
s.template registerType<CArmedInstance, CGArtifact>();
s.template registerType<CArmedInstance, CGResource>();
s.template registerType<CArmedInstance, CGMine>();
s.template registerType<CArmedInstance, CBank>();
s.template registerType<CArmedInstance, CGSeerHut>(); s.template registerType<IQuestObject, CGSeerHut>();
s.template registerType<CGSeerHut, CGQuestGuard>();
}
template<typename Serializer>
void registerTypesMapObjectTypes(Serializer &s)
{
s.template registerType<AObjectTypeHandler, CRewardableConstructor>();
s.template registerType<AObjectTypeHandler, CHeroInstanceConstructor>();
s.template registerType<AObjectTypeHandler, CTownInstanceConstructor>();
s.template registerType<AObjectTypeHandler, DwellingInstanceConstructor>();
s.template registerType<AObjectTypeHandler, CBankInstanceConstructor>();
s.template registerType<AObjectTypeHandler, BoatInstanceConstructor>();
s.template registerType<AObjectTypeHandler, MarketInstanceConstructor>();
s.template registerType<AObjectTypeHandler, CObstacleConstructor>();
s.template registerType<AObjectTypeHandler, ShipyardInstanceConstructor>();
s.template registerType<AObjectTypeHandler, HillFortInstanceConstructor>();
s.template registerType<AObjectTypeHandler, CreatureInstanceConstructor>();
s.template registerType<AObjectTypeHandler, ResourceInstanceConstructor>();
#define REGISTER_GENERIC_HANDLER(TYPENAME) s.template registerType<AObjectTypeHandler, CDefaultObjectTypeHandler<TYPENAME> >()
REGISTER_GENERIC_HANDLER(CGObjectInstance);
REGISTER_GENERIC_HANDLER(CGArtifact);
REGISTER_GENERIC_HANDLER(CGBlackMarket);
REGISTER_GENERIC_HANDLER(CGBoat);
REGISTER_GENERIC_HANDLER(CGBorderGate);
REGISTER_GENERIC_HANDLER(CGBorderGuard);
REGISTER_GENERIC_HANDLER(CGCreature);
REGISTER_GENERIC_HANDLER(CGDenOfthieves);
REGISTER_GENERIC_HANDLER(CGDwelling);
REGISTER_GENERIC_HANDLER(CGEvent);
REGISTER_GENERIC_HANDLER(CGGarrison);
REGISTER_GENERIC_HANDLER(CGHeroPlaceholder);
REGISTER_GENERIC_HANDLER(CGHeroInstance);
REGISTER_GENERIC_HANDLER(CGKeymasterTent);
REGISTER_GENERIC_HANDLER(CGLighthouse);
REGISTER_GENERIC_HANDLER(CGTerrainPatch);
REGISTER_GENERIC_HANDLER(CGMagi);
REGISTER_GENERIC_HANDLER(CGMarket);
REGISTER_GENERIC_HANDLER(CGMine);
REGISTER_GENERIC_HANDLER(CGObelisk);
REGISTER_GENERIC_HANDLER(CGPandoraBox);
REGISTER_GENERIC_HANDLER(CGQuestGuard);
REGISTER_GENERIC_HANDLER(CGResource);
REGISTER_GENERIC_HANDLER(CGSeerHut);
REGISTER_GENERIC_HANDLER(CGShipyard);
REGISTER_GENERIC_HANDLER(CGSignBottle);
REGISTER_GENERIC_HANDLER(CGSirens);
REGISTER_GENERIC_HANDLER(CGMonolith);
REGISTER_GENERIC_HANDLER(CGSubterraneanGate);
REGISTER_GENERIC_HANDLER(CGWhirlpool);
REGISTER_GENERIC_HANDLER(CGTownInstance);
REGISTER_GENERIC_HANDLER(CGUniversity);
REGISTER_GENERIC_HANDLER(HillFort);
#undef REGISTER_GENERIC_HANDLER
s.template registerType<IUpdater, GrowsWithLevelUpdater>();
s.template registerType<IUpdater, TimesHeroLevelUpdater>();
s.template registerType<IUpdater, TimesStackLevelUpdater>();
s.template registerType<IUpdater, OwnerUpdater>();
s.template registerType<IUpdater, ArmyMovementUpdater>();
s.template registerType<ILimiter, AnyOfLimiter>();
s.template registerType<ILimiter, NoneOfLimiter>();
s.template registerType<ILimiter, OppositeSideLimiter>();
//new types (other than netpacks) must register here
//order of type registration is critical for loading old savegames
}
template<typename Serializer>
void registerTypesMapObjects2(Serializer &s)
{
//Other object-related
s.template registerType<IObjectInterface, CGTownBuilding>();
s.template registerType<CGTownBuilding, CTownBonus>();
s.template registerType<CGTownBuilding, COPWBonus>();
s.template registerType<CGTownBuilding, CTownRewardableBuilding>();
s.template registerType<CGObjectInstance, CRewardableObject>();
s.template registerType<CGObjectInstance, CTeamVisited>();
s.template registerType<CTeamVisited, CGObelisk>();
//s.template registerType<CQuest>();
//s.template registerType<IQuestObject>();
//end of objects
//////////////////////////////////////////////////////////////////////////
// Bonus system
//////////////////////////////////////////////////////////////////////////
//s.template registerType<IPropagator>();
s.template registerType<IPropagator, CPropagatorNodeType>();
// Limiters
//s.template registerType<ILimiter>();
s.template registerType<ILimiter, AllOfLimiter>();
s.template registerType<ILimiter, CCreatureTypeLimiter>();
s.template registerType<ILimiter, HasAnotherBonusLimiter>();
s.template registerType<ILimiter, CreatureTerrainLimiter>();
s.template registerType<ILimiter, FactionLimiter>();
s.template registerType<ILimiter, CreatureLevelLimiter>();
s.template registerType<ILimiter, CreatureAlignmentLimiter>();
s.template registerType<ILimiter, RankRangeLimiter>();
s.template registerType<ILimiter, UnitOnHexLimiter>();
// s.template registerType<CBonusSystemNode>();
s.template registerType<CBonusSystemNode, CArtifact>();
s.template registerType<CBonusSystemNode, CCreature>();
s.template registerType<CBonusSystemNode, CStackInstance>();
s.template registerType<CStackInstance, CCommanderInstance>();
s.template registerType<CBonusSystemNode, PlayerState>();
s.template registerType<CBonusSystemNode, TeamState>();
//s.template registerType<CGameState>(); //TODO
//s.template registerType<CArmedInstance>();
s.template registerType<CBonusSystemNode, CStack>();
s.template registerType<CBonusSystemNode, BattleInfo>();
//s.template registerType<QuestInfo>();
s.template registerType<CBonusSystemNode, CArtifactInstance>();
//s.template registerType<CObstacleInstance>();
s.template registerType<CObstacleInstance, SpellCreatedObstacle>();
}
template<typename Serializer>
void registerTypesClientPacks1(Serializer &s)
{
s.template registerType<CPack, CPackForClient>();
s.template registerType<CPackForClient, PackageApplied>();
s.template registerType<CPackForClient, SystemMessage>();
s.template registerType<CPackForClient, PlayerBlocked>();
s.template registerType<CPackForClient, PlayerCheated>();
s.template registerType<CPackForClient, PlayerStartsTurn>();
s.template registerType<CPackForClient, DaysWithoutTown>();
s.template registerType<CPackForClient, TurnTimeUpdate>();
s.template registerType<CPackForClient, SetResources>();
s.template registerType<CPackForClient, SetPrimSkill>();
s.template registerType<CPackForClient, SetSecSkill>();
s.template registerType<CPackForClient, HeroVisitCastle>();
s.template registerType<CPackForClient, ChangeSpells>();
s.template registerType<CPackForClient, SetMana>();
s.template registerType<CPackForClient, SetMovePoints>();
s.template registerType<CPackForClient, FoWChange>();
s.template registerType<CPackForClient, SetAvailableHero>();
s.template registerType<CPackForClient, GiveBonus>();
s.template registerType<CPackForClient, ChangeObjPos>();
s.template registerType<CPackForClient, PlayerEndsTurn>();
s.template registerType<CPackForClient, PlayerEndsGame>();
s.template registerType<CPackForClient, PlayerReinitInterface>();
s.template registerType<CPackForClient, RemoveBonus>();
s.template registerType<CPackForClient, UpdateArtHandlerLists>();
s.template registerType<CPackForClient, UpdateMapEvents>();
s.template registerType<CPackForClient, UpdateCastleEvents>();
s.template registerType<CPackForClient, ChangeFormation>();
s.template registerType<CPackForClient, RemoveObject>();
s.template registerType<CPackForClient, TryMoveHero>();
s.template registerType<CPackForClient, NewStructures>();
s.template registerType<CPackForClient, RazeStructures>();
s.template registerType<CPackForClient, SetAvailableCreatures>();
s.template registerType<CPackForClient, SetHeroesInTown>();
s.template registerType<CPackForClient, HeroRecruited>();
s.template registerType<CPackForClient, GiveHero>();
s.template registerType<CPackForClient, NewTurn>();
s.template registerType<CPackForClient, InfoWindow>();
s.template registerType<CPackForClient, SetObjectProperty>();
s.template registerType<CPackForClient, AdvmapSpellCast>();
s.template registerType<CPackForClient, OpenWindow>();
s.template registerType<CPackForClient, NewObject>();
s.template registerType<CPackForClient, NewArtifact>();
s.template registerType<CPackForClient, AddQuest>();
s.template registerType<CPackForClient, SetAvailableArtifacts>();
s.template registerType<CPackForClient, CenterView>();
s.template registerType<CPackForClient, HeroVisit>();
s.template registerType<CPackForClient, SetCommanderProperty>();
s.template registerType<CPackForClient, ChangeObjectVisitors>();
s.template registerType<CPackForClient, ShowWorldViewEx>();
s.template registerType<CPackForClient, PrepareHeroLevelUp>();
s.template registerType<CPackForClient, EntitiesChanged>();
}
template<typename Serializer>
void registerTypesClientPacks2(Serializer &s)
{
s.template registerType<CPackForClient, BattleStart>();
s.template registerType<CPackForClient, BattleNextRound>();
s.template registerType<CPackForClient, BattleSetActiveStack>();
s.template registerType<CPackForClient, BattleResult>();
s.template registerType<CPackForClient, BattleResultAccepted>();
s.template registerType<CPackForClient, BattleCancelled>();
s.template registerType<CPackForClient, BattleLogMessage>();
s.template registerType<CPackForClient, BattleStackMoved>();
s.template registerType<CPackForClient, BattleAttack>();
s.template registerType<CPackForClient, StartAction>();
s.template registerType<CPackForClient, EndAction>();
s.template registerType<CPackForClient, BattleSpellCast>();
s.template registerType<CPackForClient, SetStackEffect>();
s.template registerType<CPackForClient, BattleTriggerEffect>();
s.template registerType<CPackForClient, BattleUpdateGateState>();
s.template registerType<CPackForClient, BattleSetStackProperty>();
s.template registerType<CPackForClient, StacksInjured>();
s.template registerType<CPackForClient, BattleResultsApplied>();
s.template registerType<CPackForClient, BattleUnitsChanged>();
s.template registerType<CPackForClient, BattleObstaclesChanged>();
s.template registerType<CPackForClient, CatapultAttack>();
s.template registerType<CPackForClient, Query>();
s.template registerType<Query, HeroLevelUp>();
s.template registerType<Query, CommanderLevelUp>();
s.template registerType<Query, BlockingDialog>();
s.template registerType<Query, GarrisonDialog>();
s.template registerType<Query, ExchangeDialog>();
s.template registerType<Query, TeleportDialog>();
s.template registerType<Query, MapObjectSelectDialog>();
s.template registerType<CPackForClient, CGarrisonOperationPack>();
s.template registerType<CGarrisonOperationPack, ChangeStackCount>();
s.template registerType<CGarrisonOperationPack, SetStackType>();
s.template registerType<CGarrisonOperationPack, EraseStack>();
s.template registerType<CGarrisonOperationPack, SwapStacks>();
s.template registerType<CGarrisonOperationPack, InsertNewStack>();
s.template registerType<CGarrisonOperationPack, RebalanceStacks>();
s.template registerType<CPackForClient, CArtifactOperationPack>();
s.template registerType<CArtifactOperationPack, PutArtifact>();
s.template registerType<CArtifactOperationPack, EraseArtifact>();
s.template registerType<CArtifactOperationPack, MoveArtifact>();
s.template registerType<CArtifactOperationPack, AssembledArtifact>();
s.template registerType<CArtifactOperationPack, DisassembledArtifact>();
s.template registerType<CArtifactOperationPack, BulkMoveArtifacts>();
s.template registerType<CPackForClient, PlayerMessageClient>();
s.template registerType<CGarrisonOperationPack, BulkRebalanceStacks>();
s.template registerType<CGarrisonOperationPack, BulkSmartRebalanceStacks>();
}
template<typename Serializer>
void registerTypesServerPacks(Serializer &s)
{
s.template registerType<CPack, CPackForServer>();
s.template registerType<CPackForServer, EndTurn>();
s.template registerType<CPackForServer, DismissHero>();
s.template registerType<CPackForServer, MoveHero>();
s.template registerType<CPackForServer, ArrangeStacks>();
s.template registerType<CPackForServer, DisbandCreature>();
s.template registerType<CPackForServer, BuildStructure>();
s.template registerType<CPackForServer, RecruitCreatures>();
s.template registerType<CPackForServer, UpgradeCreature>();
s.template registerType<CPackForServer, GarrisonHeroSwap>();
s.template registerType<CPackForServer, ExchangeArtifacts>();
s.template registerType<CPackForServer, AssembleArtifacts>();
s.template registerType<CPackForServer, BuyArtifact>();
s.template registerType<CPackForServer, TradeOnMarketplace>();
s.template registerType<CPackForServer, SetFormation>();
s.template registerType<CPackForServer, HireHero>();
s.template registerType<CPackForServer, BuildBoat>();
s.template registerType<CPackForServer, QueryReply>();
s.template registerType<CPackForServer, MakeAction>();
s.template registerType<CPackForServer, DigWithHero>();
s.template registerType<CPackForServer, CastAdvSpell>();
s.template registerType<CPackForServer, CastleTeleportHero>();
s.template registerType<CPackForServer, SaveGame>();
s.template registerType<CPackForServer, PlayerMessage>();
s.template registerType<CPackForServer, BulkSplitStack>();
s.template registerType<CPackForServer, BulkMergeStacks>();
s.template registerType<CPackForServer, BulkSmartSplitStack>();
s.template registerType<CPackForServer, BulkMoveArmy>();
s.template registerType<CPackForServer, BulkExchangeArtifacts>();
s.template registerType<CPackForServer, EraseArtifactByClient>();
s.template registerType<CPackForServer, GamePause>();
}
template<typename Serializer>
void registerTypesLobbyPacks(Serializer &s)
{
s.template registerType<CPack, CPackForLobby>();
s.template registerType<CPackForLobby, CLobbyPackToPropagate>();
s.template registerType<CPackForLobby, CLobbyPackToServer>();
// Any client can sent
s.template registerType<CLobbyPackToPropagate, LobbyClientConnected>();
s.template registerType<CLobbyPackToPropagate, LobbyClientDisconnected>();
s.template registerType<CLobbyPackToPropagate, LobbyChatMessage>();
// Only host client send
s.template registerType<CLobbyPackToPropagate, LobbyGuiAction>();
s.template registerType<CLobbyPackToPropagate, LobbyLoadProgress>();
s.template registerType<CLobbyPackToPropagate, LobbyEndGame>();
s.template registerType<CLobbyPackToPropagate, LobbyStartGame>();
s.template registerType<CLobbyPackToPropagate, LobbyChangeHost>();
// Only server send
s.template registerType<CLobbyPackToPropagate, LobbyUpdateState>();
s.template registerType<CLobbyPackToPropagate, LobbyShowMessage>();
// For client with permissions
s.template registerType<CLobbyPackToServer, LobbyChangePlayerOption>();
// Only for host client
s.template registerType<CLobbyPackToServer, LobbySetMap>();
s.template registerType<CLobbyPackToServer, LobbySetCampaign>();
s.template registerType<CLobbyPackToServer, LobbySetCampaignMap>();
s.template registerType<CLobbyPackToServer, LobbySetCampaignBonus>();
s.template registerType<CLobbyPackToServer, LobbySetPlayer>();
s.template registerType<CLobbyPackToServer, LobbySetPlayerName>();
s.template registerType<CLobbyPackToServer, LobbySetTurnTime>();
s.template registerType<CLobbyPackToServer, LobbySetSimturns>();
s.template registerType<CLobbyPackToServer, LobbySetDifficulty>();
s.template registerType<CLobbyPackToServer, LobbyForceSetPlayer>();
}
template<typename Serializer>
void registerTypes(Serializer &s)
{
registerTypesMapObjects1(s);
registerTypesMapObjects2(s);
registerTypesMapObjectTypes(s);
registerTypesClientPacks1(s);
registerTypesClientPacks2(s);
registerTypesMapObjects(s);
registerTypesClientPacks(s);
registerTypesServerPacks(s);
registerTypesLobbyPacks(s);
}
#ifndef INSTANTIATE_REGISTER_TYPES_HERE
extern template DLL_LINKAGE void registerTypes<BinaryDeserializer>(BinaryDeserializer & s);
extern template DLL_LINKAGE void registerTypes<BinarySerializer>(BinarySerializer & s);
extern template DLL_LINKAGE void registerTypes<CTypeList>(CTypeList & s);
#endif
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,125 @@
/*
* RegisterTypesClientPacks.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include "../networkPacks/PacksForClient.h"
#include "../networkPacks/PacksForClientBattle.h"
#include "../networkPacks/SetStackEffect.h"
VCMI_LIB_NAMESPACE_BEGIN
template<typename Serializer>
void registerTypesClientPacks(Serializer &s)
{
s.template registerType<CPack, CPackForClient>();
s.template registerType<CPackForClient, PackageApplied>();
s.template registerType<CPackForClient, SystemMessage>();
s.template registerType<CPackForClient, PlayerBlocked>();
s.template registerType<CPackForClient, PlayerCheated>();
s.template registerType<CPackForClient, PlayerStartsTurn>();
s.template registerType<CPackForClient, DaysWithoutTown>();
s.template registerType<CPackForClient, TurnTimeUpdate>();
s.template registerType<CPackForClient, SetResources>();
s.template registerType<CPackForClient, SetPrimSkill>();
s.template registerType<CPackForClient, SetSecSkill>();
s.template registerType<CPackForClient, HeroVisitCastle>();
s.template registerType<CPackForClient, ChangeSpells>();
s.template registerType<CPackForClient, SetMana>();
s.template registerType<CPackForClient, SetMovePoints>();
s.template registerType<CPackForClient, FoWChange>();
s.template registerType<CPackForClient, SetAvailableHero>();
s.template registerType<CPackForClient, GiveBonus>();
s.template registerType<CPackForClient, ChangeObjPos>();
s.template registerType<CPackForClient, PlayerEndsTurn>();
s.template registerType<CPackForClient, PlayerEndsGame>();
s.template registerType<CPackForClient, PlayerReinitInterface>();
s.template registerType<CPackForClient, RemoveBonus>();
s.template registerType<CPackForClient, UpdateArtHandlerLists>();
s.template registerType<CPackForClient, UpdateMapEvents>();
s.template registerType<CPackForClient, UpdateCastleEvents>();
s.template registerType<CPackForClient, ChangeFormation>();
s.template registerType<CPackForClient, RemoveObject>();
s.template registerType<CPackForClient, TryMoveHero>();
s.template registerType<CPackForClient, NewStructures>();
s.template registerType<CPackForClient, RazeStructures>();
s.template registerType<CPackForClient, SetAvailableCreatures>();
s.template registerType<CPackForClient, SetHeroesInTown>();
s.template registerType<CPackForClient, HeroRecruited>();
s.template registerType<CPackForClient, GiveHero>();
s.template registerType<CPackForClient, NewTurn>();
s.template registerType<CPackForClient, InfoWindow>();
s.template registerType<CPackForClient, SetObjectProperty>();
s.template registerType<CPackForClient, AdvmapSpellCast>();
s.template registerType<CPackForClient, OpenWindow>();
s.template registerType<CPackForClient, NewObject>();
s.template registerType<CPackForClient, NewArtifact>();
s.template registerType<CPackForClient, AddQuest>();
s.template registerType<CPackForClient, SetAvailableArtifacts>();
s.template registerType<CPackForClient, CenterView>();
s.template registerType<CPackForClient, HeroVisit>();
s.template registerType<CPackForClient, SetCommanderProperty>();
s.template registerType<CPackForClient, ChangeObjectVisitors>();
s.template registerType<CPackForClient, ShowWorldViewEx>();
s.template registerType<CPackForClient, PrepareHeroLevelUp>();
s.template registerType<CPackForClient, EntitiesChanged>();
s.template registerType<CPackForClient, BattleStart>();
s.template registerType<CPackForClient, BattleNextRound>();
s.template registerType<CPackForClient, BattleSetActiveStack>();
s.template registerType<CPackForClient, BattleResult>();
s.template registerType<CPackForClient, BattleResultAccepted>();
s.template registerType<CPackForClient, BattleCancelled>();
s.template registerType<CPackForClient, BattleLogMessage>();
s.template registerType<CPackForClient, BattleStackMoved>();
s.template registerType<CPackForClient, BattleAttack>();
s.template registerType<CPackForClient, StartAction>();
s.template registerType<CPackForClient, EndAction>();
s.template registerType<CPackForClient, BattleSpellCast>();
s.template registerType<CPackForClient, SetStackEffect>();
s.template registerType<CPackForClient, BattleTriggerEffect>();
s.template registerType<CPackForClient, BattleUpdateGateState>();
s.template registerType<CPackForClient, BattleSetStackProperty>();
s.template registerType<CPackForClient, StacksInjured>();
s.template registerType<CPackForClient, BattleResultsApplied>();
s.template registerType<CPackForClient, BattleUnitsChanged>();
s.template registerType<CPackForClient, BattleObstaclesChanged>();
s.template registerType<CPackForClient, CatapultAttack>();
s.template registerType<CPackForClient, Query>();
s.template registerType<Query, HeroLevelUp>();
s.template registerType<Query, CommanderLevelUp>();
s.template registerType<Query, BlockingDialog>();
s.template registerType<Query, GarrisonDialog>();
s.template registerType<Query, ExchangeDialog>();
s.template registerType<Query, TeleportDialog>();
s.template registerType<Query, MapObjectSelectDialog>();
s.template registerType<CPackForClient, CGarrisonOperationPack>();
s.template registerType<CGarrisonOperationPack, ChangeStackCount>();
s.template registerType<CGarrisonOperationPack, SetStackType>();
s.template registerType<CGarrisonOperationPack, EraseStack>();
s.template registerType<CGarrisonOperationPack, SwapStacks>();
s.template registerType<CGarrisonOperationPack, InsertNewStack>();
s.template registerType<CGarrisonOperationPack, RebalanceStacks>();
s.template registerType<CPackForClient, CArtifactOperationPack>();
s.template registerType<CArtifactOperationPack, PutArtifact>();
s.template registerType<CArtifactOperationPack, EraseArtifact>();
s.template registerType<CArtifactOperationPack, MoveArtifact>();
s.template registerType<CArtifactOperationPack, AssembledArtifact>();
s.template registerType<CArtifactOperationPack, DisassembledArtifact>();
s.template registerType<CArtifactOperationPack, BulkMoveArtifacts>();
s.template registerType<CPackForClient, PlayerMessageClient>();
s.template registerType<CGarrisonOperationPack, BulkRebalanceStacks>();
s.template registerType<CGarrisonOperationPack, BulkSmartRebalanceStacks>();
}
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,62 @@
/*
* RegisterTypesLobbyPacks.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include "../networkPacks/PacksForLobby.h"
#include "../gameState/CGameState.h"
#include "../campaign/CampaignState.h"
#include "../mapping/CMapInfo.h"
#include "../rmg/CMapGenOptions.h"
#include "../gameState/TavernHeroesPool.h"
#include "../gameState/CGameStateCampaign.h"
#include "../mapping/CMap.h"
#include "../TerrainHandler.h"
#include "../RiverHandler.h"
#include "../RoadHandler.h"
VCMI_LIB_NAMESPACE_BEGIN
template<typename Serializer>
void registerTypesLobbyPacks(Serializer &s)
{
s.template registerType<CPack, CPackForLobby>();
s.template registerType<CPackForLobby, CLobbyPackToPropagate>();
s.template registerType<CPackForLobby, CLobbyPackToServer>();
// Any client can sent
s.template registerType<CLobbyPackToPropagate, LobbyClientConnected>();
s.template registerType<CLobbyPackToPropagate, LobbyClientDisconnected>();
s.template registerType<CLobbyPackToPropagate, LobbyChatMessage>();
// Only host client send
s.template registerType<CLobbyPackToPropagate, LobbyGuiAction>();
s.template registerType<CLobbyPackToPropagate, LobbyLoadProgress>();
s.template registerType<CLobbyPackToPropagate, LobbyEndGame>();
s.template registerType<CLobbyPackToPropagate, LobbyStartGame>();
s.template registerType<CLobbyPackToPropagate, LobbyChangeHost>();
// Only server send
s.template registerType<CLobbyPackToPropagate, LobbyUpdateState>();
s.template registerType<CLobbyPackToPropagate, LobbyShowMessage>();
// For client with permissions
s.template registerType<CLobbyPackToServer, LobbyChangePlayerOption>();
// Only for host client
s.template registerType<CLobbyPackToServer, LobbySetMap>();
s.template registerType<CLobbyPackToServer, LobbySetCampaign>();
s.template registerType<CLobbyPackToServer, LobbySetCampaignMap>();
s.template registerType<CLobbyPackToServer, LobbySetCampaignBonus>();
s.template registerType<CLobbyPackToServer, LobbySetPlayer>();
s.template registerType<CLobbyPackToServer, LobbySetPlayerName>();
s.template registerType<CLobbyPackToServer, LobbySetTurnTime>();
s.template registerType<CLobbyPackToServer, LobbySetSimturns>();
s.template registerType<CLobbyPackToServer, LobbySetDifficulty>();
s.template registerType<CLobbyPackToServer, LobbyForceSetPlayer>();
}
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,137 @@
/*
* RegisterTypesMapObjects.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include "../mapObjectConstructors/CBankInstanceConstructor.h"
#include "../mapObjects/MapObjects.h"
#include "../mapObjects/CGCreature.h"
#include "../mapObjects/CGTownBuilding.h"
#include "../mapObjects/ObjectTemplate.h"
#include "../battle/BattleInfo.h"
#include "../battle/CObstacleInstance.h"
#include "../bonuses/Limiters.h"
#include "../bonuses/Updaters.h"
#include "../bonuses/Propagators.h"
#include "../CPlayerState.h"
#include "../CStack.h"
#include "../CHeroHandler.h"
VCMI_LIB_NAMESPACE_BEGIN
template<typename Serializer>
void registerTypesMapObjects(Serializer &s)
{
//////////////////////////////////////////////////////////////////////////
// Adventure map objects
//////////////////////////////////////////////////////////////////////////
s.template registerType<IObjectInterface, CGObjectInstance>();
// Non-armed objects
s.template registerType<CGObjectInstance, CGTeleport>();
s.template registerType<CGTeleport, CGMonolith>();
s.template registerType<CGMonolith, CGSubterraneanGate>();
s.template registerType<CGMonolith, CGWhirlpool>();
s.template registerType<CGObjectInstance, CGSignBottle>();
s.template registerType<CGObjectInstance, CGKeys>();
s.template registerType<CGKeys, CGKeymasterTent>();
s.template registerType<CGKeys, CGBorderGuard>(); s.template registerType<IQuestObject, CGBorderGuard>();
s.template registerType<CGBorderGuard, CGBorderGate>();
s.template registerType<CGObjectInstance, CGBoat>();
s.template registerType<CGObjectInstance, CGMagi>();
s.template registerType<CGObjectInstance, CGSirens>();
s.template registerType<CGObjectInstance, CGShipyard>();
s.template registerType<CGObjectInstance, CGDenOfthieves>();
s.template registerType<CGObjectInstance, CGLighthouse>();
s.template registerType<CGObjectInstance, CGTerrainPatch>();
s.template registerType<CGObjectInstance, HillFort>();
s.template registerType<CGObjectInstance, CGMarket>();
s.template registerType<CGMarket, CGBlackMarket>();
s.template registerType<CGMarket, CGUniversity>();
s.template registerType<CGObjectInstance, CGHeroPlaceholder>();
s.template registerType<CGObjectInstance, CArmedInstance>(); s.template registerType<CBonusSystemNode, CArmedInstance>(); s.template registerType<CCreatureSet, CArmedInstance>();
// Armed objects
s.template registerType<CArmedInstance, CGHeroInstance>(); s.template registerType<CArtifactSet, CGHeroInstance>();
s.template registerType<CArmedInstance, CGDwelling>();
s.template registerType<CGDwelling, CGTownInstance>();
s.template registerType<CArmedInstance, CGPandoraBox>();
s.template registerType<CGPandoraBox, CGEvent>();
s.template registerType<CArmedInstance, CGCreature>();
s.template registerType<CArmedInstance, CGGarrison>();
s.template registerType<CArmedInstance, CGArtifact>();
s.template registerType<CArmedInstance, CGResource>();
s.template registerType<CArmedInstance, CGMine>();
s.template registerType<CArmedInstance, CBank>();
s.template registerType<CArmedInstance, CGSeerHut>(); s.template registerType<IQuestObject, CGSeerHut>();
s.template registerType<CGSeerHut, CGQuestGuard>();
s.template registerType<IUpdater, GrowsWithLevelUpdater>();
s.template registerType<IUpdater, TimesHeroLevelUpdater>();
s.template registerType<IUpdater, TimesStackLevelUpdater>();
s.template registerType<IUpdater, OwnerUpdater>();
s.template registerType<IUpdater, ArmyMovementUpdater>();
s.template registerType<ILimiter, AnyOfLimiter>();
s.template registerType<ILimiter, NoneOfLimiter>();
s.template registerType<ILimiter, OppositeSideLimiter>();
//new types (other than netpacks) must register here
//order of type registration is critical for loading old savegames
//Other object-related
s.template registerType<IObjectInterface, CGTownBuilding>();
s.template registerType<CGTownBuilding, CTownBonus>();
s.template registerType<CGTownBuilding, COPWBonus>();
s.template registerType<CGTownBuilding, CTownRewardableBuilding>();
s.template registerType<CGObjectInstance, CRewardableObject>();
s.template registerType<CGObjectInstance, CTeamVisited>();
s.template registerType<CTeamVisited, CGObelisk>();
//end of objects
//////////////////////////////////////////////////////////////////////////
// Bonus system
//////////////////////////////////////////////////////////////////////////
//s.template registerType<IPropagator>();
s.template registerType<IPropagator, CPropagatorNodeType>();
// Limiters
//s.template registerType<ILimiter>();
s.template registerType<ILimiter, AllOfLimiter>();
s.template registerType<ILimiter, CCreatureTypeLimiter>();
s.template registerType<ILimiter, HasAnotherBonusLimiter>();
s.template registerType<ILimiter, CreatureTerrainLimiter>();
s.template registerType<ILimiter, FactionLimiter>();
s.template registerType<ILimiter, CreatureLevelLimiter>();
s.template registerType<ILimiter, CreatureAlignmentLimiter>();
s.template registerType<ILimiter, RankRangeLimiter>();
s.template registerType<ILimiter, UnitOnHexLimiter>();
// s.template registerType<CBonusSystemNode>();
s.template registerType<CBonusSystemNode, CArtifact>();
s.template registerType<CBonusSystemNode, CCreature>();
s.template registerType<CBonusSystemNode, CStackInstance>();
s.template registerType<CStackInstance, CCommanderInstance>();
s.template registerType<CBonusSystemNode, PlayerState>();
s.template registerType<CBonusSystemNode, TeamState>();
//s.template registerType<CGameState>(); //TODO
//s.template registerType<CArmedInstance>();
s.template registerType<CBonusSystemNode, CStack>();
s.template registerType<CBonusSystemNode, BattleInfo>();
//s.template registerType<QuestInfo>();
s.template registerType<CBonusSystemNode, CArtifactInstance>();
//s.template registerType<CObstacleInstance>();
s.template registerType<CObstacleInstance, SpellCreatedObstacle>();
}
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,56 @@
/*
* RegisterTypesServerPacks.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include "../networkPacks/PacksForServer.h"
VCMI_LIB_NAMESPACE_BEGIN
class BinarySerializer;
class BinaryDeserializer;
class CTypeList;
template<typename Serializer>
void registerTypesServerPacks(Serializer &s)
{
s.template registerType<CPack, CPackForServer>();
s.template registerType<CPackForServer, EndTurn>();
s.template registerType<CPackForServer, DismissHero>();
s.template registerType<CPackForServer, MoveHero>();
s.template registerType<CPackForServer, ArrangeStacks>();
s.template registerType<CPackForServer, DisbandCreature>();
s.template registerType<CPackForServer, BuildStructure>();
s.template registerType<CPackForServer, RecruitCreatures>();
s.template registerType<CPackForServer, UpgradeCreature>();
s.template registerType<CPackForServer, GarrisonHeroSwap>();
s.template registerType<CPackForServer, ExchangeArtifacts>();
s.template registerType<CPackForServer, AssembleArtifacts>();
s.template registerType<CPackForServer, BuyArtifact>();
s.template registerType<CPackForServer, TradeOnMarketplace>();
s.template registerType<CPackForServer, SetFormation>();
s.template registerType<CPackForServer, HireHero>();
s.template registerType<CPackForServer, BuildBoat>();
s.template registerType<CPackForServer, QueryReply>();
s.template registerType<CPackForServer, MakeAction>();
s.template registerType<CPackForServer, DigWithHero>();
s.template registerType<CPackForServer, CastAdvSpell>();
s.template registerType<CPackForServer, CastleTeleportHero>();
s.template registerType<CPackForServer, SaveGame>();
s.template registerType<CPackForServer, PlayerMessage>();
s.template registerType<CPackForServer, BulkSplitStack>();
s.template registerType<CPackForServer, BulkMergeStacks>();
s.template registerType<CPackForServer, BulkSmartSplitStack>();
s.template registerType<CPackForServer, BulkMoveArmy>();
s.template registerType<CPackForServer, BulkExchangeArtifacts>();
s.template registerType<CPackForServer, EraseArtifactByClient>();
s.template registerType<CPackForServer, GamePause>();
}
VCMI_LIB_NAMESPACE_END

View File

@ -1,33 +0,0 @@
/*
* TypesClientPacks1.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "RegisterTypes.h"
#include "../StartInfo.h"
#include "../mapObjects/CObjectHandler.h"
#include "../CCreatureHandler.h"
#include "../VCMI_Lib.h"
#include "../CArtHandler.h"
#include "../CHeroHandler.h"
#include "../spells/CSpellHandler.h"
#include "../CTownHandler.h"
#include "../serializer/BinaryDeserializer.h"
#include "../serializer/BinarySerializer.h"
#include "../serializer/CTypeList.h"
VCMI_LIB_NAMESPACE_BEGIN
template void registerTypesClientPacks1<BinaryDeserializer>(BinaryDeserializer & s);
template void registerTypesClientPacks1<BinarySerializer>(BinarySerializer & s);
template void registerTypesClientPacks1<CTypeList>(CTypeList & s);
VCMI_LIB_NAMESPACE_END

View File

@ -1,37 +0,0 @@
/*
* TypesClientPacks2.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "RegisterTypes.h"
#include "../StartInfo.h"
#include "../CStack.h"
#include "../battle/BattleInfo.h"
#include "../mapObjects/CObjectHandler.h"
#include "../CCreatureHandler.h"
#include "../VCMI_Lib.h"
#include "../CArtHandler.h"
#include "../CHeroHandler.h"
#include "../spells/CSpellHandler.h"
#include "../CTownHandler.h"
#include "../serializer/BinaryDeserializer.h"
#include "../serializer/BinarySerializer.h"
#include "../serializer/CTypeList.h"
VCMI_LIB_NAMESPACE_BEGIN
template void registerTypesClientPacks2<BinaryDeserializer>(BinaryDeserializer & s);
template void registerTypesClientPacks2<BinarySerializer>(BinarySerializer & s);
template void registerTypesClientPacks2<CTypeList>(CTypeList & s);
VCMI_LIB_NAMESPACE_END

View File

@ -1,43 +0,0 @@
/*
* TypesLobbyPacks.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "RegisterTypes.h"
#include "../mapping/CMapInfo.h"
#include "../StartInfo.h"
#include "../gameState/CGameState.h"
#include "../gameState/CGameStateCampaign.h"
#include "../gameState/TavernHeroesPool.h"
#include "../mapping/CMap.h"
#include "../mapObjects/CObjectHandler.h"
#include "../CCreatureHandler.h"
#include "../VCMI_Lib.h"
#include "../CArtHandler.h"
#include "../CHeroHandler.h"
#include "../spells/CSpellHandler.h"
#include "../CTownHandler.h"
#include "../RoadHandler.h"
#include "../RiverHandler.h"
#include "../TerrainHandler.h"
#include "../campaign/CampaignState.h"
#include "../rmg/CMapGenOptions.h"
#include "../serializer/BinaryDeserializer.h"
#include "../serializer/BinarySerializer.h"
#include "../serializer/CTypeList.h"
VCMI_LIB_NAMESPACE_BEGIN
template void registerTypesLobbyPacks<BinaryDeserializer>(BinaryDeserializer & s);
template void registerTypesLobbyPacks<BinarySerializer>(BinarySerializer & s);
template void registerTypesLobbyPacks<CTypeList>(CTypeList & s);
VCMI_LIB_NAMESPACE_END

View File

@ -1,34 +0,0 @@
/*
* TypesMapObjects1.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "RegisterTypes.h"
#include "../StartInfo.h"
#include "../mapObjects/CObjectHandler.h"
#include "../CCreatureHandler.h"
#include "../VCMI_Lib.h"
#include "../CArtHandler.h"
#include "../CHeroHandler.h"
#include "../spells/CSpellHandler.h"
#include "../CTownHandler.h"
#include "../serializer/BinaryDeserializer.h"
#include "../serializer/BinarySerializer.h"
#include "../serializer/CTypeList.h"
VCMI_LIB_NAMESPACE_BEGIN
template void registerTypesMapObjects1<BinaryDeserializer>(BinaryDeserializer & s);
template void registerTypesMapObjects1<BinarySerializer>(BinarySerializer & s);
template void registerTypesMapObjects1<CTypeList>(CTypeList & s);
VCMI_LIB_NAMESPACE_END

View File

@ -1,36 +0,0 @@
/*
* TypesMapObjects2.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "RegisterTypes.h"
#include "../StartInfo.h"
#include "../CStack.h"
#include "../battle/BattleInfo.h"
#include "../mapObjects/CObjectHandler.h"
#include "../CCreatureHandler.h"
#include "../VCMI_Lib.h"
#include "../CArtHandler.h"
#include "../CHeroHandler.h"
#include "../spells/CSpellHandler.h"
#include "../CTownHandler.h"
#include "../serializer/BinaryDeserializer.h"
#include "../serializer/BinarySerializer.h"
#include "../serializer/CTypeList.h"
VCMI_LIB_NAMESPACE_BEGIN
template void registerTypesMapObjects2<BinaryDeserializer>(BinaryDeserializer & s);
template void registerTypesMapObjects2<BinarySerializer>(BinarySerializer & s);
template void registerTypesMapObjects2<CTypeList>(CTypeList & s);
VCMI_LIB_NAMESPACE_END

View File

@ -1,32 +0,0 @@
/*
* TypesMapObjects3.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "RegisterTypes.h"
#include "../StartInfo.h"
#include "../mapObjects/CObjectHandler.h"
#include "../CCreatureHandler.h"
#include "../VCMI_Lib.h"
#include "../CArtHandler.h"
#include "../CHeroHandler.h"
#include "../spells/CSpellHandler.h"
#include "../CTownHandler.h"
#include "../serializer/BinaryDeserializer.h"
#include "../serializer/BinarySerializer.h"
#include "../serializer/CTypeList.h"
VCMI_LIB_NAMESPACE_BEGIN
template void registerTypesMapObjectTypes<BinaryDeserializer>(BinaryDeserializer & s);
template void registerTypesMapObjectTypes<BinarySerializer>(BinarySerializer & s);
template void registerTypesMapObjectTypes<CTypeList>(CTypeList & s);
VCMI_LIB_NAMESPACE_END

View File

@ -1,32 +0,0 @@
/*
* TypesServerPacks.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "RegisterTypes.h"
#include "../StartInfo.h"
#include "../mapObjects/CObjectHandler.h"
#include "../CCreatureHandler.h"
#include "../VCMI_Lib.h"
#include "../CArtHandler.h"
#include "../CHeroHandler.h"
#include "../spells/CSpellHandler.h"
#include "../CTownHandler.h"
#include "../serializer/BinaryDeserializer.h"
#include "../serializer/BinarySerializer.h"
#include "../serializer/CTypeList.h"
VCMI_LIB_NAMESPACE_BEGIN
template void registerTypesServerPacks<BinaryDeserializer>(BinaryDeserializer & s);
template void registerTypesServerPacks<BinarySerializer>(BinarySerializer & s);
template void registerTypesServerPacks<CTypeList>(CTypeList & s);
VCMI_LIB_NAMESPACE_END

View File

@ -9,97 +9,18 @@
*/
#include "StdInc.h"
#include "BinaryDeserializer.h"
#include "../registerTypes/RegisterTypes.h"
VCMI_LIB_NAMESPACE_BEGIN
extern template void registerTypes<BinaryDeserializer>(BinaryDeserializer & s);
CLoadFile::CLoadFile(const boost::filesystem::path & fname, int minimalVersion)
: serializer(this)
BinaryDeserializer::BinaryDeserializer(IBinaryReader * r): CLoaderBase(r)
{
registerTypes(serializer);
openNextFile(fname, minimalVersion);
}
saving = false;
fileVersion = 0;
smartPointerSerialization = true;
reverseEndianess = false;
//must be instantiated in .cpp file for access to complete types of all member fields
CLoadFile::~CLoadFile() = default;
int CLoadFile::read(void * data, unsigned size)
{
sfile->read(reinterpret_cast<char *>(data), size);
return size;
}
void CLoadFile::openNextFile(const boost::filesystem::path & fname, int minimalVersion)
{
assert(!serializer.reverseEndianess);
assert(minimalVersion <= SERIALIZATION_VERSION);
try
{
fName = fname.string();
sfile = std::make_unique<std::fstream>(fname.c_str(), std::ios::in | std::ios::binary);
sfile->exceptions(std::ifstream::failbit | std::ifstream::badbit); //we throw a lot anyway
if(!(*sfile))
THROW_FORMAT("Error: cannot open to read %s!", fName);
//we can read
char buffer[4];
sfile->read(buffer, 4);
if(std::memcmp(buffer, "VCMI", 4) != 0)
THROW_FORMAT("Error: not a VCMI file(%s)!", fName);
serializer & serializer.fileVersion;
if(serializer.fileVersion < minimalVersion)
THROW_FORMAT("Error: too old file format (%s)!", fName);
if(serializer.fileVersion > SERIALIZATION_VERSION)
{
logGlobal->warn("Warning format version mismatch: found %d when current is %d! (file %s)\n", serializer.fileVersion, SERIALIZATION_VERSION , fName);
auto * versionptr = reinterpret_cast<char *>(&serializer.fileVersion);
std::reverse(versionptr, versionptr + 4);
logGlobal->warn("Version number reversed is %x, checking...", serializer.fileVersion);
if(serializer.fileVersion == SERIALIZATION_VERSION)
{
logGlobal->warn("%s seems to have different endianness! Entering reversing mode.", fname.string());
serializer.reverseEndianess = true;
}
else
THROW_FORMAT("Error: too new file format (%s)!", fName);
}
}
catch(...)
{
clear(); //if anything went wrong, we delete file and rethrow
throw;
}
}
void CLoadFile::reportState(vstd::CLoggerBase * out)
{
out->debug("CLoadFile");
if(!!sfile && *sfile)
out->debug("\tOpened %s Position: %d", fName, sfile->tellg());
}
void CLoadFile::clear()
{
sfile = nullptr;
fName.clear();
serializer.fileVersion = 0;
}
void CLoadFile::checkMagicBytes(const std::string &text)
{
std::string loaded = text;
read((void *)loaded.data(), static_cast<unsigned int>(text.length()));
if(loaded != text)
throw std::runtime_error("Magic bytes doesn't match!");
registerTypes(*this);
}
VCMI_LIB_NAMESPACE_END

View File

@ -9,17 +9,12 @@
*/
#pragma once
#include <boost/mpl/vector.hpp>
#include <boost/mpl/for_each.hpp>
#include "CSerializer.h"
#include "CTypeList.h"
#include "../mapObjects/CGHeroInstance.h"
#include "../../Global.h"
VCMI_LIB_NAMESPACE_BEGIN
class CStackInstance;
class DLL_LINKAGE CLoaderBase
{
protected:
@ -37,41 +32,6 @@ public:
/// Effectively revesed version of BinarySerializer
class DLL_LINKAGE BinaryDeserializer : public CLoaderBase
{
template<typename Variant, typename Source>
struct VariantLoaderHelper
{
Source & source;
std::vector<std::function<Variant()>> funcs;
template <class V>
struct mpl_types_impl;
template <class... Ts>
struct mpl_types_impl<std::variant<Ts...>> {
using type = boost::mpl::vector<Ts...>;
};
template <class V>
using mpl_types = typename mpl_types_impl<V>::type;
VariantLoaderHelper(Source & source):
source(source)
{
boost::mpl::for_each<mpl_types<Variant>>(std::ref(*this));
}
template<typename Type>
void operator()(Type)
{
funcs.push_back([&]() -> Variant
{
Type obj;
source.load(obj);
return Variant(obj);
});
}
};
template<typename Ser,typename T>
struct LoadIfStackInstance
{
@ -138,40 +98,40 @@ class DLL_LINKAGE BinaryDeserializer : public CLoaderBase
return length;
}
template <typename T> class CPointerLoader;
template <typename Type> class CPointerLoader;
class CBasicPointerLoader
class IPointerLoader
{
public:
virtual const std::type_info * loadPtr(CLoaderBase &ar, void *data, ui32 pid) const =0; //data is pointer to the ACTUAL POINTER
virtual ~CBasicPointerLoader(){}
virtual void * loadPtr(CLoaderBase &ar, ui32 pid) const =0; //data is pointer to the ACTUAL POINTER
virtual ~IPointerLoader() = default;
template<typename T> static CBasicPointerLoader *getApplier(const T * t=nullptr)
template<typename Type> static IPointerLoader *getApplier(const Type * t = nullptr)
{
return new CPointerLoader<T>();
return new CPointerLoader<Type>();
}
};
template <typename T> class CPointerLoader : public CBasicPointerLoader
template <typename Type>
class CPointerLoader : public IPointerLoader
{
public:
const std::type_info * loadPtr(CLoaderBase &ar, void *data, ui32 pid) const override //data is pointer to the ACTUAL POINTER
void * loadPtr(CLoaderBase &ar, ui32 pid) const override //data is pointer to the ACTUAL POINTER
{
auto & s = static_cast<BinaryDeserializer &>(ar);
T *&ptr = *static_cast<T**>(data);
//create new object under pointer
typedef typename std::remove_pointer<T>::type npT;
ptr = ClassObjectCreator<npT>::invoke(); //does new npT or throws for abstract classes
Type * ptr = ClassObjectCreator<Type>::invoke(); //does new npT or throws for abstract classes
s.ptrAllocated(ptr, pid);
//T is most derived known type, it's time to call actual serialize
assert(s.fileVersion != 0);
ptr->serialize(s,s.fileVersion);
return &typeid(T);
return static_cast<void*>(ptr);
}
};
CApplier<CBasicPointerLoader> applier;
CApplier<IPointerLoader> applier;
int write(const void * data, unsigned size);
@ -181,17 +141,11 @@ public:
std::map<ui32, void*> loadedPointers;
std::map<ui32, const std::type_info*> loadedPointersTypes;
std::map<const void*, std::any> loadedSharedPointers;
std::map<const void*, std::shared_ptr<void>> loadedSharedPointers;
bool smartPointerSerialization;
bool saving;
BinaryDeserializer(IBinaryReader * r): CLoaderBase(r)
{
saving = false;
fileVersion = 0;
smartPointerSerialization = true;
reverseEndianess = false;
}
BinaryDeserializer(IBinaryReader * r);
template<class T>
BinaryDeserializer & operator&(T & t)
@ -264,14 +218,33 @@ public:
template < typename T, typename std::enable_if < std::is_pointer<T>::value, int >::type = 0 >
void load(T &data)
{
ui8 hlp;
load( hlp );
if(!hlp)
bool isNull;
load( isNull );
if(isNull)
{
data = nullptr;
return;
}
loadPointerImpl(data);
}
template < typename T, typename std::enable_if < std::is_base_of_v<Entity, std::remove_pointer_t<T>>, int >::type = 0 >
void loadPointerImpl(T &data)
{
using DataType = std::remove_pointer_t<T>;
typename DataType::IdentifierType index;
load(index);
auto * constEntity = index.toEntity(VLC);
auto * constData = dynamic_cast<const DataType *>(constEntity);
data = const_cast<DataType *>(constData);
}
template < typename T, typename std::enable_if < !std::is_base_of_v<Entity, std::remove_pointer_t<T>>, int >::type = 0 >
void loadPointerImpl(T &data)
{
if(reader->smartVectorMembersSerialization)
{
typedef typename std::remove_const<typename std::remove_pointer<T>::type>::type TObjectType; //eg: const CGHeroInstance * => CGHeroInstance
@ -307,11 +280,10 @@ public:
// We already got this pointer
// Cast it in case we are loading it to a non-first base pointer
assert(loadedPointersTypes.count(pid));
data = reinterpret_cast<T>(typeList.castRaw(i->second, loadedPointersTypes.at(pid), &typeid(typename std::remove_const<typename std::remove_pointer<T>::type>::type)));
data = static_cast<T>(i->second);
return;
}
}
//get type id
ui16 tid;
load( tid );
@ -333,8 +305,7 @@ public:
data = nullptr;
return;
}
auto typeInfo = app->loadPtr(*this,&data, pid);
data = reinterpret_cast<T>(typeList.castRaw((void*)data, typeInfo, &typeid(typename std::remove_const<typename std::remove_pointer<T>::type>::type)));
data = static_cast<T>(app->loadPtr(*this, pid));
}
}
@ -360,7 +331,7 @@ public:
NonConstT *internalPtr;
load(internalPtr);
void *internalPtrDerived = typeList.castToMostDerived(internalPtr);
void * internalPtrDerived = static_cast<void*>(internalPtr);
if(internalPtr)
{
@ -369,35 +340,13 @@ public:
{
// This pointers is already loaded. The "data" needs to be pointed to it,
// so their shared state is actually shared.
try
{
auto actualType = typeList.getTypeInfo(internalPtr);
auto typeWeNeedToReturn = typeList.getTypeInfo<T>();
if(*actualType == *typeWeNeedToReturn)
{
// No casting needed, just unpack already stored shared_ptr and return it
data = std::any_cast<std::shared_ptr<T>>(itr->second);
}
else
{
// We need to perform series of casts
auto ret = typeList.castShared(itr->second, actualType, typeWeNeedToReturn);
data = std::any_cast<std::shared_ptr<T>>(ret);
}
}
catch(std::exception &e)
{
logGlobal->error(e.what());
logGlobal->error("Failed to cast stored shared ptr. Real type: %s. Needed type %s. FIXME FIXME FIXME", itr->second.type().name(), typeid(std::shared_ptr<T>).name());
//TODO scenario with inheritance -> we can have stored ptr to base and load ptr to derived (or vice versa)
throw;
}
data = std::static_pointer_cast<T>(itr->second);
}
else
{
auto hlp = std::shared_ptr<NonConstT>(internalPtr);
data = hlp;
loadedSharedPointers[internalPtrDerived] = typeList.castSharedToMostDerived(hlp);
loadedSharedPointers[internalPtrDerived] = std::static_pointer_cast<void>(hlp);
}
}
else
@ -510,17 +459,19 @@ public:
this->read((void*)data.c_str(),length);
}
template<typename T0, typename... TN>
void load(std::variant<T0, TN...> & data)
template<typename... TN>
void load(std::variant<TN...> & data)
{
using TVariant = std::variant<T0, TN...>;
VariantLoaderHelper<TVariant, BinaryDeserializer> loader(*this);
si32 which;
load( which );
assert(which < loader.funcs.size());
data = loader.funcs.at(which)();
assert(which < sizeof...(TN));
// Create array of variants that contains all default-constructed alternatives
const std::variant<TN...> table[] = { TN{ }... };
// use appropriate alternative for result
data = table[which];
// perform actual load via std::visit dispatch
std::visit([&](auto& o) { load(o); }, data);
}
template<typename T>
@ -579,30 +530,4 @@ public:
}
};
class DLL_LINKAGE CLoadFile : public IBinaryReader
{
public:
BinaryDeserializer serializer;
std::string fName;
std::unique_ptr<std::fstream> sfile;
CLoadFile(const boost::filesystem::path & fname, int minimalVersion = SERIALIZATION_VERSION); //throws!
virtual ~CLoadFile();
int read(void * data, unsigned size) override; //throws!
void openNextFile(const boost::filesystem::path & fname, int minimalVersion); //throws!
void clear();
void reportState(vstd::CLoggerBase * out) override;
void checkMagicBytes(const std::string & text);
template<class T>
CLoadFile & operator>>(T &t)
{
serializer & t;
return * this;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -9,69 +9,15 @@
*/
#include "StdInc.h"
#include "BinarySerializer.h"
#include "../registerTypes/RegisterTypes.h"
VCMI_LIB_NAMESPACE_BEGIN
extern template void registerTypes<BinarySerializer>(BinarySerializer & s);
CSaveFile::CSaveFile(const boost::filesystem::path &fname)
: serializer(this)
BinarySerializer::BinarySerializer(IBinaryWriter * w): CSaverBase(w)
{
registerTypes(serializer);
openNextFile(fname);
}
//must be instantiated in .cpp file for access to complete types of all member fields
CSaveFile::~CSaveFile() = default;
int CSaveFile::write(const void * data, unsigned size)
{
sfile->write((char *)data,size);
return size;
}
void CSaveFile::openNextFile(const boost::filesystem::path &fname)
{
fName = fname;
try
{
sfile = std::make_unique<std::fstream>(fname.c_str(), std::ios::out | std::ios::binary);
sfile->exceptions(std::ifstream::failbit | std::ifstream::badbit); //we throw a lot anyway
if(!(*sfile))
THROW_FORMAT("Error: cannot open to write %s!", fname);
sfile->write("VCMI",4); //write magic identifier
serializer & SERIALIZATION_VERSION; //write format version
}
catch(...)
{
logGlobal->error("Failed to save to %s", fname.string());
clear();
throw;
}
}
void CSaveFile::reportState(vstd::CLoggerBase * out)
{
out->debug("CSaveFile");
if(sfile.get() && *sfile)
{
out->debug("\tOpened %s \tPosition: %d", fName, sfile->tellp());
}
}
void CSaveFile::clear()
{
fName.clear();
sfile = nullptr;
}
void CSaveFile::putMagicBytes(const std::string &text)
{
write(text.c_str(), static_cast<unsigned int>(text.length()));
saving=true;
smartPointerSerialization = true;
registerTypes(*this);
}
VCMI_LIB_NAMESPACE_END

View File

@ -9,6 +9,7 @@
*/
#pragma once
#include "CSerializer.h"
#include "CTypeList.h"
#include "../mapObjects/CArmedInstance.h"
@ -114,11 +115,7 @@ public:
bool smartPointerSerialization;
bool saving;
BinarySerializer(IBinaryWriter * w): CSaverBase(w)
{
saving=true;
smartPointerSerialization = true;
}
BinarySerializer(IBinaryWriter * w);
template<typename Base, typename Derived>
void registerType(const Base * b = nullptr, const Derived * d = nullptr)
@ -174,16 +171,30 @@ public:
void save(const T &data)
{
//write if pointer is not nullptr
ui8 hlp = (data!=nullptr);
save(hlp);
bool isNull = (data == nullptr);
save(isNull);
//if pointer is nullptr then we don't need anything more...
if(!hlp)
if(data == nullptr)
return;
savePointerImpl(data);
}
template < typename T, typename std::enable_if < std::is_base_of_v<Entity, std::remove_pointer_t<T>>, int >::type = 0 >
void savePointerImpl(const T &data)
{
auto index = data->getId();
save(index);
}
template < typename T, typename std::enable_if < !std::is_base_of_v<Entity, std::remove_pointer_t<T>>, int >::type = 0 >
void savePointerImpl(const T &data)
{
typedef typename std::remove_const<typename std::remove_pointer<T>::type>::type TObjectType;
if(writer->smartVectorMembersSerialization)
{
typedef typename std::remove_const<typename std::remove_pointer<T>::type>::type TObjectType;
typedef typename VectorizedTypeFor<TObjectType>::type VType;
typedef typename VectorizedIDType<TObjectType>::type IDType;
@ -207,7 +218,7 @@ public:
{
// We might have an object that has multiple inheritance and store it via the non-first base pointer.
// Therefore, all pointers need to be normalized to the actual object address.
auto actualPointer = typeList.castToMostDerived(data);
const void * actualPointer = static_cast<const void*>(data);
auto i = savedPointers.find(actualPointer);
if(i != savedPointers.end())
{
@ -223,13 +234,13 @@ public:
}
//write type identifier
ui16 tid = typeList.getTypeID(data);
uint16_t tid = CTypeList::getInstance().getTypeID(data);
save(tid);
if(!tid)
save(*data); //if type is unregistered simply write all data in a standard way
else
applier.getApplier(tid)->savePtr(*this, typeList.castToMostDerived(data)); //call serializer specific for our real type
applier.getApplier(tid)->savePtr(*this, static_cast<const void*>(data)); //call serializer specific for our real type
}
template < typename T, typename std::enable_if < is_serializeable<BinarySerializer, T>::value, int >::type = 0 >
@ -389,30 +400,4 @@ public:
}
};
class DLL_LINKAGE CSaveFile : public IBinaryWriter
{
public:
BinarySerializer serializer;
boost::filesystem::path fName;
std::unique_ptr<std::fstream> sfile;
CSaveFile(const boost::filesystem::path &fname); //throws!
~CSaveFile();
int write(const void * data, unsigned size) override;
void openNextFile(const boost::filesystem::path &fname); //throws!
void clear();
void reportState(vstd::CLoggerBase * out) override;
void putMagicBytes(const std::string &text);
template<class T>
CSaveFile & operator<<(const T &t)
{
serializer & t;
return * this;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,100 @@
/*
* CLoadFile.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "CLoadFile.h"
VCMI_LIB_NAMESPACE_BEGIN
CLoadFile::CLoadFile(const boost::filesystem::path & fname, int minimalVersion)
: serializer(this)
{
openNextFile(fname, minimalVersion);
}
//must be instantiated in .cpp file for access to complete types of all member fields
CLoadFile::~CLoadFile() = default;
int CLoadFile::read(void * data, unsigned size)
{
sfile->read(reinterpret_cast<char *>(data), size);
return size;
}
void CLoadFile::openNextFile(const boost::filesystem::path & fname, int minimalVersion)
{
assert(!serializer.reverseEndianess);
assert(minimalVersion <= SERIALIZATION_VERSION);
try
{
fName = fname.string();
sfile = std::make_unique<std::fstream>(fname.c_str(), std::ios::in | std::ios::binary);
sfile->exceptions(std::ifstream::failbit | std::ifstream::badbit); //we throw a lot anyway
if(!(*sfile))
THROW_FORMAT("Error: cannot open to read %s!", fName);
//we can read
char buffer[4];
sfile->read(buffer, 4);
if(std::memcmp(buffer, "VCMI", 4) != 0)
THROW_FORMAT("Error: not a VCMI file(%s)!", fName);
serializer & serializer.fileVersion;
if(serializer.fileVersion < minimalVersion)
THROW_FORMAT("Error: too old file format (%s)!", fName);
if(serializer.fileVersion > SERIALIZATION_VERSION)
{
logGlobal->warn("Warning format version mismatch: found %d when current is %d! (file %s)\n", serializer.fileVersion, SERIALIZATION_VERSION , fName);
auto * versionptr = reinterpret_cast<char *>(&serializer.fileVersion);
std::reverse(versionptr, versionptr + 4);
logGlobal->warn("Version number reversed is %x, checking...", serializer.fileVersion);
if(serializer.fileVersion == SERIALIZATION_VERSION)
{
logGlobal->warn("%s seems to have different endianness! Entering reversing mode.", fname.string());
serializer.reverseEndianess = true;
}
else
THROW_FORMAT("Error: too new file format (%s)!", fName);
}
}
catch(...)
{
clear(); //if anything went wrong, we delete file and rethrow
throw;
}
}
void CLoadFile::reportState(vstd::CLoggerBase * out)
{
out->debug("CLoadFile");
if(!!sfile && *sfile)
out->debug("\tOpened %s Position: %d", fName, sfile->tellg());
}
void CLoadFile::clear()
{
sfile = nullptr;
fName.clear();
serializer.fileVersion = 0;
}
void CLoadFile::checkMagicBytes(const std::string &text)
{
std::string loaded = text;
read((void *)loaded.data(), static_cast<unsigned int>(text.length()));
if(loaded != text)
throw std::runtime_error("Magic bytes doesn't match!");
}
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,42 @@
/*
* CLoadFile.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include "BinaryDeserializer.h"
VCMI_LIB_NAMESPACE_BEGIN
class DLL_LINKAGE CLoadFile : public IBinaryReader
{
public:
BinaryDeserializer serializer;
std::string fName;
std::unique_ptr<std::fstream> sfile;
CLoadFile(const boost::filesystem::path & fname, int minimalVersion = SERIALIZATION_VERSION); //throws!
virtual ~CLoadFile();
int read(void * data, unsigned size) override; //throws!
void openNextFile(const boost::filesystem::path & fname, int minimalVersion); //throws!
void clear();
void reportState(vstd::CLoggerBase * out) override;
void checkMagicBytes(const std::string & text);
template<class T>
CLoadFile & operator>>(T &t)
{
serializer & t;
return * this;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -1,68 +0,0 @@
/*
* CLoadIntegrityValidator.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "CLoadIntegrityValidator.h"
#include "../registerTypes/RegisterTypes.h"
VCMI_LIB_NAMESPACE_BEGIN
CLoadIntegrityValidator::CLoadIntegrityValidator(const boost::filesystem::path &primaryFileName, const boost::filesystem::path &controlFileName, int minimalVersion)
: serializer(this), foundDesync(false)
{
registerTypes(serializer);
primaryFile = std::make_unique<CLoadFile>(primaryFileName, minimalVersion);
controlFile = std::make_unique<CLoadFile>(controlFileName, minimalVersion);
assert(primaryFile->serializer.fileVersion == controlFile->serializer.fileVersion);
serializer.fileVersion = primaryFile->serializer.fileVersion;
}
int CLoadIntegrityValidator::read( void * data, unsigned size )
{
assert(primaryFile);
assert(controlFile);
if(!size)
return size;
std::vector<ui8> controlData(size);
auto ret = primaryFile->read(data, size);
if(!foundDesync)
{
controlFile->read(controlData.data(), size);
if(std::memcmp(data, controlData.data(), size) != 0)
{
logGlobal->error("Desync found! Position: %d", primaryFile->sfile->tellg());
foundDesync = true;
//throw std::runtime_error("Savegame dsynchronized!");
}
}
return ret;
}
std::unique_ptr<CLoadFile> CLoadIntegrityValidator::decay()
{
primaryFile->serializer.loadedPointers = this->serializer.loadedPointers;
primaryFile->serializer.loadedPointersTypes = this->serializer.loadedPointersTypes;
return std::move(primaryFile);
}
void CLoadIntegrityValidator::checkMagicBytes(const std::string & text) const
{
assert(primaryFile);
assert(controlFile);
primaryFile->checkMagicBytes(text);
controlFile->checkMagicBytes(text);
}
VCMI_LIB_NAMESPACE_END

View File

@ -1,33 +0,0 @@
/*
* CLoadIntegrityValidator.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include "BinaryDeserializer.h"
VCMI_LIB_NAMESPACE_BEGIN
/// Simple byte-to-byte saves comparator
class DLL_LINKAGE CLoadIntegrityValidator
: public IBinaryReader
{
public:
BinaryDeserializer serializer;
std::unique_ptr<CLoadFile> primaryFile, controlFile;
bool foundDesync;
CLoadIntegrityValidator(const boost::filesystem::path &primaryFileName, const boost::filesystem::path &controlFileName, int minimalVersion = SERIALIZATION_VERSION); //throws!
int read( void * data, unsigned size) override; //throws!
void checkMagicBytes(const std::string & text) const;
std::unique_ptr<CLoadFile> decay(); //returns primary file. CLoadIntegrityValidator stops being usable anymore
};
VCMI_LIB_NAMESPACE_END

View File

@ -10,8 +10,6 @@
#include "StdInc.h"
#include "CMemorySerializer.h"
#include "../registerTypes/RegisterTypes.h"
VCMI_LIB_NAMESPACE_BEGIN
int CMemorySerializer::read(void * data, unsigned size)
@ -34,8 +32,6 @@ int CMemorySerializer::write(const void * data, unsigned size)
CMemorySerializer::CMemorySerializer(): iser(this), oser(this), readPos(0)
{
registerTypes(iser);
registerTypes(oser);
iser.fileVersion = SERIALIZATION_VERSION;
}

View File

@ -0,0 +1,72 @@
/*
* CSaveFile.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "CSaveFile.h"
VCMI_LIB_NAMESPACE_BEGIN
CSaveFile::CSaveFile(const boost::filesystem::path &fname)
: serializer(this)
{
openNextFile(fname);
}
//must be instantiated in .cpp file for access to complete types of all member fields
CSaveFile::~CSaveFile() = default;
int CSaveFile::write(const void * data, unsigned size)
{
sfile->write((char *)data,size);
return size;
}
void CSaveFile::openNextFile(const boost::filesystem::path &fname)
{
fName = fname;
try
{
sfile = std::make_unique<std::fstream>(fname.c_str(), std::ios::out | std::ios::binary);
sfile->exceptions(std::ifstream::failbit | std::ifstream::badbit); //we throw a lot anyway
if(!(*sfile))
THROW_FORMAT("Error: cannot open to write %s!", fname);
sfile->write("VCMI",4); //write magic identifier
serializer & SERIALIZATION_VERSION; //write format version
}
catch(...)
{
logGlobal->error("Failed to save to %s", fname.string());
clear();
throw;
}
}
void CSaveFile::reportState(vstd::CLoggerBase * out)
{
out->debug("CSaveFile");
if(sfile.get() && *sfile)
{
out->debug("\tOpened %s \tPosition: %d", fName, sfile->tellp());
}
}
void CSaveFile::clear()
{
fName.clear();
sfile = nullptr;
}
void CSaveFile::putMagicBytes(const std::string &text)
{
write(text.c_str(), static_cast<unsigned int>(text.length()));
}
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,42 @@
/*
* CSaveFile.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include "BinarySerializer.h"
VCMI_LIB_NAMESPACE_BEGIN
class DLL_LINKAGE CSaveFile : public IBinaryWriter
{
public:
BinarySerializer serializer;
boost::filesystem::path fName;
std::unique_ptr<std::fstream> sfile;
CSaveFile(const boost::filesystem::path &fname); //throws!
~CSaveFile();
int write(const void * data, unsigned size) override;
void openNextFile(const boost::filesystem::path &fname); //throws!
void clear();
void reportState(vstd::CLoggerBase * out) override;
void putMagicBytes(const std::string &text);
template<class T>
CSaveFile & operator<<(const T &t)
{
serializer & t;
return * this;
}
};
VCMI_LIB_NAMESPACE_END

View File

@ -14,8 +14,8 @@
VCMI_LIB_NAMESPACE_BEGIN
const ui32 SERIALIZATION_VERSION = 828;
const ui32 MINIMAL_SERIALIZATION_VERSION = 828;
const ui32 SERIALIZATION_VERSION = 830;
const ui32 MINIMAL_SERIALIZATION_VERSION = 830;
const std::string SAVEGAME_MAGIC = "VCMISVG";
class CHero;
@ -149,42 +149,31 @@ struct is_serializeable
template <typename T> //metafunction returning CGObjectInstance if T is its derivate or T elsewise
struct VectorizedTypeFor
{
using type = typename
//if
boost::mpl::eval_if<std::is_same<CGHeroInstance, T>,
boost::mpl::identity<CGHeroInstance>,
//else if
boost::mpl::eval_if<std::is_base_of<CGObjectInstance, T>,
boost::mpl::identity<CGObjectInstance>,
//else
boost::mpl::identity<T>
>>::type;
using type = std::conditional_t<std::is_base_of_v<CGObjectInstance, T>, CGObjectInstance, T>;
};
template <typename U>
template <>
struct VectorizedTypeFor<CGHeroInstance>
{
using type = CGHeroInstance;
};
template <typename T>
struct VectorizedIDType
{
using type = typename
//if
boost::mpl::eval_if<std::is_same<CArtifact, U>,
boost::mpl::identity<ArtifactID>,
//else if
boost::mpl::eval_if<std::is_same<CCreature, U>,
boost::mpl::identity<CreatureID>,
//else if
boost::mpl::eval_if<std::is_same<CHero, U>,
boost::mpl::identity<HeroTypeID>,
//else if
boost::mpl::eval_if<std::is_same<CArtifactInstance, U>,
boost::mpl::identity<ArtifactInstanceID>,
//else if
boost::mpl::eval_if<std::is_same<CGHeroInstance, U>,
boost::mpl::identity<HeroTypeID>,
//else if
boost::mpl::eval_if<std::is_base_of<CGObjectInstance, U>,
boost::mpl::identity<ObjectInstanceID>,
//else
boost::mpl::identity<si32>
>>>>>>::type;
using type = std::conditional_t<std::is_base_of_v<CGObjectInstance, T>, ObjectInstanceID, int32_t>;
};
template <>
struct VectorizedIDType<CArtifactInstance>
{
using type = ArtifactInstanceID;
};
template <>
struct VectorizedIDType<CGHeroInstance>
{
using type = HeroTypeID;
};
/// Base class for deserializers

View File

@ -14,128 +14,9 @@
VCMI_LIB_NAMESPACE_BEGIN
extern template void registerTypes<CTypeList>(CTypeList & s);
CTypeList typeList;
CTypeList::CTypeList()
{
registerTypes(*this);
}
CTypeList::TypeInfoPtr CTypeList::registerType(const std::type_info *type)
{
if(auto typeDescr = getTypeDescriptor(type, false))
return typeDescr; //type found, return ptr to structure
//type not found - add it to the list and return given ID
auto newType = std::make_shared<TypeDescriptor>();
newType->typeID = static_cast<ui16>(typeInfos.size() + 1);
newType->name = type->name();
typeInfos[type] = newType;
return newType;
}
ui16 CTypeList::getTypeID(const std::type_info *type, bool throws) const
{
auto descriptor = getTypeDescriptor(type, throws);
if (descriptor == nullptr)
{
return 0;
}
return descriptor->typeID;
}
CTypeList::TypeInfoPtr CTypeList::getTypeDescriptor(ui16 typeID) const
{
auto found = std::find_if(typeInfos.begin(), typeInfos.end(), [typeID](const std::pair<const std::type_info *, TypeInfoPtr> & p) -> bool
{
return p.second->typeID == typeID;
});
if(found != typeInfos.end())
{
return found->second;
}
return TypeInfoPtr();
}
std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(TypeInfoPtr from, TypeInfoPtr to) const
{
if(!strcmp(from->name, to->name))
return std::vector<CTypeList::TypeInfoPtr>();
// Perform a simple BFS in the class hierarchy.
auto BFS = [&](bool upcast)
{
std::map<TypeInfoPtr, TypeInfoPtr> previous;
std::queue<TypeInfoPtr> q;
q.push(to);
while(!q.empty())
{
auto typeNode = q.front();
q.pop();
for(auto & weakNode : (upcast ? typeNode->parents : typeNode->children) )
{
auto nodeBase = weakNode.lock();
if(!previous.count(nodeBase))
{
previous[nodeBase] = typeNode;
q.push(nodeBase);
}
}
}
std::vector<TypeInfoPtr> ret;
if(!previous.count(from))
return ret;
ret.push_back(from);
TypeInfoPtr ptr = from;
do
{
ptr = previous.at(ptr);
ret.push_back(ptr);
} while(ptr != to);
return ret;
};
// Try looking both up and down.
auto ret = BFS(true);
if(ret.empty())
ret = BFS(false);
if(ret.empty())
THROW_FORMAT("Cannot find relation between types %s and %s. Were they (and all classes between them) properly registered?", from->name % to->name);
return ret;
}
std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(const std::type_info *from, const std::type_info *to) const
{
//This additional if is needed because getTypeDescriptor might fail if type is not registered
// (and if casting is not needed, then registereing should no be required)
if(!strcmp(from->name(), to->name()))
return std::vector<CTypeList::TypeInfoPtr>();
return castSequence(getTypeDescriptor(from), getTypeDescriptor(to));
}
CTypeList::TypeInfoPtr CTypeList::getTypeDescriptor(const std::type_info *type, bool throws) const
{
auto i = typeInfos.find(type);
if(i != typeInfos.end())
return i->second; //type found, return ptr to structure
if(!throws)
return nullptr;
THROW_FORMAT("Cannot find type descriptor for type %s. Was it registered?", type->name());
}
VCMI_LIB_NAMESPACE_END

View File

@ -9,199 +9,72 @@
*/
#pragma once
#include "CSerializer.h"
VCMI_LIB_NAMESPACE_BEGIN
struct IPointerCaster
{
virtual std::any castRawPtr(const std::any &ptr) const = 0; // takes From*, returns To*
virtual std::any castSharedPtr(const std::any &ptr) const = 0; // takes std::shared_ptr<From>, performs dynamic cast, returns std::shared_ptr<To>
virtual std::any castWeakPtr(const std::any &ptr) const = 0; // takes std::weak_ptr<From>, performs dynamic cast, returns std::weak_ptr<To>. The object under poitner must live.
//virtual std::any castUniquePtr(const std::any &ptr) const = 0; // takes std::unique_ptr<From>, performs dynamic cast, returns std::unique_ptr<To>
virtual ~IPointerCaster() = default;
};
template <typename From, typename To>
struct PointerCaster : IPointerCaster
{
virtual std::any castRawPtr(const std::any &ptr) const override // takes void* pointing to From object, performs dynamic cast, returns void* pointing to To object
{
From * from = (From*)std::any_cast<void*>(ptr);
To * ret = static_cast<To*>(from);
return (void*)ret;
}
// Helper function performing casts between smart pointers
template<typename SmartPt>
std::any castSmartPtr(const std::any &ptr) const
{
try
{
auto from = std::any_cast<SmartPt>(ptr);
auto ret = std::static_pointer_cast<To>(from);
return ret;
}
catch(std::exception &e)
{
THROW_FORMAT("Failed cast %s -> %s. Given argument was %s. Error message: %s", typeid(From).name() % typeid(To).name() % ptr.type().name() % e.what());
}
}
virtual std::any castSharedPtr(const std::any &ptr) const override
{
return castSmartPtr<std::shared_ptr<From>>(ptr);
}
virtual std::any castWeakPtr(const std::any &ptr) const override
{
auto from = std::any_cast<std::weak_ptr<From>>(ptr);
return castSmartPtr<std::shared_ptr<From>>(from.lock());
}
};
/// Class that implements basic reflection-like mechanisms
/// For every type registered via registerType() generates inheritance tree
/// Rarely used directly - usually used as part of CApplier
class DLL_LINKAGE CTypeList: public boost::noncopyable
class CTypeList
{
//public:
struct TypeDescriptor;
using TypeInfoPtr = std::shared_ptr<TypeDescriptor>;
using WeakTypeInfoPtr = std::weak_ptr<TypeDescriptor>;
struct TypeDescriptor
{
ui16 typeID;
const char *name;
std::vector<WeakTypeInfoPtr> children, parents;
};
using TMutex = boost::shared_mutex;
using TUniqueLock = boost::unique_lock<TMutex>;
using TSharedLock = boost::shared_lock<TMutex>;
std::map<std::string, uint16_t> typeInfos;
private:
mutable TMutex mx;
std::map<const std::type_info *, TypeInfoPtr, TypeComparer> typeInfos;
std::map<std::pair<TypeInfoPtr, TypeInfoPtr>, std::unique_ptr<const IPointerCaster>> casters; //for each pair <Base, Der> we provide a caster (each registered relations creates a single entry here)
/// Returns sequence of types starting from "from" and ending on "to". Every next type is derived from the previous.
/// Throws if there is no link registered.
std::vector<TypeInfoPtr> castSequence(TypeInfoPtr from, TypeInfoPtr to) const;
std::vector<TypeInfoPtr> castSequence(const std::type_info *from, const std::type_info *to) const;
template<std::any(IPointerCaster::*CastingFunction)(const std::any &) const>
std::any castHelper(std::any inputPtr, const std::type_info *fromArg, const std::type_info *toArg) const
{
TSharedLock lock(mx);
auto typesSequence = castSequence(fromArg, toArg);
std::any ptr = inputPtr;
for(int i = 0; i < static_cast<int>(typesSequence.size()) - 1; i++)
{
auto &from = typesSequence[i];
auto &to = typesSequence[i + 1];
auto castingPair = std::make_pair(from, to);
if(!casters.count(castingPair))
THROW_FORMAT("Cannot find caster for conversion %s -> %s which is needed to cast %s -> %s", from->name % to->name % fromArg->name() % toArg->name());
const auto & caster = casters.at(castingPair);
ptr = (*caster.*CastingFunction)(ptr); //Why does unique_ptr not have operator->* ..?
}
return ptr;
}
CTypeList & operator=(CTypeList &) = delete;
TypeInfoPtr getTypeDescriptor(const std::type_info *type, bool throws = true) const; //if not throws, failure returns nullptr
TypeInfoPtr registerType(const std::type_info *type);
public:
CTypeList();
template <typename Base, typename Derived>
void registerType(const Base * b = nullptr, const Derived * d = nullptr)
{
TUniqueLock lock(mx);
static_assert(std::is_base_of<Base, Derived>::value, "First registerType template parameter needs to ba a base class of the second one.");
static_assert(std::has_virtual_destructor<Base>::value, "Base class needs to have a virtual destructor.");
static_assert(!std::is_same<Base, Derived>::value, "Parameters of registerTypes should be two different types.");
auto bt = getTypeInfo(b);
auto dt = getTypeInfo(d); //obtain std::type_info
auto bti = registerType(bt);
auto dti = registerType(dt); //obtain our TypeDescriptor
// register the relation between classes
bti->children.push_back(dti);
dti->parents.push_back(bti);
casters[std::make_pair(bti, dti)] = std::make_unique<const PointerCaster<Base, Derived>>();
casters[std::make_pair(dti, bti)] = std::make_unique<const PointerCaster<Derived, Base>>();
}
ui16 getTypeID(const std::type_info *type, bool throws = false) const;
DLL_LINKAGE CTypeList();
template <typename T>
ui16 getTypeID(const T * t = nullptr, bool throws = false) const
{
return getTypeID(getTypeInfo(t), throws);
}
TypeInfoPtr getTypeDescriptor(ui16 typeID) const;
template<typename TInput>
void * castToMostDerived(const TInput * inputPtr) const
{
const auto & baseType = typeid(typename std::remove_cv<TInput>::type);
auto derivedType = getTypeInfo(inputPtr);
if (strcmp(baseType.name(), derivedType->name()) == 0)
{
return const_cast<void*>(reinterpret_cast<const void*>(inputPtr));
}
return std::any_cast<void*>(castHelper<&IPointerCaster::castRawPtr>(
const_cast<void*>(reinterpret_cast<const void*>(inputPtr)), &baseType,
derivedType));
}
template<typename TInput>
std::any castSharedToMostDerived(const std::shared_ptr<TInput> inputPtr) const
{
const auto & baseType = typeid(typename std::remove_cv<TInput>::type);
auto derivedType = getTypeInfo(inputPtr.get());
if (!strcmp(baseType.name(), derivedType->name()))
return inputPtr;
return castHelper<&IPointerCaster::castSharedPtr>(inputPtr, &baseType, derivedType);
}
void * castRaw(void *inputPtr, const std::type_info *from, const std::type_info *to) const
{
return std::any_cast<void*>(castHelper<&IPointerCaster::castRawPtr>(inputPtr, from, to));
}
std::any castShared(std::any inputPtr, const std::type_info *from, const std::type_info *to) const
{
return castHelper<&IPointerCaster::castSharedPtr>(inputPtr, from, to);
}
template <typename T> const std::type_info * getTypeInfo(const T * t = nullptr) const
const std::type_info & getTypeInfo(const T * t = nullptr) const
{
if(t)
return &typeid(*t);
return typeid(*t);
else
return &typeid(T);
return typeid(T);
}
public:
static CTypeList & getInstance()
{
static CTypeList registry;
return registry;
}
template<typename T, typename U>
void registerType()
{
registerType<T>();
registerType<U>();
}
template<typename T>
void registerType()
{
const std::type_info & typeInfo = typeid(T);
if (typeInfos.count(typeInfo.name()) != 0)
return;
typeInfos[typeInfo.name()] = typeInfos.size() + 1;
}
template<typename T>
uint16_t getTypeID(T * typePtr)
{
static_assert(!std::is_pointer_v<T>, "CTypeList does not supports pointers!");
static_assert(!std::is_reference_v<T>, "CTypeList does not supports references!");
const std::type_info & typeInfo = getTypeInfo(typePtr);
if (typeInfos.count(typeInfo.name()) == 0)
return 0;
return typeInfos.at(typeInfo.name());
}
};
extern DLL_LINKAGE CTypeList typeList;
/// Wrapper over CTypeList. Allows execution of templated class T for any type
/// that was resgistered for this applier
template<typename T>
class CApplier : boost::noncopyable
{
std::map<ui16, std::unique_ptr<T>> apps;
std::map<int32_t, std::unique_ptr<T>> apps;
template<typename RegisteredType>
void addApplier(ui16 ID)
@ -224,9 +97,8 @@ public:
template<typename Base, typename Derived>
void registerType(const Base * b = nullptr, const Derived * d = nullptr)
{
typeList.registerType(b, d);
addApplier<Base>(typeList.getTypeID(b));
addApplier<Derived>(typeList.getTypeID(d));
addApplier<Base>(CTypeList::getInstance().getTypeID<Base>(nullptr));
addApplier<Derived>(CTypeList::getInstance().getTypeID<Derived>(nullptr));
}
};

View File

@ -9,58 +9,18 @@
*/
#pragma once
#include <typeinfo>
#include <string>
#include "CTypeList.h"
VCMI_LIB_NAMESPACE_BEGIN
template<class T, class F>
inline const T * dynamic_ptr_cast(const F * ptr)
{
#ifndef VCMI_APPLE
return dynamic_cast<const T *>(ptr);
#else
if(!strcmp(typeid(*ptr).name(), typeid(T).name()))
{
return static_cast<const T *>(ptr);
}
try
{
auto * sourceTypeInfo = typeList.getTypeInfo(ptr);
auto * targetTypeInfo = &typeid(typename std::remove_const<typename std::remove_pointer<T>::type>::type);
typeList.castRaw((void *)ptr, sourceTypeInfo, targetTypeInfo);
}
catch(...)
{
return nullptr;
}
return static_cast<const T *>(ptr);
#endif
}
template<class T, class F>
inline T * dynamic_ptr_cast(F * ptr)
{
#ifndef VCMI_APPLE
return dynamic_cast<T *>(ptr);
#else
if(!strcmp(typeid(*ptr).name(), typeid(T).name()))
{
return static_cast<T *>(ptr);
}
try
{
auto * sourceTypeInfo = typeList.getTypeInfo(ptr);
auto * targetTypeInfo = &typeid(typename std::remove_const<typename std::remove_pointer<T>::type>::type);
typeList.castRaw((void *)ptr, sourceTypeInfo, targetTypeInfo);
}
catch(...)
{
return nullptr;
}
return static_cast<T *>(ptr);
#endif
}
VCMI_LIB_NAMESPACE_END

View File

@ -10,8 +10,7 @@
#include "StdInc.h"
#include "Connection.h"
#include "../registerTypes/RegisterTypes.h"
#include "../mapping/CMapHeader.h"
#include "../networkPacks/NetPacksBase.h"
#include <boost/asio.hpp>
@ -45,8 +44,6 @@ void CConnection::init()
enableSmartPointerSerialization();
disableStackSendingByID();
registerTypes(iser);
registerTypes(oser);
#ifndef VCMI_ENDIAN_BIG
myEndianess = true;
#else

View File

@ -267,39 +267,6 @@ public:
void updateFrom(const JsonNode & data);
void serializeJson(JsonSerializeFormat & handler);
template <typename Handler> void serialize(Handler & h, const int version)
{
h & identifier;
if (version > 820)
h & modScope;
h & id;
h & level;
h & power;
h & probabilities;
h & attributes;
h & combat;
h & creatureAbility;
h & positiveness;
h & counteredSpells;
h & rising;
h & damage;
h & offensive;
h & targetType;
h & targetCondition;
h & iconImmune;
h & defaultProbability;
h & special;
h & castSound;
h & iconBook;
h & iconEffect;
h & iconScenarioBonus;
h & iconScroll;
h & levels;
h & school;
h & animationInfo;
h & nonMagical;
h & onlyOnWaterMap;
}
friend class CSpellHandler;
friend class Graphics;
friend class test::CSpellTest;
@ -384,15 +351,6 @@ public:
*/
std::vector<bool> getDefaultAllowed() const override;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & objects;
if(!h.saving)
{
afterLoadFinalization();
}
}
protected:
const std::vector<std::string> & getTypeNames() const override;
CSpell * loadFromJson(const std::string & scope, const JsonNode & json, const std::string & identifier, size_t index) override;

View File

@ -16,7 +16,7 @@
#include "../lib/modding/CModInfo.h"
VCMI_LIB_NAMESPACE_BEGIN
using ModCompatibilityInfo = std::map<std::string, CModInfo::VerificationInfo>;
using ModCompatibilityInfo = std::map<std::string, ModVerificationInfo>;
class EditorObstaclePlacer;
VCMI_LIB_NAMESPACE_END

View File

@ -27,6 +27,7 @@
#include "../lib/CCreatureSet.h"
#include "../lib/CGeneralTextHandler.h"
#include "../lib/CHeroHandler.h"
#include "../lib/CPlayerState.h"
#include "../lib/CSoundBase.h"
#include "../lib/CThreadHelper.h"
#include "../lib/CTownHandler.h"
@ -47,20 +48,19 @@
#include "../lib/mapping/CMap.h"
#include "../lib/mapping/CMapService.h"
#include "../lib/mapObjects/CGMarket.h"
#include "../lib/modding/ModIncompatibility.h"
#include "../lib/networkPacks/StackLocation.h"
#include "../lib/pathfinder/CPathfinder.h"
#include "../lib/pathfinder/PathfinderOptions.h"
#include "../lib/pathfinder/TurnInfo.h"
#include "../lib/registerTypes/RegisterTypes.h"
#include "../lib/registerTypes/RegisterTypesServerPacks.h"
#include "../lib/rmg/CMapGenOptions.h"
#include "../lib/serializer/CTypeList.h"
#include "../lib/serializer/Cast.h"
#include "../lib/serializer/Connection.h"
#include "../lib/serializer/JsonSerializer.h"
#include "../lib/serializer/CSaveFile.h"
#include "../lib/serializer/CLoadFile.h"
#include "../lib/spells/CSpellHandler.h"
@ -463,12 +463,12 @@ void CGameHandler::handleReceivedPack(CPackForServer * pack)
PackageApplied applied;
applied.player = pack->player;
applied.result = succesfullyApplied;
applied.packType = typeList.getTypeID(pack);
applied.packType = CTypeList::getInstance().getTypeID(pack);
applied.requestID = pack->requestID;
pack->c->sendPack(&applied);
};
CBaseForGHApply * apply = applier->getApplier(typeList.getTypeID(pack)); //and appropriate applier object
CBaseForGHApply * apply = applier->getApplier(CTypeList::getInstance().getTypeID(pack)); //and appropriate applier object
if(isBlockedByQueries(pack, pack->player))
{
sendPackageResponse(false);
@ -4057,7 +4057,7 @@ void CGameHandler::spawnWanderingMonsters(CreatureID creatureID)
void CGameHandler::synchronizeArtifactHandlerLists()
{
UpdateArtHandlerLists uahl;
uahl.allocatedArtifacts = VLC->arth->allocatedArtifacts;
uahl.allocatedArtifacts = gs->allocatedArtifacts;
sendAndApply(&uahl);
}

View File

@ -47,7 +47,7 @@
#include "../lib/UnlockGuard.h"
// for applier
#include "../lib/registerTypes/RegisterTypes.h"
#include "../lib/registerTypes/RegisterTypesLobbyPacks.h"
// UUID generation
#include <boost/uuid/uuid.hpp>
@ -485,7 +485,7 @@ void CVCMIServer::threadHandleClient(std::shared_ptr<CConnection> c)
void CVCMIServer::handleReceivedPack(std::unique_ptr<CPackForLobby> pack)
{
CBaseForServerApply * apply = applier->getApplier(typeList.getTypeID(pack.get()));
CBaseForServerApply * apply = applier->getApplier(CTypeList::getInstance().getTypeID(pack.get()));
if(apply->applyOnServerBefore(this, pack.get()))
addToAnnounceQueue(std::move(pack));
}
@ -502,7 +502,7 @@ void CVCMIServer::announcePack(std::unique_ptr<CPackForLobby> pack)
c->sendPack(pack.get());
}
applier->getApplier(typeList.getTypeID(pack.get()))->applyOnServerAfter(this, pack.get());
applier->getApplier(CTypeList::getInstance().getTypeID(pack.get()))->applyOnServerAfter(this, pack.get());
}
void CVCMIServer::announceMessage(const std::string & txt)