- updated to beta2 and added primitive CRC checking for network games, requies the Host user to set the following ini to enable CRC's:
EnableNetworkGameSynchChecks=true
This commit is contained in:
parent
6f85a6aa4a
commit
b5e26070b1
|
@ -140,11 +140,11 @@ void PathFinder::removeUnitPrecache(Unit *unit) {
|
||||||
clearPath = true;
|
clearPath = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
|
// if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
|
||||||
char szBuf[8096]="";
|
// char szBuf[8096]="";
|
||||||
snprintf(szBuf,8096,"[removeUnitPrecache] clearTravelState: %d clearPath: %d",clearTravelState,clearPath);
|
// snprintf(szBuf,8096,"[removeUnitPrecache] clearTravelState: %d clearPath: %d",clearTravelState,clearPath);
|
||||||
unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
|
// unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ using namespace Shared::Platform;
|
||||||
namespace Glest { namespace Game {
|
namespace Glest { namespace Game {
|
||||||
|
|
||||||
const char *mailString = " http://bugs.megaglest.org";
|
const char *mailString = " http://bugs.megaglest.org";
|
||||||
const string glestVersionString = "v3.8.0-beta1";
|
const string glestVersionString = "v3.8.0-beta2";
|
||||||
#if defined(SVNVERSION)
|
#if defined(SVNVERSION)
|
||||||
const string SVN_Rev = string("Rev: ") + string(SVNVERSION);
|
const string SVN_Rev = string("Rev: ") + string(SVNVERSION);
|
||||||
#elif defined(SVNVERSIONHEADER)
|
#elif defined(SVNVERSIONHEADER)
|
||||||
|
|
|
@ -1705,6 +1705,28 @@ void Game::update() {
|
||||||
perfList.push_back(perfBuf);
|
perfList.push_back(perfBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isNetworkGame = this->gameSettings.isNetworkGame();
|
||||||
|
if(isNetworkGame == true && NetworkManager::getInstance().getGameNetworkInterface() != NULL) {
|
||||||
|
GameSettings *settings = world.getGameSettingsPtr();
|
||||||
|
if(settings != NULL && (settings->getFlagTypes1() & ft1_network_synch_checks) == ft1_network_synch_checks) {
|
||||||
|
NetworkInterface *netIntf = NetworkManager::getInstance().getGameNetworkInterface();
|
||||||
|
for(int index = 0; index < GameConstants::maxPlayers; ++index) {
|
||||||
|
|
||||||
|
if(index < world.getFactionCount()) {
|
||||||
|
Faction *faction = world.getFaction(index);
|
||||||
|
netIntf->setNetworkPlayerFactionCRC(index,faction->getCRC().getSum());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
netIntf->setNetworkPlayerFactionCRC(index,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//if(world.getFrameCount() % 40 == 0) {
|
||||||
|
// printf("Frame #: %d Faction: %d CRC: %u\n",world.getFrameCount(),index,netIntf->getNetworkPlayerFactionCRC(index));
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Chrono chrono;
|
Chrono chrono;
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
|
||||||
|
|
||||||
|
@ -1771,7 +1793,7 @@ void Game::update() {
|
||||||
|
|
||||||
NetworkManager &networkManager= NetworkManager::getInstance();
|
NetworkManager &networkManager= NetworkManager::getInstance();
|
||||||
bool enableServerControlledAI = this->gameSettings.getEnableServerControlledAI();
|
bool enableServerControlledAI = this->gameSettings.getEnableServerControlledAI();
|
||||||
bool isNetworkGame = this->gameSettings.isNetworkGame();
|
//bool isNetworkGame = this->gameSettings.isNetworkGame();
|
||||||
NetworkRole role = networkManager.getNetworkRole();
|
NetworkRole role = networkManager.getNetworkRole();
|
||||||
|
|
||||||
if(role == nrClient && updateLoops == 1 && world.getFrameCount() >= (gameSettings.getNetworkFramePeriod() * 2) ) {
|
if(role == nrClient && updateLoops == 1 && world.getFrameCount() >= (gameSettings.getNetworkFramePeriod() * 2) ) {
|
||||||
|
|
|
@ -61,11 +61,11 @@ public:
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
|
||||||
enum FlagTypes1 {
|
enum FlagTypes1 {
|
||||||
ft1_none = 0x00,
|
ft1_none = 0x00,
|
||||||
ft1_show_map_resources = 0x01,
|
ft1_show_map_resources = 0x01,
|
||||||
ft1_allow_team_switching = 0x02,
|
ft1_allow_team_switching = 0x02,
|
||||||
ft1_allow_in_game_joining = 0x04
|
ft1_allow_in_game_joining = 0x04,
|
||||||
//ft1_xx = 0x08,
|
ft1_network_synch_checks = 0x08
|
||||||
//ft1_xx = 0x10,
|
//ft1_xx = 0x10,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3182,6 +3182,17 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings,bool force
|
||||||
gameSettings->setFlagTypes1(valueFlags1);
|
gameSettings->setFlagTypes1(valueFlags1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(Config::getInstance().getBool("EnableNetworkGameSynchChecks","false") == true) {
|
||||||
|
valueFlags1 |= ft1_network_synch_checks;
|
||||||
|
gameSettings->setFlagTypes1(valueFlags1);
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
valueFlags1 &= ~ft1_network_synch_checks;
|
||||||
|
gameSettings->setFlagTypes1(valueFlags1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
gameSettings->setNetworkAllowNativeLanguageTechtree(checkBoxAllowNativeLanguageTechtree.getValue());
|
gameSettings->setNetworkAllowNativeLanguageTechtree(checkBoxAllowNativeLanguageTechtree.getValue());
|
||||||
|
|
||||||
// First save Used slots
|
// First save Used slots
|
||||||
|
|
|
@ -430,6 +430,9 @@ void ClientInterface::update() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
NetworkMessageCommandList networkMessageCommandList(currentFrameCount);
|
NetworkMessageCommandList networkMessageCommandList(currentFrameCount);
|
||||||
|
for(int index = 0; index < GameConstants::maxPlayers; ++index) {
|
||||||
|
networkMessageCommandList.setNetworkPlayerFactionCRC(index,this->getNetworkPlayerFactionCRC(index));
|
||||||
|
}
|
||||||
|
|
||||||
//send as many commands as we can
|
//send as many commands as we can
|
||||||
while(requestedCommands.empty() == false) {
|
while(requestedCommands.empty() == false) {
|
||||||
|
@ -1085,6 +1088,23 @@ void ClientInterface::updateFrame(int *checkFrame) {
|
||||||
close();
|
close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
for(int index = 0; index < GameConstants::maxPlayers; ++index) {
|
||||||
|
printf("Frame: %d faction: %d local CRC: %u Remote CRC: %u\n",*checkFrame,index,getNetworkPlayerFactionCRC(index),networkMessageCommandList.getNetworkPlayerFactionCRC(index));
|
||||||
|
|
||||||
|
if(networkMessageCommandList.getNetworkPlayerFactionCRC(index) != getNetworkPlayerFactionCRC(index)) {
|
||||||
|
string sErr = "Player: " + getHumanPlayerName() +
|
||||||
|
" got a Network CRC error, CRC's do not match, server CRC = " +
|
||||||
|
uIntToStr(networkMessageCommandList.getNetworkPlayerFactionCRC(index)) + ", local CRC = " +
|
||||||
|
uIntToStr(getNetworkPlayerFactionCRC(index));
|
||||||
|
sendTextMessage(sErr,-1, true,"");
|
||||||
|
DisplayErrorMessage(sErr);
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
setQuit(true);
|
||||||
|
close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cachedPendingCommands[networkMessageCommandList.getFrameCount()].reserve(networkMessageCommandList.getCommandCount());
|
cachedPendingCommands[networkMessageCommandList.getFrameCount()].reserve(networkMessageCommandList.getCommandCount());
|
||||||
|
@ -1093,6 +1113,13 @@ void ClientInterface::updateFrame(int *checkFrame) {
|
||||||
for(int i= 0; i < networkMessageCommandList.getCommandCount(); ++i) {
|
for(int i= 0; i < networkMessageCommandList.getCommandCount(); ++i) {
|
||||||
//pendingCommands.push_back(*networkMessageCommandList.getCommand(i));
|
//pendingCommands.push_back(*networkMessageCommandList.getCommand(i));
|
||||||
cachedPendingCommands[networkMessageCommandList.getFrameCount()].push_back(*networkMessageCommandList.getCommand(i));
|
cachedPendingCommands[networkMessageCommandList.getFrameCount()].push_back(*networkMessageCommandList.getCommand(i));
|
||||||
|
|
||||||
|
if(cachedPendingCommandCRCs.find(networkMessageCommandList.getFrameCount()) == cachedPendingCommandCRCs.end()) {
|
||||||
|
cachedPendingCommandCRCs[networkMessageCommandList.getFrameCount()].reserve(GameConstants::maxPlayers);
|
||||||
|
for(int index = 0; index < GameConstants::maxPlayers; ++index) {
|
||||||
|
cachedPendingCommandCRCs[networkMessageCommandList.getFrameCount()].push_back(networkMessageCommandList.getNetworkPlayerFactionCRC(index));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
safeMutex.ReleaseLock();
|
safeMutex.ReleaseLock();
|
||||||
|
|
||||||
|
@ -1377,6 +1404,30 @@ bool ClientInterface::getNetworkCommand(int frameCount, int currentCachedPending
|
||||||
}
|
}
|
||||||
//cachedPendingCommands.erase(frameCount);
|
//cachedPendingCommands.erase(frameCount);
|
||||||
cachedPendingCommands[frameCount].clear();
|
cachedPendingCommands[frameCount].clear();
|
||||||
|
|
||||||
|
if(frameCount >= 0) {
|
||||||
|
for(int index = 0; index < GameConstants::maxPlayers; ++index) {
|
||||||
|
//printf("X**X Frame: %d faction: %d local CRC: %u Remote CRC: %u\n",frameCount,index,getNetworkPlayerFactionCRC(index),cachedPendingCommandCRCs[frameCount][index]);
|
||||||
|
|
||||||
|
if(cachedPendingCommandCRCs[frameCount][index] != getNetworkPlayerFactionCRC(index)) {
|
||||||
|
|
||||||
|
printf("X**X Frame: %d faction: %d local CRC: %u Remote CRC: %u\n",frameCount,index,getNetworkPlayerFactionCRC(index),cachedPendingCommandCRCs[frameCount][index]);
|
||||||
|
|
||||||
|
string sErr = "Player: " + getHumanPlayerName() +
|
||||||
|
" got a Network CRC error, CRC's do not match, server CRC = " +
|
||||||
|
uIntToStr(cachedPendingCommandCRCs[frameCount][index]) + ", local CRC = " +
|
||||||
|
uIntToStr(getNetworkPlayerFactionCRC(index));
|
||||||
|
sendTextMessage(sErr,-1, true,"");
|
||||||
|
DisplayErrorMessage(sErr);
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
setQuit(true);
|
||||||
|
close();
|
||||||
|
//return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cachedPendingCommandCRCs.erase(frameCount);
|
||||||
}
|
}
|
||||||
if(waitForData == true) {
|
if(waitForData == true) {
|
||||||
timeClientWaitedForLastMessage=chrono.getMillis();
|
timeClientWaitedForLastMessage=chrono.getMillis();
|
||||||
|
|
|
@ -87,6 +87,7 @@ private:
|
||||||
|
|
||||||
Mutex *networkCommandListThreadAccessor;
|
Mutex *networkCommandListThreadAccessor;
|
||||||
std::map<int,Commands> cachedPendingCommands; //commands ready to be given
|
std::map<int,Commands> cachedPendingCommands; //commands ready to be given
|
||||||
|
std::map<int,vector<uint32> > cachedPendingCommandCRCs; //commands ready to be given
|
||||||
uint64 cachedPendingCommandsIndex;
|
uint64 cachedPendingCommandsIndex;
|
||||||
uint64 cachedLastPendingFrameCount;
|
uint64 cachedLastPendingFrameCount;
|
||||||
int64 timeClientWaitedForLastMessage;
|
int64 timeClientWaitedForLastMessage;
|
||||||
|
|
|
@ -47,6 +47,8 @@ NetworkInterface::NetworkInterface() {
|
||||||
networkGameDataSynchCheckOkTile=false;
|
networkGameDataSynchCheckOkTile=false;
|
||||||
networkGameDataSynchCheckOkTech=false;
|
networkGameDataSynchCheckOkTech=false;
|
||||||
receivedDataSynchCheck=false;
|
receivedDataSynchCheck=false;
|
||||||
|
|
||||||
|
networkPlayerFactionCRCMutex = new Mutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkInterface::init() {
|
void NetworkInterface::init() {
|
||||||
|
@ -63,6 +65,22 @@ void NetworkInterface::init() {
|
||||||
NetworkInterface::~NetworkInterface() {
|
NetworkInterface::~NetworkInterface() {
|
||||||
delete networkAccessMutex;
|
delete networkAccessMutex;
|
||||||
networkAccessMutex = NULL;
|
networkAccessMutex = NULL;
|
||||||
|
|
||||||
|
delete networkPlayerFactionCRCMutex;
|
||||||
|
networkPlayerFactionCRCMutex = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 NetworkInterface::getNetworkPlayerFactionCRC(int index) {
|
||||||
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
||||||
|
MutexSafeWrapper safeMutex(networkPlayerFactionCRCMutex,mutexOwnerId);
|
||||||
|
|
||||||
|
return networkPlayerFactionCRC[index];
|
||||||
|
}
|
||||||
|
void NetworkInterface::setNetworkPlayerFactionCRC(int index, uint32 crc) {
|
||||||
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
||||||
|
MutexSafeWrapper safeMutex(networkPlayerFactionCRCMutex,mutexOwnerId);
|
||||||
|
|
||||||
|
networkPlayerFactionCRC[index]=crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkInterface::addChatInfo(const ChatMsgInfo &msg) {
|
void NetworkInterface::addChatInfo(const ChatMsgInfo &msg) {
|
||||||
|
|
|
@ -188,6 +188,10 @@ protected:
|
||||||
Mutex *networkAccessMutex;
|
Mutex *networkAccessMutex;
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
Mutex *networkPlayerFactionCRCMutex;
|
||||||
|
uint32 networkPlayerFactionCRC[GameConstants::maxPlayers];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const int readyWaitTimeout;
|
static const int readyWaitTimeout;
|
||||||
GameSettings gameSettings;
|
GameSettings gameSettings;
|
||||||
|
@ -205,6 +209,9 @@ public:
|
||||||
throw megaglest_runtime_error("class NetworkInterface is NOT safe to assign!");
|
throw megaglest_runtime_error("class NetworkInterface is NOT safe to assign!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 getNetworkPlayerFactionCRC(int index);
|
||||||
|
void setNetworkPlayerFactionCRC(int index, uint32 crc);
|
||||||
|
|
||||||
virtual Socket* getSocket(bool mutexLock=true)= 0;
|
virtual Socket* getSocket(bool mutexLock=true)= 0;
|
||||||
virtual void close()= 0;
|
virtual void close()= 0;
|
||||||
virtual string getHumanPlayerName(int index=-1) = 0;
|
virtual string getHumanPlayerName(int index=-1) = 0;
|
||||||
|
|
|
@ -1215,6 +1215,9 @@ NetworkMessageCommandList::NetworkMessageCommandList(int32 frameCount) {
|
||||||
data.header.messageType= nmtCommandList;
|
data.header.messageType= nmtCommandList;
|
||||||
data.header.frameCount= frameCount;
|
data.header.frameCount= frameCount;
|
||||||
data.header.commandCount= 0;
|
data.header.commandCount= 0;
|
||||||
|
for(int index = 0; index < GameConstants::maxPlayers; ++index) {
|
||||||
|
data.header.networkPlayerFactionCRC[index]=0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetworkMessageCommandList::addCommand(const NetworkCommand* networkCommand){
|
bool NetworkMessageCommandList::addCommand(const NetworkCommand* networkCommand){
|
||||||
|
|
|
@ -348,6 +348,7 @@ private:
|
||||||
int8 messageType;
|
int8 messageType;
|
||||||
uint16 commandCount;
|
uint16 commandCount;
|
||||||
int32 frameCount;
|
int32 frameCount;
|
||||||
|
uint32 networkPlayerFactionCRC[GameConstants::maxPlayers];
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int32 commandListHeaderSize = sizeof(DataHeader);
|
static const int32 commandListHeaderSize = sizeof(DataHeader);
|
||||||
|
@ -388,9 +389,12 @@ public:
|
||||||
|
|
||||||
bool addCommand(const NetworkCommand* networkCommand);
|
bool addCommand(const NetworkCommand* networkCommand);
|
||||||
|
|
||||||
void clear() {data.header.commandCount= 0;}
|
void clear() {data.header.commandCount= 0;}
|
||||||
int getCommandCount() const {return data.header.commandCount;}
|
int getCommandCount() const {return data.header.commandCount;}
|
||||||
int getFrameCount() const {return data.header.frameCount;}
|
int getFrameCount() const {return data.header.frameCount;}
|
||||||
|
uint32 getNetworkPlayerFactionCRC(int index) const {return data.header.networkPlayerFactionCRC[index];}
|
||||||
|
void setNetworkPlayerFactionCRC(int index, uint32 crc) { data.header.networkPlayerFactionCRC[index]=crc;}
|
||||||
|
|
||||||
const NetworkCommand* getCommand(int i) const {return &data.commands[i];}
|
const NetworkCommand* getCommand(int i) const {return &data.commands[i];}
|
||||||
|
|
||||||
virtual bool receive(Socket* socket);
|
virtual bool receive(Socket* socket);
|
||||||
|
|
|
@ -1605,6 +1605,9 @@ void ServerInterface::updateKeyframe(int frameCount) {
|
||||||
currentFrameCount = frameCount;
|
currentFrameCount = frameCount;
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] currentFrameCount = %d, requestedCommands.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentFrameCount,requestedCommands.size());
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] currentFrameCount = %d, requestedCommands.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentFrameCount,requestedCommands.size());
|
||||||
NetworkMessageCommandList networkMessageCommandList(frameCount);
|
NetworkMessageCommandList networkMessageCommandList(frameCount);
|
||||||
|
for(int index = 0; index < GameConstants::maxPlayers; ++index) {
|
||||||
|
networkMessageCommandList.setNetworkPlayerFactionCRC(index,this->getNetworkPlayerFactionCRC(index));
|
||||||
|
}
|
||||||
|
|
||||||
while(requestedCommands.empty() == false) {
|
while(requestedCommands.empty() == false) {
|
||||||
if(networkMessageCommandList.addCommand(&requestedCommands.back())) {
|
if(networkMessageCommandList.addCommand(&requestedCommands.back())) {
|
||||||
|
|
|
@ -2248,4 +2248,53 @@ void Faction::loadGame(const XmlNode *rootNode, int factionIndex,GameSettings *s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Checksum Faction::getCRC() {
|
||||||
|
const bool consoleDebug = false;
|
||||||
|
|
||||||
|
Checksum crcForFaction;
|
||||||
|
|
||||||
|
// UpgradeManager upgradeManager;
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < resources.size(); ++i) {
|
||||||
|
Resource &resource = resources[i];
|
||||||
|
//crcForFaction.addSum(resource.getCRC().getSum());
|
||||||
|
uint32 crc = resource.getCRC().getSum();
|
||||||
|
crcForFaction.addBytes(&crc,sizeof(uint32));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(consoleDebug) {
|
||||||
|
if(getWorld()->getFrameCount() % 40 == 0) {
|
||||||
|
printf("#1 Frame #: %d Faction: %d CRC: %u\n",getWorld()->getFrameCount(),index,crcForFaction.getSum());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < store.size(); ++i) {
|
||||||
|
Resource &resource = store[i];
|
||||||
|
//crcForFaction.addSum(resource.getCRC().getSum());
|
||||||
|
uint32 crc = resource.getCRC().getSum();
|
||||||
|
crcForFaction.addBytes(&crc,sizeof(uint32));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(consoleDebug) {
|
||||||
|
if(getWorld()->getFrameCount() % 40 == 0) {
|
||||||
|
printf("#2 Frame #: %d Faction: %d CRC: %u\n",getWorld()->getFrameCount(),index,crcForFaction.getSum());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < units.size(); ++i) {
|
||||||
|
Unit *unit = units[i];
|
||||||
|
//crcForFaction.addSum(unit->getCRC().getSum());
|
||||||
|
uint32 crc = unit->getCRC().getSum();
|
||||||
|
crcForFaction.addBytes(&crc,sizeof(uint32));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(consoleDebug) {
|
||||||
|
if(getWorld()->getFrameCount() % 40 == 0) {
|
||||||
|
printf("#3 Frame #: %d Faction: %d CRC: %u\n",getWorld()->getFrameCount(),index,crcForFaction.getSum());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return crcForFaction;
|
||||||
|
}
|
||||||
|
|
||||||
}}//end namespace
|
}}//end namespace
|
||||||
|
|
|
@ -369,6 +369,8 @@ public:
|
||||||
|
|
||||||
void clearCaches();
|
void clearCaches();
|
||||||
|
|
||||||
|
Checksum getCRC();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
void resetResourceAmount(const ResourceType *rt);
|
void resetResourceAmount(const ResourceType *rt);
|
||||||
|
|
|
@ -129,4 +129,16 @@ void Resource::loadGame(const XmlNode *rootNode, int index,const TechTree *techT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Checksum Resource::getCRC() {
|
||||||
|
Checksum crcForResource;
|
||||||
|
|
||||||
|
crcForResource.addInt(amount);
|
||||||
|
crcForResource.addString(type->getName(false));
|
||||||
|
crcForResource.addInt(pos.x);
|
||||||
|
crcForResource.addInt(pos.y);
|
||||||
|
crcForResource.addInt(balance);
|
||||||
|
|
||||||
|
return crcForResource;
|
||||||
|
}
|
||||||
|
|
||||||
}}//end namespace
|
}}//end namespace
|
||||||
|
|
|
@ -65,6 +65,8 @@ public:
|
||||||
|
|
||||||
void saveGame(XmlNode *rootNode) const;
|
void saveGame(XmlNode *rootNode) const;
|
||||||
void loadGame(const XmlNode *rootNode, int index,const TechTree *techTree);
|
void loadGame(const XmlNode *rootNode, int index,const TechTree *techTree);
|
||||||
|
|
||||||
|
Checksum getCRC();
|
||||||
};
|
};
|
||||||
|
|
||||||
}}// end namespace
|
}}// end namespace
|
||||||
|
|
|
@ -4905,4 +4905,216 @@ Unit * Unit::loadGame(const XmlNode *rootNode, GameSettings *settings, Faction *
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Checksum Unit::getCRC() {
|
||||||
|
const bool consoleDebug = false;
|
||||||
|
|
||||||
|
Checksum crcForUnit;
|
||||||
|
|
||||||
|
crcForUnit.addInt(id);
|
||||||
|
crcForUnit.addInt(hp);
|
||||||
|
crcForUnit.addInt(ep);
|
||||||
|
crcForUnit.addInt(loadCount);
|
||||||
|
crcForUnit.addInt(deadCount);
|
||||||
|
|
||||||
|
if(consoleDebug) printf("#1 Unit: %d CRC: %u\n",id,crcForUnit.getSum());
|
||||||
|
|
||||||
|
crcForUnit.addInt64(progress);
|
||||||
|
crcForUnit.addInt64(lastAnimProgress);
|
||||||
|
crcForUnit.addInt64(animProgress);
|
||||||
|
|
||||||
|
if(consoleDebug) printf("#2 Unit: %d CRC: %u\n",id,crcForUnit.getSum());
|
||||||
|
|
||||||
|
//float highlight;
|
||||||
|
crcForUnit.addInt(progress2);
|
||||||
|
crcForUnit.addInt(kills);
|
||||||
|
crcForUnit.addInt(enemyKills);
|
||||||
|
crcForUnit.addInt(morphFieldsBlocked);
|
||||||
|
|
||||||
|
if(consoleDebug) printf("#3 Unit: %d CRC: %u\n",id,crcForUnit.getSum());
|
||||||
|
|
||||||
|
//UnitReference targetRef;
|
||||||
|
|
||||||
|
crcForUnit.addInt(currField);
|
||||||
|
crcForUnit.addInt(targetField);
|
||||||
|
|
||||||
|
if(consoleDebug) printf("#4 Unit: %d CRC: %u\n",id,crcForUnit.getSum());
|
||||||
|
|
||||||
|
//const Level *level;
|
||||||
|
if(level != NULL) {
|
||||||
|
crcForUnit.addString(level->getName(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(consoleDebug) printf("#5 Unit: %d CRC: %u\n",id,crcForUnit.getSum());
|
||||||
|
|
||||||
|
crcForUnit.addInt(pos.x);
|
||||||
|
crcForUnit.addInt(pos.y);
|
||||||
|
crcForUnit.addInt(lastPos.x);
|
||||||
|
crcForUnit.addInt(lastPos.y);
|
||||||
|
crcForUnit.addInt(targetPos.x);
|
||||||
|
crcForUnit.addInt(targetPos.y);
|
||||||
|
|
||||||
|
if(consoleDebug) printf("#6 Unit: %d CRC: %u\n",id,crcForUnit.getSum());
|
||||||
|
|
||||||
|
//Vec3f targetVec;
|
||||||
|
|
||||||
|
crcForUnit.addInt(meetingPos.x);
|
||||||
|
crcForUnit.addInt(meetingPos.y);
|
||||||
|
|
||||||
|
if(consoleDebug) printf("#7 Unit: %d CRC: %u\n",id,crcForUnit.getSum());
|
||||||
|
|
||||||
|
//float lastRotation;
|
||||||
|
//float targetRotation;
|
||||||
|
//float rotation;
|
||||||
|
//float targetRotationZ;
|
||||||
|
//float targetRotationX;
|
||||||
|
//float rotationZ;
|
||||||
|
//float rotationX;
|
||||||
|
|
||||||
|
//const UnitType *preMorph_type;
|
||||||
|
if(preMorph_type != NULL) {
|
||||||
|
crcForUnit.addString(preMorph_type->getName(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(consoleDebug) printf("#8 Unit: %d CRC: %u\n",id,crcForUnit.getSum());
|
||||||
|
|
||||||
|
//const UnitType *type;
|
||||||
|
if(type != NULL) {
|
||||||
|
crcForUnit.addString(type->getName(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
//const ResourceType *loadType;
|
||||||
|
if(loadType != NULL) {
|
||||||
|
crcForUnit.addString(loadType->getName(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
//const SkillType *currSkill;
|
||||||
|
if(currSkill != NULL) {
|
||||||
|
crcForUnit.addString(currSkill->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("#9 Unit: %d CRC: %u lastModelIndexForCurrSkillType: %d\n",id,crcForUnit.getSum(),lastModelIndexForCurrSkillType);
|
||||||
|
//printf("#9a Unit: %d CRC: %u\n",id,crcForUnit.getSum());
|
||||||
|
//crcForUnit.addInt(lastModelIndexForCurrSkillType);
|
||||||
|
|
||||||
|
if(consoleDebug) printf("#9 Unit: %d CRC: %u\n",id,crcForUnit.getSum());
|
||||||
|
|
||||||
|
//crcForUnit.addInt(animationRandomCycleCount);
|
||||||
|
//printf("#9b Unit: %d CRC: %u\n",id,crcForUnit.getSum());
|
||||||
|
|
||||||
|
crcForUnit.addInt(toBeUndertaken);
|
||||||
|
|
||||||
|
if(consoleDebug) printf("#9c Unit: %d CRC: %u\n",id,crcForUnit.getSum());
|
||||||
|
|
||||||
|
crcForUnit.addInt(alive);
|
||||||
|
//bool showUnitParticles;
|
||||||
|
|
||||||
|
if(consoleDebug) printf("#10 Unit: %d CRC: %u\n",id,crcForUnit.getSum());
|
||||||
|
|
||||||
|
//Faction *faction;
|
||||||
|
//ParticleSystem *fire;
|
||||||
|
if(fire != NULL) {
|
||||||
|
crcForUnit.addInt(fire->getActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
//TotalUpgrade totalUpgrade;
|
||||||
|
//Map *map;
|
||||||
|
//UnitPathInterface *unitPath;
|
||||||
|
//WaypointPath waypointPath;
|
||||||
|
|
||||||
|
if(consoleDebug) printf("#11 Unit: %d CRC: %u commands.size(): %ld\n",id,crcForUnit.getSum(),commands.size());
|
||||||
|
|
||||||
|
//Commands commands;
|
||||||
|
crcForUnit.addInt64((int64)commands.size());
|
||||||
|
|
||||||
|
//printf("#11 Unit: %d CRC: %u observers.size(): %ld\n",id,crcForUnit.getSum(),observers.size());
|
||||||
|
|
||||||
|
//Observers observers;
|
||||||
|
//crcForUnit.addInt64((int64)observers.size());
|
||||||
|
|
||||||
|
if(consoleDebug) printf("#11 Unit: %d CRC: %u damageParticleSystems.size(): %ld\n",id,crcForUnit.getSum(),damageParticleSystems.size());
|
||||||
|
|
||||||
|
//vector<UnitParticleSystem*> unitParticleSystems;
|
||||||
|
//vector<UnitParticleSystemType*> queuedUnitParticleSystemTypes;
|
||||||
|
|
||||||
|
//UnitParticleSystems damageParticleSystems;
|
||||||
|
crcForUnit.addInt64((int64)damageParticleSystems.size());
|
||||||
|
|
||||||
|
if(consoleDebug) printf("#12 Unit: %d CRC: %u\n",id,crcForUnit.getSum());
|
||||||
|
|
||||||
|
//std::map<int, UnitParticleSystem *> damageParticleSystemsInUse;
|
||||||
|
|
||||||
|
//vector<ParticleSystem*> fireParticleSystems;
|
||||||
|
//vector<UnitParticleSystem*> smokeParticleSystems;
|
||||||
|
|
||||||
|
//CardinalDir modelFacing;
|
||||||
|
crcForUnit.addInt(modelFacing);
|
||||||
|
|
||||||
|
//std::string lastSynchDataString;
|
||||||
|
//std::string lastFile;
|
||||||
|
//int lastLine;
|
||||||
|
//std::string lastSource;
|
||||||
|
//int lastRenderFrame;
|
||||||
|
//bool visible;
|
||||||
|
crcForUnit.addInt(modelFacing);
|
||||||
|
|
||||||
|
//int retryCurrCommandCount;
|
||||||
|
|
||||||
|
//Vec3f screenPos;
|
||||||
|
//string currentUnitTitle;
|
||||||
|
|
||||||
|
if(consoleDebug) printf("#13 Unit: %d CRC: %u\n",id,crcForUnit.getSum());
|
||||||
|
|
||||||
|
crcForUnit.addInt(inBailOutAttempt);
|
||||||
|
|
||||||
|
crcForUnit.addInt64((int64)badHarvestPosList.size());
|
||||||
|
//crcForUnit.addInt(lastHarvestResourceTarget.first());
|
||||||
|
|
||||||
|
if(consoleDebug) printf("#14 Unit: %d CRC: %u\n",id,crcForUnit.getSum());
|
||||||
|
|
||||||
|
//static Game *game;
|
||||||
|
//bool ignoreCheckCommand;
|
||||||
|
|
||||||
|
//uint32 lastStuckFrame;
|
||||||
|
//Vec2i lastStuckPos;
|
||||||
|
|
||||||
|
//uint32 lastPathfindFailedFrame;
|
||||||
|
//Vec2i lastPathfindFailedPos;
|
||||||
|
//bool usePathfinderExtendedMaxNodes;
|
||||||
|
//int maxQueuedCommandDisplayCount;
|
||||||
|
|
||||||
|
//UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect;
|
||||||
|
crcForUnit.addInt64((int64)currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size());
|
||||||
|
|
||||||
|
if(consoleDebug) printf("#15 Unit: %d CRC: %u\n",id,crcForUnit.getSum());
|
||||||
|
|
||||||
|
//std::vector<UnitAttackBoostEffect *> currentAttackBoostEffects;
|
||||||
|
|
||||||
|
//Mutex *mutexCommands;
|
||||||
|
|
||||||
|
//bool changedActiveCommand;
|
||||||
|
|
||||||
|
//int lastAttackerUnitId;
|
||||||
|
//int lastAttackedUnitId;
|
||||||
|
//CauseOfDeathType causeOfDeath;
|
||||||
|
|
||||||
|
//uint32 pathfindFailedConsecutiveFrameCount;
|
||||||
|
//Vec2i currentPathFinderDesiredFinalPos;
|
||||||
|
|
||||||
|
crcForUnit.addInt(random.getLastNumber());
|
||||||
|
|
||||||
|
if(consoleDebug) printf("#16 Unit: %d CRC: %u\n",id,crcForUnit.getSum());
|
||||||
|
|
||||||
|
//int pathFindRefreshCellCount;
|
||||||
|
|
||||||
|
//FowAlphaCellsLookupItem cachedFow;
|
||||||
|
//Vec2i cachedFowPos;
|
||||||
|
|
||||||
|
crcForUnit.addInt(lastHarvestedResourcePos.x);
|
||||||
|
crcForUnit.addInt(lastHarvestedResourcePos.y);
|
||||||
|
|
||||||
|
if(consoleDebug) printf("#17 Unit: %d CRC: %u\n",id,crcForUnit.getSum());
|
||||||
|
|
||||||
|
return crcForUnit;
|
||||||
|
}
|
||||||
|
|
||||||
}}//end namespace
|
}}//end namespace
|
||||||
|
|
|
@ -343,19 +343,19 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const int id;
|
const int32 id;
|
||||||
int hp;
|
int32 hp;
|
||||||
int ep;
|
int32 ep;
|
||||||
int loadCount;
|
int32 loadCount;
|
||||||
int deadCount;
|
int32 deadCount;
|
||||||
//float progress; //between 0 and 1
|
//float progress; //between 0 and 1
|
||||||
int64 progress; //between 0 and 1
|
int64 progress; //between 0 and 1
|
||||||
int64 lastAnimProgress; //between 0 and 1
|
int64 lastAnimProgress; //between 0 and 1
|
||||||
int64 animProgress; //between 0 and 1
|
int64 animProgress; //between 0 and 1
|
||||||
float highlight;
|
float highlight;
|
||||||
int progress2;
|
int32 progress2;
|
||||||
int kills;
|
int32 kills;
|
||||||
int enemyKills;
|
int32 enemyKills;
|
||||||
bool morphFieldsBlocked;
|
bool morphFieldsBlocked;
|
||||||
|
|
||||||
UnitReference targetRef;
|
UnitReference targetRef;
|
||||||
|
@ -382,8 +382,8 @@ private:
|
||||||
const UnitType *type;
|
const UnitType *type;
|
||||||
const ResourceType *loadType;
|
const ResourceType *loadType;
|
||||||
const SkillType *currSkill;
|
const SkillType *currSkill;
|
||||||
int lastModelIndexForCurrSkillType;
|
int32 lastModelIndexForCurrSkillType;
|
||||||
int animationRandomCycleCount;
|
int32 animationRandomCycleCount;
|
||||||
|
|
||||||
bool toBeUndertaken;
|
bool toBeUndertaken;
|
||||||
bool alive;
|
bool alive;
|
||||||
|
@ -412,9 +412,9 @@ private:
|
||||||
|
|
||||||
std::string lastSynchDataString;
|
std::string lastSynchDataString;
|
||||||
std::string lastFile;
|
std::string lastFile;
|
||||||
int lastLine;
|
int32 lastLine;
|
||||||
std::string lastSource;
|
std::string lastSource;
|
||||||
int lastRenderFrame;
|
int32 lastRenderFrame;
|
||||||
bool visible;
|
bool visible;
|
||||||
|
|
||||||
int retryCurrCommandCount;
|
int retryCurrCommandCount;
|
||||||
|
@ -445,7 +445,7 @@ private:
|
||||||
uint32 lastPathfindFailedFrame;
|
uint32 lastPathfindFailedFrame;
|
||||||
Vec2i lastPathfindFailedPos;
|
Vec2i lastPathfindFailedPos;
|
||||||
bool usePathfinderExtendedMaxNodes;
|
bool usePathfinderExtendedMaxNodes;
|
||||||
int maxQueuedCommandDisplayCount;
|
int32 maxQueuedCommandDisplayCount;
|
||||||
|
|
||||||
UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect;
|
UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect;
|
||||||
|
|
||||||
|
@ -458,15 +458,15 @@ private:
|
||||||
|
|
||||||
bool changedActiveCommand;
|
bool changedActiveCommand;
|
||||||
|
|
||||||
int lastAttackerUnitId;
|
int32 lastAttackerUnitId;
|
||||||
int lastAttackedUnitId;
|
int32 lastAttackedUnitId;
|
||||||
CauseOfDeathType causeOfDeath;
|
CauseOfDeathType causeOfDeath;
|
||||||
|
|
||||||
uint32 pathfindFailedConsecutiveFrameCount;
|
uint32 pathfindFailedConsecutiveFrameCount;
|
||||||
Vec2i currentPathFinderDesiredFinalPos;
|
Vec2i currentPathFinderDesiredFinalPos;
|
||||||
|
|
||||||
RandomGen random;
|
RandomGen random;
|
||||||
int pathFindRefreshCellCount;
|
int32 pathFindRefreshCellCount;
|
||||||
|
|
||||||
FowAlphaCellsLookupItem cachedFow;
|
FowAlphaCellsLookupItem cachedFow;
|
||||||
Vec2i cachedFowPos;
|
Vec2i cachedFowPos;
|
||||||
|
@ -768,6 +768,8 @@ public:
|
||||||
void clearCaches();
|
void clearCaches();
|
||||||
bool showTranslatedTechTree() const;
|
bool showTranslatedTechTree() const;
|
||||||
|
|
||||||
|
Checksum getCRC();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float computeHeight(const Vec2i &pos) const;
|
float computeHeight(const Vec2i &pos) const;
|
||||||
void calculateXZRotation();
|
void calculateXZRotation();
|
||||||
|
|
|
@ -359,11 +359,6 @@ void UnitUpdater::updateStop(Unit *unit, int frameIndex) {
|
||||||
clearUnitPrecache(unit);
|
clearUnitPrecache(unit);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) {
|
|
||||||
char szBuf[8096]="";
|
|
||||||
snprintf(szBuf,8096,"[updateStop]");
|
|
||||||
unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
Chrono chrono;
|
Chrono chrono;
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
|
||||||
|
@ -690,11 +685,6 @@ void UnitUpdater::updateAttackStopped(Unit *unit, int frameIndex) {
|
||||||
clearUnitPrecache(unit);
|
clearUnitPrecache(unit);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) {
|
|
||||||
char szBuf[8096]="";
|
|
||||||
snprintf(szBuf,8096,"[updateAttackStopped]");
|
|
||||||
unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
Chrono chrono;
|
Chrono chrono;
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
|
||||||
|
|
|
@ -53,6 +53,7 @@ public:
|
||||||
uint32 addBytes(const void *_data, size_t _size);
|
uint32 addBytes(const void *_data, size_t _size);
|
||||||
void addString(const string &value);
|
void addString(const string &value);
|
||||||
uint32 addInt(const int32 &value);
|
uint32 addInt(const int32 &value);
|
||||||
|
uint32 addInt64(const int64 &value);
|
||||||
void addFile(const string &path);
|
void addFile(const string &path);
|
||||||
|
|
||||||
static void removeFileFromCache(const string file);
|
static void removeFileFromCache(const string file);
|
||||||
|
|
|
@ -128,6 +128,27 @@ uint32 Checksum::addInt(const int32 &value) {
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 Checksum::addInt64(const int64 &value) {
|
||||||
|
int8 byte = (value >> 0) & 0xFF;
|
||||||
|
addByte(byte);
|
||||||
|
byte = (value >> 8) & 0xFF;
|
||||||
|
addByte(byte);
|
||||||
|
byte = (value >> 16) & 0xFF;
|
||||||
|
addByte(byte);
|
||||||
|
byte = (value >> 24) & 0xFF;
|
||||||
|
addByte(byte);
|
||||||
|
byte = (value >> 32) & 0xFF;
|
||||||
|
addByte(byte);
|
||||||
|
byte = (value >> 40) & 0xFF;
|
||||||
|
addByte(byte);
|
||||||
|
byte = (value >> 48) & 0xFF;
|
||||||
|
addByte(byte);
|
||||||
|
byte = (value >> 56) & 0xFF;
|
||||||
|
addByte(byte);
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
void Checksum::addString(const string &value) {
|
void Checksum::addString(const string &value) {
|
||||||
for(unsigned int i = 0; i < value.size(); ++i) {
|
for(unsigned int i = 0; i < value.size(); ++i) {
|
||||||
addByte(value[i]);
|
addByte(value[i]);
|
||||||
|
|
Loading…
Reference in New Issue