mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-17 20:58:07 +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 "../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
|
||||
|
||||
#include "../global.h"
|
||||
class CGameState;
|
||||
class CConnection;
|
||||
struct CPack;
|
||||
class CBattleGameInterface;
|
||||
struct BattleAction;
|
||||
class CStack;
|
||||
|
||||
class CClient/* : public IGameCallback*/
|
||||
{
|
||||
public:
|
||||
bool terminate;
|
||||
BattleAction *curbaction;
|
||||
CGameState *gs;
|
||||
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="Client.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="NetPacksRunner.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="BattleCallback.h" />
|
||||
<ClInclude Include="CheckTime.h" />
|
||||
<ClInclude Include="Client.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
@ -81,10 +81,17 @@ int main(int argc, char** argv)
|
||||
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);
|
||||
if(battleAIName.size())
|
||||
{
|
||||
cl.ai = CDynLibHandler::getNewBattleAI(battleAIName);
|
||||
cl.ai->playerID = color;
|
||||
tlog0 << "AI created\n";
|
||||
cl.ai->init(cbc);
|
||||
}
|
||||
else
|
||||
tlog0 << "Not loading AI, only simulation will be run\n";
|
||||
tlog0 << cbc->battleGetAllStacks().size() << std::endl;
|
||||
cl.run();
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
|
@ -240,7 +240,7 @@ CPack * CConnection::retreivePack()
|
||||
boost::unique_lock<boost::mutex> lock(*rmx);
|
||||
tlog5 << "Listening... ";
|
||||
*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;
|
||||
}
|
||||
|
||||
|
@ -462,6 +462,16 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
|
||||
{
|
||||
CSaveFile resultFile("result.vdrst");
|
||||
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;
|
||||
}
|
||||
|
||||
@ -626,17 +636,12 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
||||
{
|
||||
while(1)//server should never shut connection first //was: while(!end2)
|
||||
{
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(*c.rmx);
|
||||
c >> pack; //get the package
|
||||
tlog5 << "Received client message of type " << typeid(*pack).name() << std::endl;
|
||||
}
|
||||
|
||||
pack = c.retreivePack();
|
||||
int packType = typeList.getTypeID(pack); //get the id of type
|
||||
CBaseForGHApply *apply = applier->apps[packType]; //and appropriae applier object
|
||||
if(packType != typeList.getTypeID<QueryReply>() &&
|
||||
(packType != typeList.getTypeID<ArrangeStacks>() || !isAllowedArrangePack((ArrangeStacks*)pack)) && // for dialogs like garrison
|
||||
states[getCurrentPlayer()].queries.size())
|
||||
if(packType != typeList.getTypeID<QueryReply>()
|
||||
&&(packType != typeList.getTypeID<ArrangeStacks>() || !isAllowedArrangePack((ArrangeStacks*)pack)) // for dialogs like garrison
|
||||
&& vstd::contains(states.players, getCurrentPlayer()) && states[getCurrentPlayer()].queries.size())
|
||||
{
|
||||
complain("Answer the query before attempting any further actions!");
|
||||
PackageApplied applied;
|
||||
@ -1997,13 +2002,7 @@ void CGameHandler::save( const std::string &fname )
|
||||
|
||||
void CGameHandler::close()
|
||||
{
|
||||
tlog0 << "We have been requested to close.\n";
|
||||
|
||||
if(gs->initialOpts->mode == StartInfo::DUEL)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
|
||||
tlog0 << "We have been requested to close.\n";
|
||||
//BOOST_FOREACH(CConnection *cc, conns)
|
||||
// if(cc && cc->socket && cc->socket->is_open())
|
||||
// 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)
|
||||
{
|
||||
//we need three connections
|
||||
CConnection *conns[1] = {0};
|
||||
for (int i = 0; i < 1 ; i++)
|
||||
CConnection *conns[3] = {0};
|
||||
for (int i = 0; i < 3 ; 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());
|
||||
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);
|
||||
acceptor->accept(*s, error);
|
||||
|
||||
if (error)
|
||||
{
|
||||
@ -537,26 +528,39 @@ void CVCMIServer::startDuel(const std::string &battle, const std::string &leftAI
|
||||
si.mode = StartInfo::DUEL;
|
||||
si.mapname = battle;
|
||||
|
||||
|
||||
tlog0 << "Preparing gh!\n";
|
||||
CGameHandler *gh = new CGameHandler();
|
||||
gh->init(&si,std::time(NULL));
|
||||
|
||||
BOOST_FOREACH(CConnection *c, conns)
|
||||
{
|
||||
ui8 player = gh->conns.size();
|
||||
tlog0 << boost::format("Preparing connection %d!\n") % (int)player;
|
||||
c->addStdVecItems(gh->gs, VLC);
|
||||
gh->connections[gh->conns.size()] = c;
|
||||
gh->connections[player] = c;
|
||||
gh->conns.insert(c);
|
||||
gh->states.addPlayer(player);
|
||||
*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[1] << rightAI << ui8(1);
|
||||
//*gh->connections[2] << std::string() << ui8(254);
|
||||
*gh->connections[1] << rightAI << ui8(1);
|
||||
*gh->connections[2] << std::string() << ui8(254);
|
||||
|
||||
|
||||
tlog0 << "Starting battle!\n";
|
||||
gh->runBattle();
|
||||
|
||||
tlog0 << "Battle over!\n";
|
||||
delNull(gh);
|
||||
tlog0 << "Removed gh!\n";
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
|
||||
tlog0 << "Dying...\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,17 @@
|
||||
bin_PROGRAMS = odpalarka
|
||||
|
||||
odpalarka_LDADD = $(top_builddir)/lib/libvcmi.la
|
||||
odpalarka_CXXFLAGS = @SDL_CXXFLAGS@
|
||||
odpalarka_LDFLAGS = -L$(top_builddir)/lib
|
||||
odpalarka_SOURCES = main.cpp
|
||||
bin_PROGRAMS = vcmiserver
|
||||
|
||||
vcmiserver_LDADD = $(top_builddir)/lib/libvcmi.la
|
||||
vcmiserver_CXXFLAGS = @SDL_CXXFLAGS@
|
||||
vcmiserver_LDFLAGS = -L$(top_builddir)/lib
|
||||
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