- fixed two nasty AI bugs which would cause out of synch and memory corruption problems

- added new glest.ini setting to log commands for each client
This commit is contained in:
Mark Vejvoda 2010-06-08 07:40:32 +00:00
parent d14f013491
commit 4fd75e5d7d
18 changed files with 212 additions and 86 deletions

View File

@ -1,7 +1,7 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
// Copyright (C) 2001-2008 Martio Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
@ -375,6 +375,8 @@ void Ai::sendScoutPatrol(){
if(aiInterface->getFactionIndex()!=startLoc){
if(findAbleUnit(&unit, ccAttack, false)){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
aiInterface->giveCommand(unit, ccAttack, pos);
aiInterface->printLog(2, "Scout patrol sent to: " + intToStr(pos.x)+","+intToStr(pos.y)+"\n");
}
@ -427,6 +429,7 @@ void Ai::massiveAttack(const Vec2i &pos, Field field, bool ultraAttack){
bool alreadyAttacking= unit->getCurrSkill()->getClass()==scAttack;
if(!alreadyAttacking && act!=NULL && (ultraAttack || isWarrior)){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
aiInterface->giveCommand(i, act, pos);
}
}
@ -459,6 +462,8 @@ void Ai::returnBase(int unitIndex){
pos= Vec2i(
random.randRange(-villageRadius, villageRadius), random.randRange(-villageRadius, villageRadius)) +
getRandomHomePosition();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
r= aiInterface->giveCommand(unitIndex, ccMove, pos);
//aiInterface->printLog(1, "Order return to base pos:" + intToStr(pos.x)+", "+intToStr(pos.y)+": "+rrToStr(r)+"\n");

View File

@ -98,9 +98,12 @@ CommandResult AiInterface::giveCommand(int unitIndex, CommandClass commandClass,
if(this->gameSettings->getEnableServerControlledAI() == true &&
this->gameSettings->isNetworkGame() == true &&
NetworkManager::getInstance().getNetworkRole() == nrServer) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
CommandResult result = commander->tryGiveCommand(world->getFaction(factionIndex)->getUnit(unitIndex), world->getFaction(factionIndex)->getUnit(unitIndex)->getType()->getFirstCtOfClass(commandClass), pos, world->getFaction(factionIndex)->getUnit(unitIndex)->getType(),CardinalDir::NORTH);
//Unit *unit = world->getFaction(factionIndex)->getUnit(unitIndex);
const Unit *unit = getMyUnit(unitIndex);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unitIndex = %d\nunit = [%s]\ncommandClass = [%d]\n",__FILE__,__FUNCTION__,__LINE__,unitIndex,unit->toString().c_str(),commandClass);
CommandResult result = commander->tryGiveCommand(unit, unit->getType()->getFirstCtOfClass(commandClass), pos, unit->getType(),CardinalDir::NORTH);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -123,9 +126,12 @@ CommandResult AiInterface::giveCommand(int unitIndex, const CommandType *command
if(this->gameSettings->getEnableServerControlledAI() == true &&
this->gameSettings->isNetworkGame() == true &&
NetworkManager::getInstance().getNetworkRole() == nrServer) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
CommandResult result = commander->tryGiveCommand(world->getFaction(factionIndex)->getUnit(unitIndex), commandType, pos, world->getFaction(factionIndex)->getUnit(unitIndex)->getType(),CardinalDir::NORTH);
//Unit *unit = world->getFaction(factionIndex)->getUnit(unitIndex);
const Unit *unit = getMyUnit(unitIndex);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unitIndex = %d\nunit = [%s]\ncommandType = %d - [%s]\nCommand Type List:\n%s\n",__FILE__,__FUNCTION__,__LINE__,unitIndex,unit->toString().c_str(),commandType->getId(),commandType->toString().c_str(),unit->getType()->getCommandTypeListDesc().c_str());
CommandResult result = commander->tryGiveCommand(unit, commandType, pos, unit->getType(),CardinalDir::NORTH);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -148,9 +154,12 @@ CommandResult AiInterface::giveCommand(int unitIndex, const CommandType *command
if(this->gameSettings->getEnableServerControlledAI() == true &&
this->gameSettings->isNetworkGame() == true &&
NetworkManager::getInstance().getNetworkRole() == nrServer) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
CommandResult result = commander->tryGiveCommand(world->getFaction(factionIndex)->getUnit(unitIndex), commandType, pos, ut,CardinalDir::NORTH);
//Unit *unit = world->getFaction(factionIndex)->getUnit(unitIndex);
const Unit *unit = getMyUnit(unitIndex);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unitIndex = %d\nunit = [%s]\ncommandType = %d - [%s]\nut = %p\n",__FILE__,__FUNCTION__,__LINE__,unitIndex,unit->toString().c_str(),commandType->getId(),commandType->toString().c_str(),ut);
CommandResult result = commander->tryGiveCommand(unit, commandType, pos, ut,CardinalDir::NORTH);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -175,12 +184,12 @@ CommandResult AiInterface::giveCommand(int unitIndex, const CommandType *command
this->gameSettings->isNetworkGame() == true &&
NetworkManager::getInstance().getNetworkRole() == nrServer) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
Unit *targetUnit = u;
//Unit *unit = world->getFaction(factionIndex)->getUnit(unitIndex);
const Unit *unit = getMyUnit(unitIndex);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unitIndex = %d\nunit = [%s]\ncommandType = %d - [%s]\nTarget Unit Id= %d\nUnit Commands:\n%s\n",__FILE__,__FUNCTION__,__LINE__,unitIndex,unit->toString().c_str(),(commandType != NULL ? commandType->getId() : -1),(commandType != NULL ? commandType->toString().c_str() : "null"),(targetUnit != NULL ? targetUnit->getId() : -1),unit->getType()->getCommandTypeListDesc().c_str());
if(u == NULL) {
u = world->getFaction(factionIndex)->getUnit(unitIndex);
}
CommandResult result = commander->tryGiveCommand(u, commandType, Vec2i(0), u->getType(),CardinalDir::NORTH);
CommandResult result = commander->tryGiveCommand(unit, commandType, Vec2i(0), unit->getType(),CardinalDir::NORTH,false,targetUnit);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -242,7 +251,13 @@ const Resource *AiInterface::getResource(const ResourceType *rt){
}
const Unit *AiInterface::getMyUnit(int unitIndex){
return world->getFaction(factionIndex)->getUnit(unitIndex);
if(unitIndex >= world->getFaction(factionIndex)->getUnitCount()) {
char szBuf[1024]="";
sprintf(szBuf,"In [%s::%s Line: %d] unitIndex >= world->getFaction(factionIndex)->getUnitCount(), unitIndex = %d, world->getFaction(factionIndex)->getUnitCount() = %d",__FILE__,__FUNCTION__,__LINE__,unitIndex,world->getFaction(factionIndex)->getUnitCount());
throw runtime_error(szBuf);
}
return world->getFaction(factionIndex)->getUnit(unitIndex);
}
const Unit *AiInterface::getOnSightUnit(int unitIndex){

View File

@ -1,7 +1,7 @@
// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
// Copyright (C) 2001-2008 Martio Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
@ -115,6 +115,8 @@ void AiRuleRepair::execute(){
const RepairCommandType *rct= static_cast<const RepairCommandType *>(u->getType()->getFirstCtOfClass(ccRepair));
if(rct!=NULL && (u->getCurrSkill()->getClass()==scStop || u->getCurrSkill()->getClass()==scMove)){
if(rct->isRepairableUnitType(damagedUnit->getType())){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
aiInterface->giveCommand(i, rct, damagedUnit->getPos());
aiInterface->printLog(3, "Repairing order issued");
return;
@ -489,6 +491,7 @@ void AiRuleProduce::produceSpecific(const ProduceTask *pt){
//produce specific unit
vector<int> producers;
vector<const CommandType *> producersDefaultCommandType;
const CommandType *defCt= NULL;
//for each unit
@ -508,6 +511,7 @@ void AiRuleProduce::produceSpecific(const ProduceTask *pt){
if(aiInterface->reqsOk(ct)){
defCt= ct;
producers.push_back(i);
producersDefaultCommandType.push_back(ct);
}
}
}
@ -527,6 +531,12 @@ void AiRuleProduce::produceSpecific(const ProduceTask *pt){
for(unsigned int i=randomstart; i<producers.size()+randomstart; i++)
{
currentProducerIndex=producers[i%(producers.size())];
if(currentProducerIndex >= aiInterface->getMyUnitCount()) {
char szBuf[1024]="";
sprintf(szBuf,"In [%s::%s Line: %d] currentProducerIndex >= aiInterface->getMyUnitCount(), currentProducerIndex = %d, aiInterface->getMyUnitCount() = %d, i = %d,producers.size() = %d",__FILE__,__FUNCTION__,__LINE__,currentProducerIndex,aiInterface->getMyUnitCount(),i,producers.size());
throw runtime_error(szBuf);
}
currentCommandCount=aiInterface->getMyUnit(currentProducerIndex)->getCommandSize();
if( currentCommandCount==1 &&
aiInterface->getMyUnit(currentProducerIndex)->getCurrCommand()->getCommandType()->getClass()==ccStop)
@ -548,8 +558,9 @@ void AiRuleProduce::produceSpecific(const ProduceTask *pt){
if(ai->getCountOfClass(ucBuilding)>5)
ai->addTask(new BuildTask(aiInterface->getMyUnit(bestIndex)->getType()));
}
// need to calculte another producer, maybe its better to produce another warrior with another producer
// need to calculate another producer, maybe its better to produce another warrior with another producer
vector<int> backupProducers;
vector<const CommandType *> backupProducersDefaultCommandType;
// find another producer unit which is free and produce any kind of warrior.
//for each unit
for(int i=0; i<aiInterface->getMyUnitCount(); ++i){
@ -563,7 +574,8 @@ void AiRuleProduce::produceSpecific(const ProduceTask *pt){
const UnitType *unitType= static_cast<const UnitType*>(ct->getProduced());
if(unitType->hasSkillClass(scAttack) && !unitType->hasCommandClass(ccHarvest) && aiInterface->reqsOk(ct))
{//this can produce a warrior
backupProducers.push_back(i);
backupProducers.push_back(i);
backupProducersDefaultCommandType.push_back(ct);
}
}
}
@ -608,10 +620,13 @@ void AiRuleProduce::produceSpecific(const ProduceTask *pt){
}
}
int commandIndex=productionCommandIndexes[ai->getRandom()->randRange(0, productionCommandIndexes.size()-1)];
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
aiInterface->giveCommand(bestIndex, ut->getCommandType(commandIndex));
}
else
{// do it like normal CPU
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
defCt = producersDefaultCommandType[bestIndex];
aiInterface->giveCommand(bestIndex, defCt);
}
}
@ -619,14 +634,21 @@ void AiRuleProduce::produceSpecific(const ProduceTask *pt){
{
if(currentCommandCount==0)
{
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
defCt = producersDefaultCommandType[bestIndex];
aiInterface->giveCommand(bestIndex, defCt);
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
defCt = producersDefaultCommandType[bestIndex];
aiInterface->giveCommand(bestIndex, defCt);
}
}
else
{
int producerIndex= producers[ai->getRandom()->randRange(0, producers.size()-1)];
int pIndex = ai->getRandom()->randRange(0, producers.size()-1);
int producerIndex= producers[pIndex];
defCt = producersDefaultCommandType[pIndex];
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] producers.size() = %d, producerIndex = %d, pIndex = %d, producersDefaultCommandType.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,producers.size(),producerIndex,pIndex,producersDefaultCommandType.size());
aiInterface->giveCommand(producerIndex, defCt);
}
}
@ -779,6 +801,7 @@ void AiRuleBuild::buildSpecific(const BuildTask *bt){
}
vector<int> builders;
vector<const BuildCommandType *> buildersDefaultCommandType;
const BuildCommandType *defBct= NULL;
//for each unit
@ -805,6 +828,7 @@ void AiRuleBuild::buildSpecific(const BuildTask *bt){
if(bt->getUnitType()==building){
if(aiInterface->reqsOk(bct)){
builders.push_back(i);
buildersDefaultCommandType.push_back(bct);
defBct= bct;
}
}
@ -816,12 +840,16 @@ void AiRuleBuild::buildSpecific(const BuildTask *bt){
//use random builder to build
if(!builders.empty()){
int builderIndex= builders[ai->getRandom()->randRange(0, builders.size()-1)];
int bIndex = ai->getRandom()->randRange(0, builders.size()-1);
int builderIndex= builders[bIndex];
Vec2i pos;
Vec2i searchPos= bt->getForcePos()? bt->getPos(): ai->getRandomHomePosition();
//if free pos give command, else retry
if(ai->findPosForBuilding(bt->getUnitType(), searchPos, pos)){
defBct = buildersDefaultCommandType[bIndex];
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] builderIndex = %d, bIndex = %d, defBct = %p\n",__FILE__,__FUNCTION__,__LINE__,builderIndex,bIndex,defBct);
aiInterface->giveCommand(builderIndex, defBct, pos, bt->getUnitType());
}
else{
@ -957,6 +985,7 @@ void AiRuleUpgrade::upgradeSpecific(const UpgradeTask *upgt){
//if upgrades match
if(producedUpgrade == upgt->getUpgradeType()){
if(aiInterface->reqsOk(uct)){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
aiInterface->giveCommand(i, uct);
}
}

View File

@ -41,7 +41,7 @@ void Commander::init(World *world){
this->world= world;
}
CommandResult Commander::tryGiveCommand(const Unit* unit, const CommandType *commandType, const Vec2i &pos, const UnitType* unitType, CardinalDir facing, bool tryQueue) const {
CommandResult Commander::tryGiveCommand(const Unit* unit, const CommandType *commandType, const Vec2i &pos, const UnitType* unitType, CardinalDir facing, bool tryQueue,Unit *targetUnit) const {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
assert(this->world != NULL);
@ -51,7 +51,7 @@ CommandResult Commander::tryGiveCommand(const Unit* unit, const CommandType *com
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
NetworkCommand networkCommand(this->world,nctGiveCommand, unit->getId(), commandType->getId(), pos, unitType->getId(), -1, facing, tryQueue);
NetworkCommand networkCommand(this->world,nctGiveCommand, unit->getId(), commandType->getId(), pos, unitType->getId(), (targetUnit != NULL ? targetUnit->getId() : -1), facing, tryQueue);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -265,7 +265,10 @@ void Commander::updateNetwork() {
//check that this is a keyframe
GameSettings *gameSettings = this->world->getGame()->getGameSettings();
if( !networkManager.isNetworkGame() || (world->getFrameCount() % gameSettings->getNetworkFramePeriod()) == 0) {
if( networkManager.isNetworkGame() == false ||
(world->getFrameCount() % gameSettings->getNetworkFramePeriod()) == 0) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] networkManager.isNetworkGame() = %d,world->getFrameCount() = %d, gameSettings->getNetworkFramePeriod() = %d\n",__FILE__,__FUNCTION__,__LINE__,networkManager.isNetworkGame(),world->getFrameCount(),gameSettings->getNetworkFramePeriod());
GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();

View File

@ -50,7 +50,7 @@ public:
void init(World *world);
void updateNetwork();
CommandResult tryGiveCommand(const Unit* unit, const CommandType *commandType, const Vec2i &pos, const UnitType* unitType, CardinalDir facing, bool tryQueue = false) const;
CommandResult tryGiveCommand(const Unit* unit, const CommandType *commandType, const Vec2i &pos, const UnitType* unitType, CardinalDir facing, bool tryQueue = false,Unit *targetUnit=NULL) const;
CommandResult tryGiveCommand(const Selection *selection, CommandClass commandClass, const Vec2i &pos= Vec2i(0), const Unit *targetUnit= NULL, bool tryQueue = false) const;
CommandResult tryGiveCommand(const Selection *selection, const CommandType *commandType, const Vec2i &pos= Vec2i(0), const Unit *targetUnit= NULL, bool tryQueue = false) const;
CommandResult tryGiveCommand(const Selection *selection, const Vec2i &pos, const Unit *targetUnit= NULL, bool tryQueue = false) const;

View File

@ -298,6 +298,7 @@ int glestMain(int argc, char** argv){
SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled = config.getBool("DebugNetwork","false");
SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled = config.getBool("DebugPerformance","false");
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled = config.getBool("DebugWorldSynch","false");
SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled = config.getBool("DebugUnitCommands","false");
string debugLogFile = config.getString("DebugLogFile","");
if(getGameReadWritePath() != "") {
@ -315,23 +316,31 @@ int glestMain(int argc, char** argv){
if(debugNetworkLogFile == "") {
debugNetworkLogFile = debugLogFile;
}
string debugUnitCommandsLogFile = config.getString("DebugLogFileUnitCommands","");
if(debugUnitCommandsLogFile == "") {
debugUnitCommandsLogFile = debugLogFile;
}
SystemFlags::getSystemSettingType(SystemFlags::debugSystem).debugLogFileName = debugLogFile;
SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).debugLogFileName = debugNetworkLogFile;
SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).debugLogFileName = debugPerformanceLogFile;
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).debugLogFileName = debugWorldSynchLogFile;
SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).debugLogFileName = debugUnitCommandsLogFile;
printf("Startup settings are: debugSystem [%d], debugNetwork [%d], debugPerformance [%d], debugWorldSynch [%d]\n",
printf("Startup settings are: debugSystem [%d], debugNetwork [%d], debugPerformance [%d], debugWorldSynch [%d], debugUnitCommands[%d]\n",
SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled,
SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled,
SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled,
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled);
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled,
SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled);
NetworkInterface::setDisplayMessageFunction(ExceptionHandler::DisplayMessage);
MenuStateMasterserver::setDisplayMessageFunction(ExceptionHandler::DisplayMessage);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"START\n");
// 256 for English
// 30000 for Chinese
Font::charCount = config.getInt("FONT_CHARCOUNT",intToStr(Font::charCount).c_str());

View File

@ -370,18 +370,22 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
else if(buttonPlayNow.mouseClick(x,y) && buttonPlayNow.getEnabled()) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
saveGameSettingsToFile("lastCustomGamSettings.mgg");
closeUnusedSlots();
soundRenderer.playFx(coreData.getClickSoundC());
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
safeMutex.ReleaseLock(false);
GameSettings gameSettings;
loadGameSettings(&gameSettings);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
// Send the game settings to each client if we have at least one networked client
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
safeMutex.Lock();
if( hasNetworkGameSettings() == true &&
needToSetChangedGameSettings == true)
{
@ -411,7 +415,6 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
needToBroadcastServerSettings = false;
needToRepublishToMasterserver = false;
saveGameSettingsToFile("lastCustomGamSettings.mgg");
BaseThread::shutdownAndWait(publishToMasterserverThread);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);

View File

@ -471,7 +471,7 @@ void ClientInterface::updateKeyframe(int frameCount)
chrono.start();
//check that we are in the right frame
if(networkMessageCommandList.getFrameCount() != frameCount) {
string sErr = "Network synchronization error, frame counts do not match";
string sErr = "Network synchronization error, frame counts do not match, server frameCount = " + intToStr(networkMessageCommandList.getFrameCount()) + ", local frameCount = " + intToStr(frameCount);
//throw runtime_error("Network synchronization error, frame counts do not match");
sendTextMessage(sErr,-1);
DisplayErrorMessage(sErr);

View File

@ -57,14 +57,14 @@ NetworkMessageType NetworkInterface::getNextMessageType(bool checkHasDataFirst)
//peek message type
int dataSize = socket->getDataToRead();
if(dataSize >= sizeof(messageType)){
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] socket->getDataToRead() dataSize = %d\n",__FILE__,__FUNCTION__,dataSize);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() dataSize = %d\n",__FILE__,__FUNCTION__,__LINE__,dataSize);
int iPeek = socket->peek(&messageType, sizeof(messageType));
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] socket->getDataToRead() iPeek = %d, messageType = %d [size = %d]\n",__FILE__,__FUNCTION__,iPeek,messageType,sizeof(messageType));
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() iPeek = %d, messageType = %d [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,iPeek,messageType,sizeof(messageType));
}
else {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] PEEK WARNING, socket->getDataToRead() messageType = %d [size = %d], dataSize = %d, checkHasDataFirst = %d\n",__FILE__,__FUNCTION__,messageType,sizeof(messageType),dataSize,checkHasDataFirst);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] PEEK WARNING, socket->getDataToRead() messageType = %d [size = %d], dataSize = %d, checkHasDataFirst = %d\n",__FILE__,__FUNCTION__,__LINE__,messageType,sizeof(messageType),dataSize,checkHasDataFirst);
}
//sanity check new message type

View File

@ -236,40 +236,51 @@ void NetworkMessageLaunch::send(Socket* socket) const{
// =====================================================
NetworkMessageCommandList::NetworkMessageCommandList(int32 frameCount){
data.messageType= nmtCommandList;
data.frameCount= frameCount;
data.commandCount= 0;
data.header.messageType= nmtCommandList;
data.header.frameCount= frameCount;
data.header.commandCount= 0;
}
bool NetworkMessageCommandList::addCommand(const NetworkCommand* networkCommand){
if(data.commandCount < maxCommandCount){
data.commands[static_cast<int>(data.commandCount)]= *networkCommand;
data.commandCount++;
if(data.header.commandCount < maxCommandCount){
data.commands[static_cast<int>(data.header.commandCount)]= *networkCommand;
data.header.commandCount++;
return true;
}
return false;
}
bool NetworkMessageCommandList::receive(Socket* socket){
bool NetworkMessageCommandList::receive(Socket* socket) {
// _peek_ type, commandCount & frame num first.
if (!NetworkMessage::peek(socket, &data, commandListHeaderSize)) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING!!! NetworkMessage::peek failed!\n",__FILE__,__FUNCTION__,__LINE__);
for(int peekAttempt = 1; peekAttempt < 5; peekAttempt++) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] peekAttempt = %d\n",__FILE__,__FUNCTION__,__LINE__,peekAttempt);
if (NetworkMessage::peek(socket, &data, commandListHeaderSize) == true) {
break;
}
else {
sleep(1); // sleep 1 ms to wait for socket data
}
}
if (NetworkMessage::peek(socket, &data, commandListHeaderSize) == false) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR / WARNING!!! NetworkMessage::peek failed!\n",__FILE__,__FUNCTION__,__LINE__);
return false;
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] messageType = %d, frameCount = %d, data.commandCount = %d\n",
__FILE__,__FUNCTION__,__LINE__,data.messageType,data.frameCount,data.commandCount);
__FILE__,__FUNCTION__,__LINE__,data.header.messageType,data.header.frameCount,data.header.commandCount);
// read header + data.commandCount commands.
int totalMsgSize = commandListHeaderSize + sizeof(NetworkCommand) * data.commandCount;
int totalMsgSize = commandListHeaderSize + (sizeof(NetworkCommand) * data.header.commandCount);
if (socket->getDataToRead() < totalMsgSize) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING!!! Insufficient data to read entire command list [need %d bytes, only %d available].\n",
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR / WARNING!!! Insufficient data to read entire command list [need %d bytes, only %d available].\n",
__FILE__,__FUNCTION__,__LINE__, totalMsgSize, socket->getDataToRead());
return false;
}
bool result = NetworkMessage::receive(socket, &data, totalMsgSize);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled == true) {
for(int idx = 0 ; idx < data.commandCount; ++idx) {
for(int idx = 0 ; idx < data.header.commandCount; ++idx) {
const NetworkCommand &cmd = data.commands[idx];
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] index = %d, received networkCommand [%s]\n",
@ -280,15 +291,16 @@ bool NetworkMessageCommandList::receive(Socket* socket){
}
void NetworkMessageCommandList::send(Socket* socket) const{
assert(data.messageType==nmtCommandList);
NetworkMessage::send(socket, &data, commandListHeaderSize + sizeof(NetworkCommand) * data.commandCount);
assert(data.header.messageType==nmtCommandList);
int totalMsgSize = commandListHeaderSize + (sizeof(NetworkCommand) * data.header.commandCount);
NetworkMessage::send(socket, &data, totalMsgSize);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] messageType = %d, frameCount = %d, data.commandCount = %d\n",
__FILE__,__FUNCTION__,__LINE__,data.messageType,data.frameCount,data.commandCount);
__FILE__,__FUNCTION__,__LINE__,data.header.messageType,data.header.frameCount,data.header.commandCount);
if (data.commandCount > 0) {
for(int idx = 0 ; idx < data.commandCount; ++idx) {
if (data.header.commandCount > 0) {
for(int idx = 0 ; idx < data.header.commandCount; ++idx) {
const NetworkCommand &cmd = data.commands[idx];
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] index = %d, sent networkCommand [%s]\n",

View File

@ -53,8 +53,6 @@ enum NetworkGameStateType {
nmgstCount
};
const int32 commandListHeaderSize = 6;
// =====================================================
// class NetworkMessage
// =====================================================
@ -189,18 +187,27 @@ public:
// Message to order a commands to several units
// =====================================================
//const int32 commandListHeaderSize = 6;
#pragma pack(push, 1)
class NetworkMessageCommandList: public NetworkMessage{
private:
//static const int maxCommandCount= 16*4;
static const int maxCommandCount = (16 * 4) * 2;
//static const int maxCommandCount = (16 * 4) * 2;
static const int maxCommandCount = 2048; // can be as large as 65535
private:
struct Data{
struct DataHeader {
int8 messageType;
uint8 commandCount;
uint16 commandCount;
//int8 commandCount;
int32 frameCount;
};
static const int32 commandListHeaderSize = sizeof(DataHeader);
struct Data {
DataHeader header;
NetworkCommand commands[maxCommandCount];
};
@ -212,9 +219,9 @@ public:
bool addCommand(const NetworkCommand* networkCommand);
void clear() {data.commandCount= 0;}
int getCommandCount() const {return data.commandCount;}
int getFrameCount() const {return data.frameCount;}
void clear() {data.header.commandCount= 0;}
int getCommandCount() const {return data.header.commandCount;}
int getFrameCount() const {return data.header.frameCount;}
const NetworkCommand* getCommand(int i) const {return &data.commands[i];}
virtual bool receive(Socket* socket);
@ -230,7 +237,7 @@ public:
class NetworkMessageText: public NetworkMessage{
private:
static const int maxStringSize= 128;
static const int maxStringSize= 256;
private:
struct Data{

View File

@ -19,7 +19,9 @@
using std::string;
using Shared::Platform::int8;
using Shared::Platform::uint8;
using Shared::Platform::int16;
using Shared::Platform::uint16;
using Shared::Platform::int32;
using Shared::Graphics::Vec2i;
@ -57,7 +59,7 @@ enum NetworkCommandType {
// ncstRotateUnit
//};
#pragma pack(push, 2)
#pragma pack(push, 1)
class NetworkCommand{
private:
int16 networkCommandType;
@ -67,10 +69,10 @@ private:
int16 positionY;
int16 unitTypeId;
int32 targetId;
int16 wantQueue;
int16 fromFactionIndex;
int16 unitFactionUnitCount;
int16 unitFactionIndex;
int8 wantQueue;
int8 fromFactionIndex;
uint16 unitFactionUnitCount;
int8 unitFactionIndex;
public:
NetworkCommand(){};

View File

@ -144,6 +144,10 @@ Unit::Unit(int id, const Vec2i &pos, const UnitType *type, Faction *faction, Map
this->faction=faction;
this->map= map;
this->targetRef = NULL;
this->targetField = fLand;
this->targetVec = Vec3f(0.0);
this->targetPos = Vec2i(0);
level= NULL;
loadType= NULL;
@ -448,6 +452,10 @@ void Unit::setTargetPos(const Vec2i &targetPos){
#endif
targetRef= NULL;
//this->targetField = fLand;
//this->targetVec = Vec3f(0.0);
//this->targetPos = Vec2i(0);
this->targetPos= targetPos;
logSynchData(string(__FILE__) + string("::") + string(__FUNCTION__) + string(" Line: ") + intToStr(__LINE__));
@ -520,6 +528,8 @@ unsigned int Unit::getCommandSize() const{
CommandResult Unit::giveCommand(Command *command, bool tryQueue) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__, __LINE__);
SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"\n======================\nUnit Command tryQueue = %d\nUnit Info:\n%s\nCommand Info:\n%s\n",tryQueue,this->toString().c_str(),command->toString().c_str());
assert(command != NULL);
assert(command->getCommandType() != NULL);
@ -1306,12 +1316,13 @@ std::string Unit::toString() const {
result += " loadCount = " + intToStr(this->loadCount);
result += " deadCount = " + intToStr(this->deadCount);
result += " progress = " + floatToStr(this->progress);
result += "\n";
result += " lastAnimProgress = " + floatToStr(this->lastAnimProgress);
result += " animProgress = " + floatToStr(this->animProgress);
result += " highlight = " + floatToStr(this->highlight);
result += " progress2 = " + intToStr(this->progress2);
result += " kills = " + intToStr(this->kills);
result += "\n";
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
// WARNING!!! Don't access the Unit pointer in this->targetRef in this method or it causes
@ -1328,12 +1339,14 @@ std::string Unit::toString() const {
if(level != NULL) {
result += " level = " + level->getName();
}
result += "\n";
result += " pos = " + pos.getString();
result += " lastPos = " + lastPos.getString();
result += "\n";
result += " targetPos = " + targetPos.getString();
result += " targetVec = " + targetVec.getString();
result += " meetingPos = " + meetingPos.getString();
result += "\n";
result += " lastRotation = " + floatToStr(this->lastRotation);
result += " targetRotation = " + floatToStr(this->targetRotation);
@ -1348,6 +1361,7 @@ std::string Unit::toString() const {
if(currSkill != NULL) {
result += " currSkill = " + currSkill->getName();
}
result += "\n";
result += " toBeUndertaken = " + intToStr(this->toBeUndertaken);
result += " alive = " + intToStr(this->alive);
@ -1356,8 +1370,8 @@ std::string Unit::toString() const {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
result += " totalUpgrade = " + totalUpgrade.toString();
result += " " + unitPath.toString() + "\n";
result += "\n";
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -1374,6 +1388,7 @@ std::string Unit::toString() const {
}
cmdIdx++;
}
result += "\n";
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);

View File

@ -595,6 +595,15 @@ const CommandType* UnitType::findCommandTypeById(int id) const{
return NULL;
}
const CommandType *UnitType::getCommandType(int i) const {
if(i >= commandTypes.size()) {
char szBuf[1024]="";
sprintf(szBuf,"In [%s::%s Line: %d] i >= commandTypes.size(), i = %d, commandTypes.size() = %d",__FILE__,__FUNCTION__,__LINE__,i,commandTypes.size());
throw runtime_error(szBuf);
}
return commandTypes[i];
}
string UnitType::getCommandTypeListDesc() const {
string desc = "Commands: ";
for(int i=0; i<getCommandTypeCount(); ++i){

View File

@ -138,7 +138,7 @@ public:
int getArmor() const {return armor;}
const ArmorType *getArmorType() const {return armorType;}
const SkillType *getSkillType(int i) const {return skillTypes[i];}
const CommandType *getCommandType(int i) const {return commandTypes[i];}
const CommandType *getCommandType(int i) const;
const Level *getLevel(int i) const {return &levels[i];}
int getSkillTypeCount() const {return skillTypes.size();}
int getCommandTypeCount() const {return commandTypes.size();}

View File

@ -38,7 +38,8 @@ public:
debugSystem,
debugNetwork,
debugPerformance,
debugWorldSynch
debugWorldSynch,
debugUnitCommands
};
class SystemFlagsType
@ -101,6 +102,7 @@ protected:
static int lockFile;
static string lockfilename;
static int lockFileCountIndex;
static std::map<DebugType,SystemFlagsType> debugLogFileList;

View File

@ -1,8 +1,10 @@
#include "randomgen.h"
#include <cassert>
#include "util.h"
#include <stdexcept>
#include "leak_dumper.h"
using namespace std;
namespace Shared { namespace Util {
// =====================================================
@ -37,7 +39,7 @@ void RandomGen::init(int seed){
int RandomGen::rand() {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] lastNumber = %d\n",__FILE__,__FUNCTION__,__LINE__,lastNumber);
lastNumber= ((a*lastNumber) + b) % m;
lastNumber= (a*lastNumber + b) % m;
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] lastNumber = %d\n",__FILE__,__FUNCTION__,__LINE__,lastNumber);
@ -46,14 +48,24 @@ int RandomGen::rand() {
int RandomGen::randRange(int min, int max){
assert(min<=max);
if(min > max) {
char szBuf[1024]="";
sprintf(szBuf,"In [%s::%s Line: %d] min > max, min = %d, max = %d",__FILE__,__FUNCTION__,__LINE__,min,max);
throw runtime_error(szBuf);
}
//#ifdef USE_STREFLOP
// int res = streflop::Random<true, false, float>(min, max); // streflop
//#else
int diff= max-min;
int res= min + static_cast<int>((static_cast<float>(diff+1)*RandomGen::rand()) / m);
int res= min + static_cast<int>(static_cast<float>(diff+1)*RandomGen::rand() / m);
//#endif
assert(res>=min && res<=max);
if(res < min || res > max) {
char szBuf[1024]="";
sprintf(szBuf,"In [%s::%s Line: %d] res < min || res > max, min = %d, max = %d, res = %d",__FILE__,__FUNCTION__,__LINE__,min,max,res);
throw runtime_error(szBuf);
}
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] min = %d, max = %d, res = %d\n",__FILE__,__FUNCTION__,__LINE__,min,max,res);
@ -62,15 +74,25 @@ int RandomGen::randRange(int min, int max){
float RandomGen::randRange(float min, float max){
assert(min<=max);
if(min > max) {
char szBuf[1024]="";
sprintf(szBuf,"In [%s::%s Line: %d] min > max, min = %f, max = %f",__FILE__,__FUNCTION__,__LINE__,min,max);
throw runtime_error(szBuf);
}
//#ifdef USE_STREFLOP
// float res = streflop::Random<true, false, float>(min, max, randomState); // streflop
//#else
float rand01= static_cast<float>(RandomGen::rand())/(m-1);
float res= min+((max-min)*rand01);
float res= min+(max-min)*rand01;
//#endif
assert(res>=min && res<=max);
if(res < min || res > max) {
char szBuf[1024]="";
sprintf(szBuf,"In [%s::%s Line: %d] res < min || res > max, min = %f, max = %f, res = %f",__FILE__,__FUNCTION__,__LINE__,min,max,res);
throw runtime_error(szBuf);
}
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] min = %f, max = %f, res = %f\n",__FILE__,__FUNCTION__,__LINE__,min,max,res);

View File

@ -40,6 +40,7 @@ namespace Shared{ namespace Util{
// Init statics
std::map<SystemFlags::DebugType,SystemFlags::SystemFlagsType> SystemFlags::debugLogFileList;
int SystemFlags::lockFile = -1;
int SystemFlags::lockFileCountIndex = -1;
string SystemFlags::lockfilename = "";
CURL *SystemFlags::curl_handle = NULL;
//
@ -113,6 +114,7 @@ void SystemFlags::init() {
SystemFlags::debugLogFileList[SystemFlags::debugNetwork] = SystemFlags::SystemFlagsType(SystemFlags::debugNetwork);
SystemFlags::debugLogFileList[SystemFlags::debugPerformance] = SystemFlags::SystemFlagsType(SystemFlags::debugPerformance);
SystemFlags::debugLogFileList[SystemFlags::debugWorldSynch] = SystemFlags::SystemFlagsType(SystemFlags::debugWorldSynch);
SystemFlags::debugLogFileList[SystemFlags::debugUnitCommands] = SystemFlags::SystemFlagsType(SystemFlags::debugUnitCommands);
}
if(curl_handle == NULL) {
@ -166,6 +168,7 @@ void SystemFlags::Close() {
_close(SystemFlags::lockFile);
#endif
SystemFlags::lockFile = -1;
SystemFlags::lockFileCountIndex = -1;
if(SystemFlags::lockfilename != "") {
remove(SystemFlags::lockfilename.c_str());
@ -230,17 +233,9 @@ void SystemFlags::handleDebug(DebugType type, const char *fmt, ...) {
#ifndef WIN32
//SystemFlags::lockFile = open(lockfile.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IRUSR|S_IWUSR);
#ifdef S_IREAD
SystemFlags::lockFile = open(lockfile.c_str(), O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
#else
SystemFlags::lockFile = open(lockfile.c_str(), O_WRONLY | O_CREAT);
#endif
#else
#ifdef S_IREAD
SystemFlags::lockFile = _open(lockfile.c_str(), O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
#else
SystemFlags::lockFile = _open(lockfile.c_str(), O_WRONLY | O_CREAT);
#endif
#endif
if (SystemFlags::lockFile < 0 || acquire_file_lock(SystemFlags::lockFile) == false) {
string newlockfile = lockfile;
@ -249,17 +244,9 @@ void SystemFlags::handleDebug(DebugType type, const char *fmt, ...) {
newlockfile = lockfile + intToStr(idx);
//SystemFlags::lockFile = open(newlockfile.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IRUSR|S_IWUSR);
#ifndef WIN32
#ifdef S_IREAD
SystemFlags::lockFile = open(newlockfile.c_str(), O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
#else
SystemFlags::lockFile = open(newlockfile.c_str(), O_WRONLY | O_CREAT);
#endif
#else
#ifdef S_IREAD
SystemFlags::lockFile = _open(newlockfile.c_str(), O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
#else
SystemFlags::lockFile = _open(newlockfile.c_str(), O_WRONLY | O_CREAT);
#endif
#endif
if(SystemFlags::lockFile >= 0 && acquire_file_lock(SystemFlags::lockFile) == true) {
@ -267,12 +254,18 @@ void SystemFlags::handleDebug(DebugType type, const char *fmt, ...) {
}
}
SystemFlags::lockFileCountIndex = idx;
SystemFlags::lockfilename = newlockfile;
debugLog += intToStr(idx);
printf("Opening additional logfile [%s]\n",debugLog.c_str());
}
}
else if(SystemFlags::lockFileCountIndex > 0) {
debugLog += intToStr(SystemFlags::lockFileCountIndex);
printf("Opening additional logfile [%s]\n",debugLog.c_str());
}
if(currentDebugLog.fileStream == NULL) {
currentDebugLog.fileStream = new std::ofstream();