From 96a5bdaa5b25144a7cc327f43d4a9515eb5eff03 Mon Sep 17 00:00:00 2001 From: mateuszb Date: Wed, 28 Sep 2011 17:58:06 +0000 Subject: [PATCH] Programming challenge - further preparations. --- CCallback.cpp | 43 ----- CCallback.h | 5 +- Odpalarka/main.cpp | 3 +- VCMI_BattleAiHost/BattleCallback.cpp | 50 ++++++ VCMI_BattleAiHost/BattleCallback.h | 23 +++ VCMI_BattleAiHost/Client.cpp | 3 + VCMI_BattleAiHost/Client.h | 17 ++ VCMI_BattleAiHost/VCMI_BattleAiHost.vcxproj | 6 + VCMI_BattleAiHost/main.cpp | 24 ++- VCMI_VS10.sln | 13 -- b1.json | 6 +- lib/CDefObjInfoHandler.cpp | 185 ++++++++++---------- lib/CGameState.cpp | 5 +- lib/Connection.cpp | 1 + server/CVCMIServer.cpp | 36 ++-- 15 files changed, 244 insertions(+), 176 deletions(-) create mode 100644 VCMI_BattleAiHost/BattleCallback.cpp create mode 100644 VCMI_BattleAiHost/BattleCallback.h create mode 100644 VCMI_BattleAiHost/Client.cpp create mode 100644 VCMI_BattleAiHost/Client.h diff --git a/CCallback.cpp b/CCallback.cpp index 7dc4fa427..dbe2752ff 100644 --- a/CCallback.cpp +++ b/CCallback.cpp @@ -177,33 +177,6 @@ bool CCallback::buildBuilding(const CGTownInstance *town, si32 buildingID) return true; } -int CBattleCallback::battleMakeAction(BattleAction* action) -{ - assert(action->actionType == BattleAction::HERO_SPELL); - MakeCustomAction mca(*action); - sendRequest(&mca); - return 0; -} - -void CBattleCallback::sendRequest(const CPack* request) -{ - - //TODO should be part of CClient (client owns connection, not CB) - //but it would have to be very tricky cause template/serialization issues - if(waitTillRealize) - cl->waitingRequest.set(typeList.getTypeID(request)); - - cl->serv->sendPack(*request); - - if(waitTillRealize) - { - if(unlockGsWhenWaiting) - getGsMutex().unlock_shared(); - cl->waitingRequest.waitWhileTrue(); - if(unlockGsWhenWaiting) - getGsMutex().lock_shared(); - } -} void CCallback::swapGarrisonHero( const CGTownInstance *town ) { @@ -355,19 +328,3 @@ void CCallback::unregisterMyInterface() cl->battleints.erase(player); //TODO? should callback be disabled as well? } - -CBattleCallback::CBattleCallback(CGameState *GS, int Player, CClient *C ) -{ - gs = GS; - player = Player; - cl = C; -} - -bool CBattleCallback::battleMakeTacticAction( BattleAction * action ) -{ - assert(cl->gs->curB->tacticDistance); - MakeAction ma; - ma.ba = *action; - sendRequest(&ma); - return true; -} diff --git a/CCallback.h b/CCallback.h index 71e99c1cd..47fdfd279 100644 --- a/CCallback.h +++ b/CCallback.h @@ -87,16 +87,13 @@ struct CPack; class CBattleCallback : public IBattleCallback, public CBattleInfoCallback { -private: - CBattleCallback(CGameState *GS, int Player, CClient *C); - - protected: void sendRequest(const CPack *request); CClient *cl; //virtual bool hasAccess(int playerId) const; public: + CBattleCallback(CGameState *GS, int Player, CClient *C); int battleMakeAction(BattleAction* action) OVERRIDE;//for casting spells by hero - DO NOT use it for moving active stack bool battleMakeTacticAction(BattleAction * action) OVERRIDE; // performs tactic phase actions diff --git a/Odpalarka/main.cpp b/Odpalarka/main.cpp index 7d7d4bcfe..12e110ac7 100644 --- a/Odpalarka/main.cpp +++ b/Odpalarka/main.cpp @@ -8,7 +8,8 @@ int main() boost::thread tt(boost::bind(std::system, "VCMI_BattleAiHost.exe")); boost::thread ttt(boost::bind(std::system, "VCMI_BattleAiHost.exe")); boost::thread tttt(boost::bind(std::system, "VCMI_BattleAiHost.exe")); - boost::this_thread::sleep(boost::posix_time::seconds(5)); + //boost::this_thread::sleep(boost::posix_time::seconds(5)); + t.join(); return EXIT_SUCCESS; } \ No newline at end of file diff --git a/VCMI_BattleAiHost/BattleCallback.cpp b/VCMI_BattleAiHost/BattleCallback.cpp new file mode 100644 index 000000000..3c8d3fdb7 --- /dev/null +++ b/VCMI_BattleAiHost/BattleCallback.cpp @@ -0,0 +1,50 @@ +#include "BattleCallback.h" +#include "Client.h" +#include "../lib/CGameState.h" +#include "../lib/BattleState.h" +#include "../lib/NetPacks.h" +#include "../lib/Connection.h" + + +CBattleCallback::CBattleCallback(CGameState *GS, int Player, CClient *C ) +{ + gs = GS; + player = Player; + cl = C; +} + +bool CBattleCallback::battleMakeTacticAction( BattleAction * action ) +{ + assert(cl->gs->curB->tacticDistance); + MakeAction ma; + ma.ba = *action; + sendRequest(&ma); + return true; +} +int CBattleCallback::battleMakeAction(BattleAction* action) +{ + assert(action->actionType == BattleAction::HERO_SPELL); + MakeCustomAction mca(*action); + sendRequest(&mca); + return 0; +} + +void CBattleCallback::sendRequest(const CPack* request) +{ + + //TODO should be part of CClient (client owns connection, not CB) + //but it would have to be very tricky cause template/serialization issues +// if(waitTillRealize) +// cl->waitingRequest.set(typeList.getTypeID(request)); + + cl->serv->sendPack(*request); + +// if(waitTillRealize) +// { +// if(unlockGsWhenWaiting) +// getGsMutex().unlock_shared(); +// cl->waitingRequest.waitWhileTrue(); +// if(unlockGsWhenWaiting) +// getGsMutex().lock_shared(); +// } +} \ No newline at end of file diff --git a/VCMI_BattleAiHost/BattleCallback.h b/VCMI_BattleAiHost/BattleCallback.h new file mode 100644 index 000000000..2326ec23e --- /dev/null +++ b/VCMI_BattleAiHost/BattleCallback.h @@ -0,0 +1,23 @@ +#pragma once + +#include "../global.h" +#include "../CCallback.h" + +/*class CBattleCallback : public IBattleCallback, public CBattleInfoCallback +{ +private: + CBattleCallback(CGameState *GS, int Player, CClient *C); + + +protected: + void sendRequest(const CPack *request); + CClient *cl; + //virtual bool hasAccess(int playerId) const; + +public: + int battleMakeAction(BattleAction* action) OVERRIDE;//for casting spells by hero - DO NOT use it for moving active stack + bool battleMakeTacticAction(BattleAction * action) OVERRIDE; // performs tactic phase actions + + friend class CCallback; + friend class CClient; +};*/ \ No newline at end of file diff --git a/VCMI_BattleAiHost/Client.cpp b/VCMI_BattleAiHost/Client.cpp new file mode 100644 index 000000000..826dc79d3 --- /dev/null +++ b/VCMI_BattleAiHost/Client.cpp @@ -0,0 +1,3 @@ +#include "Client.h" + + diff --git a/VCMI_BattleAiHost/Client.h b/VCMI_BattleAiHost/Client.h new file mode 100644 index 000000000..f09856764 --- /dev/null +++ b/VCMI_BattleAiHost/Client.h @@ -0,0 +1,17 @@ +#pragma once + +class CGameState; +class CConnection; + +class CClient/* : public IGameCallback*/ +{ +public: + CGameState *gs; + CConnection *serv; + CClient() + { + + } + + //void commitPackage(CPackForClient *) OVERRIDE {}; +}; \ No newline at end of file diff --git a/VCMI_BattleAiHost/VCMI_BattleAiHost.vcxproj b/VCMI_BattleAiHost/VCMI_BattleAiHost.vcxproj index ea97ecb2d..040d392ab 100644 --- a/VCMI_BattleAiHost/VCMI_BattleAiHost.vcxproj +++ b/VCMI_BattleAiHost/VCMI_BattleAiHost.vcxproj @@ -132,8 +132,14 @@ + + + + + + diff --git a/VCMI_BattleAiHost/main.cpp b/VCMI_BattleAiHost/main.cpp index a18dbb7f9..6962ff65c 100644 --- a/VCMI_BattleAiHost/main.cpp +++ b/VCMI_BattleAiHost/main.cpp @@ -10,16 +10,21 @@ #else #include #endif + #include "../lib/CGameState.h" #include "../CCallback.h" #include "../lib/CGameInterface.h" #include +#include "Client.h" +#include "../lib/VCMI_Lib.h" using namespace std; using namespace boost; std::string NAME = NAME_VER + std::string(" DLL runner"); + + int main(int argc, char** argv) { int pid = -1; @@ -29,8 +34,9 @@ int main(int argc, char** argv) #else pid = getpid(); #endif + initDLL(console,logfile); - logfile = new std::ofstream(("VCMI_Server_log_" + boost::lexical_cast(pid) + ".txt").c_str()); + logfile = new std::ofstream(("VCMI_Runner_log_" + boost::lexical_cast(pid) + ".txt").c_str()); try { @@ -39,6 +45,7 @@ int main(int argc, char** argv) string port = "3030"; CConnection *serv = NULL; + int i = 3; while(!serv) { try @@ -50,6 +57,8 @@ int main(int argc, char** argv) { tlog1 << "\nCannot establish connection! Retrying within 2 seconds" << std::endl; boost::this_thread::sleep(boost::posix_time::seconds(2)); + if(!--i) + exit(0); } } @@ -58,17 +67,24 @@ int main(int argc, char** argv) string battleAIName; *serv >> si >> battleAIName >> color; assert(si.mode == StartInfo::DUEL); - tlog0 << format("Server wants us to run %s in battle %s as side %d") % battleAIName % si.mapname % color; + tlog0 << format("Server wants us to run %s in battle %s as side %d") % battleAIName % si.mapname % (int)color; CGameState *gs = new CGameState(); gs->init(&si, 0, 0); + tlog0 << "Gs inited\n"; + CClient cl; + cl.serv = serv; + cl.gs = gs; - CBattleCallback * cbc = new CBattleCallback(gs, color, this); + tlog0 << "Cl created\n"; + CBattleCallback * cbc = new CBattleCallback(gs, color, &cl); + tlog0 << "Cbc created\n"; CBattleGameInterface *ai = CDynLibHandler::getNewBattleAI(battleAIName); + tlog0 << "AI created\n"; ai->init(cbc); - + tlog0 << cbc->battleGetAllStacks().size() << std::endl; } catch(std::exception &e) { diff --git a/VCMI_VS10.sln b/VCMI_VS10.sln index 799575c6f..a3c015ae4 100644 --- a/VCMI_VS10.sln +++ b/VCMI_VS10.sln @@ -1,8 +1,6 @@  Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VCMI_client", "client\VCMI_client.vcxproj", "{8355EBA8-65C2-44A4-BC2D-78053E1BF2D6}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VCMI_lib", "lib\VCMI_lib.vcxproj", "{B952FFC5-3039-4DE1-9F08-90ACDA483D8F}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VCMI_server", "server\VCMI_server.vcxproj", "{8AF697C3-465E-4910-B31B-576A9ECDB309}" @@ -34,17 +32,6 @@ Global Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {8355EBA8-65C2-44A4-BC2D-78053E1BF2D6}.Debug|Win32.ActiveCfg = Debug|Win32 - {8355EBA8-65C2-44A4-BC2D-78053E1BF2D6}.Debug|Win32.Build.0 = Debug|Win32 - {8355EBA8-65C2-44A4-BC2D-78053E1BF2D6}.Debug|x64.ActiveCfg = Debug|x64 - {8355EBA8-65C2-44A4-BC2D-78053E1BF2D6}.Debug|x64.Build.0 = Debug|x64 - {8355EBA8-65C2-44A4-BC2D-78053E1BF2D6}.RD|Win32.ActiveCfg = RD|Win32 - {8355EBA8-65C2-44A4-BC2D-78053E1BF2D6}.RD|Win32.Build.0 = RD|Win32 - {8355EBA8-65C2-44A4-BC2D-78053E1BF2D6}.RD|x64.ActiveCfg = RD|x64 - {8355EBA8-65C2-44A4-BC2D-78053E1BF2D6}.RD|x64.Build.0 = RD|x64 - {8355EBA8-65C2-44A4-BC2D-78053E1BF2D6}.Release|Win32.ActiveCfg = RD|x64 - {8355EBA8-65C2-44A4-BC2D-78053E1BF2D6}.Release|x64.ActiveCfg = RD|x64 - {8355EBA8-65C2-44A4-BC2D-78053E1BF2D6}.Release|x64.Build.0 = RD|x64 {B952FFC5-3039-4DE1-9F08-90ACDA483D8F}.Debug|Win32.ActiveCfg = Debug|Win32 {B952FFC5-3039-4DE1-9F08-90ACDA483D8F}.Debug|Win32.Build.0 = Debug|Win32 {B952FFC5-3039-4DE1-9F08-90ACDA483D8F}.Debug|x64.ActiveCfg = Debug|x64 diff --git a/b1.json b/b1.json index 8646c090c..766f0c7ac 100644 --- a/b1.json +++ b/b1.json @@ -1,5 +1,5 @@ -[ - "terType" : 0, +{ + "terType" : 1, "bfieldType" : 0, "sides" : @@ -13,4 +13,4 @@ "army" : [[11, 41]] } ] -] \ No newline at end of file +} \ No newline at end of file diff --git a/lib/CDefObjInfoHandler.cpp b/lib/CDefObjInfoHandler.cpp index 04caee53f..c264c397e 100644 --- a/lib/CDefObjInfoHandler.cpp +++ b/lib/CDefObjInfoHandler.cpp @@ -51,98 +51,99 @@ void CGDefInfo::fetchInfoFromMSK() void CDefObjInfoHandler::load() { VLC->dobjinfo = this; - std::istringstream inp(bitmaph->getTextFile("ZOBJCTS.TXT")); - int objNumber; - inp>>objNumber; - std::string mapStr; - for(int hh=0; hh>nobj->name; - - std::transform(nobj->name.begin(), nobj->name.end(), nobj->name.begin(), (int(*)(int))toupper); - - for(int o=0; o<6; ++o) - { - nobj->blockMap[o] = 0xff; - nobj->visitMap[o] = 0x00; - nobj->coverageMap[o] = 0x00; - nobj->shadowCoverage[o] = 0x00; - } - inp>>mapStr; - std::reverse(mapStr.begin(), mapStr.end()); - for(int v=0; vblockMap[v/8] &= 255 - (128 >> (v%8)); - } - } - inp>>mapStr; - std::reverse(mapStr.begin(), mapStr.end()); - for(int v=0; vvisitMap[v/8] |= (128 >> (v%8)); - } - } - - for(int yy=0; yy<2; ++yy) //first - on which types of terrain object can be placed; - inp>>dump; //second -in which terrains' menus object in the editor will be available (?) - inp>>nobj->id; - inp>>nobj->subid; - inp>>nobj->type; - - nobj->visitDir = (8|16|32|64|128); //disabled visiting from the top - - if(nobj->type == 2 || nobj->type == 3 || nobj->type == 4 || nobj->type == 5) //creature, hero, artifact, resource - { - nobj->visitDir = 0xff; - } - else - { - static int visitableFromTop[] = {29, 82, 86, 11, 59, 8, 111,33,81,12,9,212,215,22}; //sea chest, flotsam, shipwreck survivor, buoy, ocean bottle, boat, whirlpool, garrison, scholar, campfire, borderguard, bordergate, questguard, corpse - for(int i=0; i < ARRAY_COUNT(visitableFromTop); i++) - { - if(visitableFromTop[i] == nobj->id) - { - nobj->visitDir = 0xff; - break; - } - } - } - inp >> nobj->printPriority; - - //coverageMap calculating - nobj->fetchInfoFromMSK(); - - - gobjs[nobj->id][nobj->subid] = nobj; - if(nobj->id==TOWNI_TYPE) - castles[nobj->subid]=nobj; - } - - if(vstd::contains(gobjs, 124)) - { - for (int i = 0; i < 8 ; i++) - { - - static const char *holeDefs[] = {"AVLHOLD0.DEF", "AVLHLDS0.DEF", "AVLHOLG0.DEF", "AVLHLSN0.DEF", - "AVLHOLS0.DEF", "AVLHOLR0.DEF", "AVLHOLX0.DEF", "AVLHOLL0.DEF"}; - - if(i) - { - gobjs[124][i] = new CGDefInfo(*gobjs[124][0]); - gobjs[124][i]->name = holeDefs[i]; - } - } - } - else - { - tlog1 << "No def info for holes!\n"; - } + return; +// std::istringstream inp(bitmaph->getTextFile("ZOBJCTS.TXT")); +// int objNumber; +// inp>>objNumber; +// std::string mapStr; +// for(int hh=0; hh>nobj->name; +// +// std::transform(nobj->name.begin(), nobj->name.end(), nobj->name.begin(), (int(*)(int))toupper); +// +// for(int o=0; o<6; ++o) +// { +// nobj->blockMap[o] = 0xff; +// nobj->visitMap[o] = 0x00; +// nobj->coverageMap[o] = 0x00; +// nobj->shadowCoverage[o] = 0x00; +// } +// inp>>mapStr; +// std::reverse(mapStr.begin(), mapStr.end()); +// for(int v=0; vblockMap[v/8] &= 255 - (128 >> (v%8)); +// } +// } +// inp>>mapStr; +// std::reverse(mapStr.begin(), mapStr.end()); +// for(int v=0; vvisitMap[v/8] |= (128 >> (v%8)); +// } +// } +// +// for(int yy=0; yy<2; ++yy) //first - on which types of terrain object can be placed; +// inp>>dump; //second -in which terrains' menus object in the editor will be available (?) +// inp>>nobj->id; +// inp>>nobj->subid; +// inp>>nobj->type; +// +// nobj->visitDir = (8|16|32|64|128); //disabled visiting from the top +// +// if(nobj->type == 2 || nobj->type == 3 || nobj->type == 4 || nobj->type == 5) //creature, hero, artifact, resource +// { +// nobj->visitDir = 0xff; +// } +// else +// { +// static int visitableFromTop[] = {29, 82, 86, 11, 59, 8, 111,33,81,12,9,212,215,22}; //sea chest, flotsam, shipwreck survivor, buoy, ocean bottle, boat, whirlpool, garrison, scholar, campfire, borderguard, bordergate, questguard, corpse +// for(int i=0; i < ARRAY_COUNT(visitableFromTop); i++) +// { +// if(visitableFromTop[i] == nobj->id) +// { +// nobj->visitDir = 0xff; +// break; +// } +// } +// } +// inp >> nobj->printPriority; +// +// //coverageMap calculating +// nobj->fetchInfoFromMSK(); +// +// +// gobjs[nobj->id][nobj->subid] = nobj; +// if(nobj->id==TOWNI_TYPE) +// castles[nobj->subid]=nobj; +// } +// +// if(vstd::contains(gobjs, 124)) +// { +// for (int i = 0; i < 8 ; i++) +// { +// +// static const char *holeDefs[] = {"AVLHOLD0.DEF", "AVLHLDS0.DEF", "AVLHOLG0.DEF", "AVLHLSN0.DEF", +// "AVLHOLS0.DEF", "AVLHOLR0.DEF", "AVLHOLX0.DEF", "AVLHOLL0.DEF"}; +// +// if(i) +// { +// gobjs[124][i] = new CGDefInfo(*gobjs[124][0]); +// gobjs[124][i]->name = holeDefs[i]; +// } +// } +// } +// else +// { +// tlog1 << "No def info for holes!\n"; +// } } CDefObjInfoHandler::~CDefObjInfoHandler() diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 390313879..ca1bb4d02 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -944,7 +944,7 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed ) { tlog0 << "Loading duel settings from JSON file: " << scenarioOps->mapname << std::endl; dp = DuelParameters::fromJSON(scenarioOps->mapname); - tlog0 << "JSON file has been succesfully read!\n"; + tlog0 << "JSON file has been successfully read!\n"; } else { @@ -971,16 +971,15 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed ) obj = h; h->subID = dp.sides[i].heroId; h->initHero(h->subID); + obj->initObj(); } else { CGCreature *c = new CGCreature(); armies[i] = obj = c; c->subID = 34; - } - obj->initObj(); obj->setOwner(i); for(int j = 0; j < ARRAY_COUNT(dp.sides[i].stacks); j++) diff --git a/lib/Connection.cpp b/lib/Connection.cpp index bb6ee7ef7..9a51535a8 100644 --- a/lib/Connection.cpp +++ b/lib/Connection.cpp @@ -121,6 +121,7 @@ CConnection::CConnection(std::string host, std::string port, std::string Name) else { tlog1 << "Problem with connecting: " << std::endl << error << std::endl; + tlog1 << error.message() << std::endl; } endpoint_iterator++; } diff --git a/server/CVCMIServer.cpp b/server/CVCMIServer.cpp index 00f50ce5f..f548d21b8 100644 --- a/server/CVCMIServer.cpp +++ b/server/CVCMIServer.cpp @@ -501,12 +501,23 @@ void CVCMIServer::loadGame() void CVCMIServer::startDuel(const std::string &battle, const std::string &leftAI, const std::string &rightAI) { //we need three connections - CConnection *conns[3] = {0}; - for (int i = 0; i < 3 ; i++) + CConnection *conns[1] = {0}; + for (int i = 0; i < 1 ; i++) { boost::system::error_code error; + + + //boost::system::error_code error; + tlog0<<"Listening for connections at port " << acceptor->local_endpoint().port() << std::endl; tcp::socket * s = new tcp::socket(acceptor->get_io_service()); - acceptor->accept(*s, error); + boost::thread acc(boost::bind(vaccept,acceptor,s,&error)); +// sr->setToTrueAndNotify(); +// delete mr; + + acc.join(); + + //tcp::socket * s = new tcp::socket(acceptor->get_io_service()); + //acceptor->accept(*s, error); if (error) { @@ -534,8 +545,14 @@ void CVCMIServer::startDuel(const std::string &battle, const std::string &leftAI c->addStdVecItems(gh->gs, VLC); gh->connections[gh->conns.size()] = c; gh->conns.insert(c); + *c << si; } - + + *gh->connections[0] << leftAI << ui8(0); + //*gh->connections[1] << rightAI << ui8(1); + //*gh->connections[2] << std::string() << ui8(254); + + gh->runBattle(); delNull(gh); @@ -552,15 +569,8 @@ int main(int argc, char** argv) logfile = new std::ofstream("VCMI_Server_log.txt"); console = new CConsoleHandler; //boost::thread t(boost::bind(&CConsoleHandler::run,::console)); - if(argc > 1) - { -#ifdef _MSC_VER - port = _tstoi(argv[1]); -#else - port = _ttoi(argv[1]); -#endif - } - tlog0 << "Port " << port << " will be used." << std::endl; + + initDLL(console,logfile); srand ( (unsigned int)time(NULL) ); try