mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-19 21:10:12 +02:00
Battle is run and result is stored.
This commit is contained in:
parent
96a5bdaa5b
commit
131b9d6e1a
@ -1,3 +1,128 @@
|
|||||||
#include "Client.h"
|
#include "Client.h"
|
||||||
|
#include "../lib/Connection.h"
|
||||||
|
#include "../CThreadHelper.h"
|
||||||
|
#include "../lib/CGameState.h"
|
||||||
|
#include "../lib/BattleAction.h"
|
||||||
|
#include "../lib/CGameInterface.h"
|
||||||
|
#include "CheckTime.h"
|
||||||
|
|
||||||
|
#define NOT_LIB
|
||||||
|
#include "../lib/RegisterTypes.cpp"
|
||||||
|
|
||||||
|
template <typename T> class CApplyOnCL;
|
||||||
|
|
||||||
|
class CBaseForCLApply
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void applyOnClAfter(CClient *cl, void *pack) const =0;
|
||||||
|
virtual void applyOnClBefore(CClient *cl, void *pack) const =0;
|
||||||
|
virtual ~CBaseForCLApply(){}
|
||||||
|
|
||||||
|
template<typename U> static CBaseForCLApply *getApplier(const U * t=NULL)
|
||||||
|
{
|
||||||
|
return new CApplyOnCL<U>;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T> class CApplyOnCL : public CBaseForCLApply
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void applyOnClAfter(CClient *cl, void *pack) const
|
||||||
|
{
|
||||||
|
T *ptr = static_cast<T*>(pack);
|
||||||
|
ptr->applyCl(cl);
|
||||||
|
}
|
||||||
|
void applyOnClBefore(CClient *cl, void *pack) const
|
||||||
|
{
|
||||||
|
T *ptr = static_cast<T*>(pack);
|
||||||
|
ptr->applyFirstCl(cl);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static CApplier<CBaseForCLApply> *applier = NULL;
|
||||||
|
|
||||||
|
void CClient::run()
|
||||||
|
{
|
||||||
|
setThreadName(-1, "CClient::run");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CPack *pack = NULL;
|
||||||
|
while(!terminate)
|
||||||
|
{
|
||||||
|
pack = serv->retreivePack(); //get the package from the server
|
||||||
|
|
||||||
|
if (terminate)
|
||||||
|
{
|
||||||
|
delete pack;
|
||||||
|
pack = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePack(pack);
|
||||||
|
pack = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
tlog3 << "Lost connection to server, ending listening thread!\n";
|
||||||
|
tlog1 << e.what() << std::endl;
|
||||||
|
if(!terminate) //rethrow (-> boom!) only if closing connection was unexpected
|
||||||
|
{
|
||||||
|
tlog1 << "Something wrong, lost connection while game is still ongoing...\n";
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CClient::handlePack( CPack * pack )
|
||||||
|
{
|
||||||
|
CBaseForCLApply *apply = applier->apps[typeList.getTypeID(pack)]; //find the applier
|
||||||
|
if(apply)
|
||||||
|
{
|
||||||
|
apply->applyOnClBefore(this,pack);
|
||||||
|
tlog5 << "\tMade first apply on cl\n";
|
||||||
|
gs->apply(pack);
|
||||||
|
tlog5 << "\tApplied on gs\n";
|
||||||
|
apply->applyOnClAfter(this,pack);
|
||||||
|
tlog5 << "\tMade second apply on cl\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tlog1 << "Message cannot be applied, cannot find applier! TypeID " << typeList.getTypeID(pack) << std::endl;
|
||||||
|
}
|
||||||
|
delete pack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CClient::requestMoveFromAI(const CStack *s)
|
||||||
|
{
|
||||||
|
boost::thread(&CClient::requestMoveFromAIWorker, this, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CClient::requestMoveFromAIWorker(const CStack *s)
|
||||||
|
{
|
||||||
|
BattleAction ba;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CheckTime timer("AI was thinking for ");
|
||||||
|
ba = ai->activeStack(s);
|
||||||
|
MakeAction temp_action(ba);
|
||||||
|
*serv << &temp_action;
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
tlog0 << "AI thrown an exception!\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CClient::CClient()
|
||||||
|
{
|
||||||
|
gs = NULL;
|
||||||
|
serv = NULL;
|
||||||
|
ai = NULL;
|
||||||
|
curbaction = NULL;
|
||||||
|
terminate = false;
|
||||||
|
|
||||||
|
applier = new CApplier<CBaseForCLApply>;
|
||||||
|
registerTypes2(*applier);
|
||||||
|
}
|
@ -1,17 +1,25 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "../global.h"
|
||||||
class CGameState;
|
class CGameState;
|
||||||
class CConnection;
|
class CConnection;
|
||||||
|
struct CPack;
|
||||||
|
class CBattleGameInterface;
|
||||||
|
struct BattleAction;
|
||||||
|
class CStack;
|
||||||
|
|
||||||
class CClient/* : public IGameCallback*/
|
class CClient/* : public IGameCallback*/
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
bool terminate;
|
||||||
|
BattleAction *curbaction;
|
||||||
CGameState *gs;
|
CGameState *gs;
|
||||||
CConnection *serv;
|
CConnection *serv;
|
||||||
CClient()
|
CBattleGameInterface *ai;
|
||||||
{
|
|
||||||
|
|
||||||
}
|
CClient();
|
||||||
|
|
||||||
//void commitPackage(CPackForClient *) OVERRIDE {};
|
void run();
|
||||||
|
void handlePack( CPack * pack ); //applies the given pack and deletes it
|
||||||
|
void requestMoveFromAI(const CStack *s);
|
||||||
|
void requestMoveFromAIWorker(const CStack *s);
|
||||||
};
|
};
|
@ -135,9 +135,11 @@
|
|||||||
<ClCompile Include="BattleCallback.cpp" />
|
<ClCompile Include="BattleCallback.cpp" />
|
||||||
<ClCompile Include="Client.cpp" />
|
<ClCompile Include="Client.cpp" />
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
|
<ClCompile Include="NetPacksRunner.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="BattleCallback.h" />
|
<ClInclude Include="BattleCallback.h" />
|
||||||
|
<ClInclude Include="CheckTime.h" />
|
||||||
<ClInclude Include="Client.h" />
|
<ClInclude Include="Client.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
@ -81,10 +81,17 @@ int main(int argc, char** argv)
|
|||||||
tlog0 << "Cl created\n";
|
tlog0 << "Cl created\n";
|
||||||
CBattleCallback * cbc = new CBattleCallback(gs, color, &cl);
|
CBattleCallback * cbc = new CBattleCallback(gs, color, &cl);
|
||||||
tlog0 << "Cbc created\n";
|
tlog0 << "Cbc created\n";
|
||||||
CBattleGameInterface *ai = CDynLibHandler::getNewBattleAI(battleAIName);
|
if(battleAIName.size())
|
||||||
|
{
|
||||||
|
cl.ai = CDynLibHandler::getNewBattleAI(battleAIName);
|
||||||
|
cl.ai->playerID = color;
|
||||||
tlog0 << "AI created\n";
|
tlog0 << "AI created\n";
|
||||||
ai->init(cbc);
|
cl.ai->init(cbc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tlog0 << "Not loading AI, only simulation will be run\n";
|
||||||
tlog0 << cbc->battleGetAllStacks().size() << std::endl;
|
tlog0 << cbc->battleGetAllStacks().size() << std::endl;
|
||||||
|
cl.run();
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
{
|
{
|
||||||
|
@ -240,7 +240,7 @@ CPack * CConnection::retreivePack()
|
|||||||
boost::unique_lock<boost::mutex> lock(*rmx);
|
boost::unique_lock<boost::mutex> lock(*rmx);
|
||||||
tlog5 << "Listening... ";
|
tlog5 << "Listening... ";
|
||||||
*this >> ret;
|
*this >> ret;
|
||||||
tlog5 << "\treceived server message of type " << typeid(*ret).name() << std::endl;
|
tlog5 << "\treceived message of type " << typeid(*ret).name() << std::endl;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -462,6 +462,16 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
|
|||||||
{
|
{
|
||||||
CSaveFile resultFile("result.vdrst");
|
CSaveFile resultFile("result.vdrst");
|
||||||
resultFile << *battleResult.data;
|
resultFile << *battleResult.data;
|
||||||
|
|
||||||
|
int casualtiesPoints = 0;
|
||||||
|
tlog0 << boost::format("Winner side %d\nWinner casualties:\n") % battleResult.data->winner;
|
||||||
|
for(std::map<ui32,si32>::const_iterator i = battleResult.data->casualties[battleResult.data->winner].begin(); i != battleResult.data->casualties[battleResult.data->winner].end(); i++)
|
||||||
|
{
|
||||||
|
const CCreature *c = VLC->creh->creatures[i->first];
|
||||||
|
tlog0 << boost::format("\t* %d of %s\n") % i->second % c->namePl;
|
||||||
|
casualtiesPoints = c->AIValue * i->second;
|
||||||
|
}
|
||||||
|
tlog0 << boost::format("Total causalties points: %d\n") % casualtiesPoints;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,17 +636,12 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
|||||||
{
|
{
|
||||||
while(1)//server should never shut connection first //was: while(!end2)
|
while(1)//server should never shut connection first //was: while(!end2)
|
||||||
{
|
{
|
||||||
{
|
pack = c.retreivePack();
|
||||||
boost::unique_lock<boost::mutex> lock(*c.rmx);
|
|
||||||
c >> pack; //get the package
|
|
||||||
tlog5 << "Received client message of type " << typeid(*pack).name() << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
int packType = typeList.getTypeID(pack); //get the id of type
|
int packType = typeList.getTypeID(pack); //get the id of type
|
||||||
CBaseForGHApply *apply = applier->apps[packType]; //and appropriae applier object
|
CBaseForGHApply *apply = applier->apps[packType]; //and appropriae applier object
|
||||||
if(packType != typeList.getTypeID<QueryReply>() &&
|
if(packType != typeList.getTypeID<QueryReply>()
|
||||||
(packType != typeList.getTypeID<ArrangeStacks>() || !isAllowedArrangePack((ArrangeStacks*)pack)) && // for dialogs like garrison
|
&&(packType != typeList.getTypeID<ArrangeStacks>() || !isAllowedArrangePack((ArrangeStacks*)pack)) // for dialogs like garrison
|
||||||
states[getCurrentPlayer()].queries.size())
|
&& vstd::contains(states.players, getCurrentPlayer()) && states[getCurrentPlayer()].queries.size())
|
||||||
{
|
{
|
||||||
complain("Answer the query before attempting any further actions!");
|
complain("Answer the query before attempting any further actions!");
|
||||||
PackageApplied applied;
|
PackageApplied applied;
|
||||||
@ -1998,12 +2003,6 @@ void CGameHandler::save( const std::string &fname )
|
|||||||
void CGameHandler::close()
|
void CGameHandler::close()
|
||||||
{
|
{
|
||||||
tlog0 << "We have been requested to close.\n";
|
tlog0 << "We have been requested to close.\n";
|
||||||
|
|
||||||
if(gs->initialOpts->mode == StartInfo::DUEL)
|
|
||||||
{
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//BOOST_FOREACH(CConnection *cc, conns)
|
//BOOST_FOREACH(CConnection *cc, conns)
|
||||||
// if(cc && cc->socket && cc->socket->is_open())
|
// if(cc && cc->socket && cc->socket->is_open())
|
||||||
// cc->socket->close();
|
// cc->socket->close();
|
||||||
|
@ -501,23 +501,14 @@ void CVCMIServer::loadGame()
|
|||||||
void CVCMIServer::startDuel(const std::string &battle, const std::string &leftAI, const std::string &rightAI)
|
void CVCMIServer::startDuel(const std::string &battle, const std::string &leftAI, const std::string &rightAI)
|
||||||
{
|
{
|
||||||
//we need three connections
|
//we need three connections
|
||||||
CConnection *conns[1] = {0};
|
CConnection *conns[3] = {0};
|
||||||
for (int i = 0; i < 1 ; i++)
|
for (int i = 0; i < 3 ; i++)
|
||||||
{
|
{
|
||||||
boost::system::error_code error;
|
boost::system::error_code error;
|
||||||
|
|
||||||
|
|
||||||
//boost::system::error_code error;
|
|
||||||
tlog0<<"Listening for connections at port " << acceptor->local_endpoint().port() << std::endl;
|
tlog0<<"Listening for connections at port " << acceptor->local_endpoint().port() << std::endl;
|
||||||
tcp::socket * s = new tcp::socket(acceptor->get_io_service());
|
tcp::socket * s = new tcp::socket(acceptor->get_io_service());
|
||||||
boost::thread acc(boost::bind(vaccept,acceptor,s,&error));
|
acceptor->accept(*s, error);
|
||||||
// sr->setToTrueAndNotify();
|
|
||||||
// delete mr;
|
|
||||||
|
|
||||||
acc.join();
|
|
||||||
|
|
||||||
//tcp::socket * s = new tcp::socket(acceptor->get_io_service());
|
|
||||||
//acceptor->accept(*s, error);
|
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
@ -537,26 +528,39 @@ void CVCMIServer::startDuel(const std::string &battle, const std::string &leftAI
|
|||||||
si.mode = StartInfo::DUEL;
|
si.mode = StartInfo::DUEL;
|
||||||
si.mapname = battle;
|
si.mapname = battle;
|
||||||
|
|
||||||
|
|
||||||
|
tlog0 << "Preparing gh!\n";
|
||||||
CGameHandler *gh = new CGameHandler();
|
CGameHandler *gh = new CGameHandler();
|
||||||
gh->init(&si,std::time(NULL));
|
gh->init(&si,std::time(NULL));
|
||||||
|
|
||||||
BOOST_FOREACH(CConnection *c, conns)
|
BOOST_FOREACH(CConnection *c, conns)
|
||||||
{
|
{
|
||||||
|
ui8 player = gh->conns.size();
|
||||||
|
tlog0 << boost::format("Preparing connection %d!\n") % (int)player;
|
||||||
c->addStdVecItems(gh->gs, VLC);
|
c->addStdVecItems(gh->gs, VLC);
|
||||||
gh->connections[gh->conns.size()] = c;
|
gh->connections[player] = c;
|
||||||
gh->conns.insert(c);
|
gh->conns.insert(c);
|
||||||
|
gh->states.addPlayer(player);
|
||||||
*c << si;
|
*c << si;
|
||||||
|
|
||||||
|
std::set<int> pom;
|
||||||
|
pom.insert(player);
|
||||||
|
boost::thread(boost::bind(&CGameHandler::handleConnection,gh,pom,boost::ref(*c)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tlog0 << boost::format("Sending start info to connections!\n");
|
||||||
*gh->connections[0] << leftAI << ui8(0);
|
*gh->connections[0] << leftAI << ui8(0);
|
||||||
//*gh->connections[1] << rightAI << ui8(1);
|
*gh->connections[1] << rightAI << ui8(1);
|
||||||
//*gh->connections[2] << std::string() << ui8(254);
|
*gh->connections[2] << std::string() << ui8(254);
|
||||||
|
|
||||||
|
|
||||||
|
tlog0 << "Starting battle!\n";
|
||||||
gh->runBattle();
|
gh->runBattle();
|
||||||
|
tlog0 << "Battle over!\n";
|
||||||
delNull(gh);
|
delNull(gh);
|
||||||
|
tlog0 << "Removed gh!\n";
|
||||||
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
|
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
|
||||||
|
tlog0 << "Dying...\n";
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,17 @@
|
|||||||
bin_PROGRAMS = odpalarka
|
bin_PROGRAMS = vcmiserver
|
||||||
|
|
||||||
odpalarka_LDADD = $(top_builddir)/lib/libvcmi.la
|
vcmiserver_LDADD = $(top_builddir)/lib/libvcmi.la
|
||||||
odpalarka_CXXFLAGS = @SDL_CXXFLAGS@
|
vcmiserver_CXXFLAGS = @SDL_CXXFLAGS@
|
||||||
odpalarka_LDFLAGS = -L$(top_builddir)/lib
|
vcmiserver_LDFLAGS = -L$(top_builddir)/lib
|
||||||
odpalarka_SOURCES = main.cpp
|
vcmiserver_SOURCES = \
|
||||||
|
../CConsoleHandler.cpp \
|
||||||
|
../CConsoleHandler.h \
|
||||||
|
../CThreadHelper.cpp \
|
||||||
|
../CThreadHelper.h \
|
||||||
|
CGameHandler.cpp \
|
||||||
|
CGameHandler.h \
|
||||||
|
CVCMIServer.cpp \
|
||||||
|
CVCMIServer.h \
|
||||||
|
NetPacksServer.cpp \
|
||||||
|
stdafx.cpp \
|
||||||
|
stdafx.h
|
||||||
|
Loading…
x
Reference in New Issue
Block a user