1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-10-31 00:07:39 +02:00

More changes for netcode/serialization

Removed not needed stuff
This commit is contained in:
Michał W. Urbańczyk
2008-07-25 17:28:28 +00:00
parent 358ab062eb
commit 0c139e72f5
62 changed files with 1102 additions and 5137 deletions

View File

@@ -1,9 +1,154 @@
#include <boost/foreach.hpp>
#include <boost/thread.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/bind.hpp>
#include "CGameHandler.h"
#include "../CGameState.h"
#include "../StartInfo.h"
#include "../map.h"
#include "../lib/NetPacks.h"
#include "../lib/Connection.h"
#include "../CLua.h"
#include "../hch/CObjectHandler.h"
#include "../hch/CTownHandler.h"
#include "../hch/CHeroHandler.h"
bool makingTurn;
boost::condition_variable cTurn;
boost::mutex mTurn;
boost::shared_mutex gsm;
void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
{
ui16 pom;
while(1)
{
c >> pom;
switch(pom)
{
case 100: //my interface end its turn
mTurn.lock();
makingTurn = false;
mTurn.unlock();
cTurn.notify_all();
break;
default:
throw std::exception("Not supported client message!");
break;
}
}
}
CGameHandler::CGameHandler(void)
{
gs = NULL;
}
CGameHandler::~CGameHandler(void)
{
delete gs;
}
void CGameHandler::init(StartInfo *si, int Seed)
{
Mapa *map = new Mapa(si->mapname);
gs = new CGameState();
gs->init(si,map,Seed);
}
int lowestSpeed(CGHeroInstance * chi)
{
std::map<int,std::pair<CCreature*,int> >::iterator i = chi->army.slots.begin();
int ret = (*i++).second.first->speed;
for (;i!=chi->army.slots.end();i++)
{
ret = min(ret,(*i).second.first->speed);
}
return ret;
}
int valMovePoints(CGHeroInstance * chi)
{
int ret = 1270+70*lowestSpeed(chi);
if (ret>2000)
ret=2000;
//TODO: additional bonuses (but they aren't currently stored in chi)
return ret;
}
void CGameHandler::newTurn()
{
//std::map<int, PlayerState>::iterator i = gs->players.begin() ;
gs->day++;
for ( std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++)
{
//handle heroes/////////////////////////////
for (unsigned j=0;j<(*i).second.heroes.size();j++)
{
(*i).second.heroes[j]->movement = valMovePoints((*i).second.heroes[j]);
}
//handle towns/////////////////////////////
for(unsigned j=0;j<i->second.towns.size();j++)
{
i->second.towns[j]->builded=0;
if(gs->getDate(1)==1) //first day of week
{
for(int k=0;k<CREATURES_PER_TOWN;k++) //creature growths
{
if(i->second.towns[j]->creatureDwelling(k))//there is dwelling (k-level)
i->second.towns[j]->strInfo.creatures[k]+=i->second.towns[j]->creatureGrowth(k);
}
}
if((gs->day>1) && i->first<PLAYER_LIMIT)
i->second.resources[6]+=i->second.towns[j]->dailyIncome();
}
}
for (std::set<CCPPObjectScript *>::iterator i=gs->cppscripts.begin();i!=gs->cppscripts.end();i++)
{
(*i)->newTurn();
}
}
void CGameHandler::run()
{
BOOST_FOREACH(CConnection *cc, conns)
{//init conn.
ui8 quantity, pom;
//ui32 seed;
(*cc) << gs->scenarioOps->mapname;// << gs->map->checksum << seed;
(*cc) >> quantity;
for(int i=0;i<quantity;i++)
{
(*cc) >> pom;
gsm.lock();
connections[pom] = cc;
gsm.unlock();
}
}
for(std::set<CConnection*>::iterator i = conns.begin(); i!=conns.end();i++)
{
std::set<int> pom;
for(std::map<int,CConnection*>::iterator j = connections.begin(); j!=connections.end();j++)
if(j->second == *i)
pom.insert(j->first);
boost::thread(boost::bind(&CGameHandler::handleConnection,this,pom,boost::ref(**i)));
}
while (1)
{
for(std::map<ui8,PlayerState>::iterator i = gs->players.begin(); i != gs->players.end(); i++)
{
if((i->second.towns.size()==0 && i->second.heroes.size()==0) || i->second.color<0) continue; //players has not towns/castle - loser
makingTurn = true;
*connections[i->first] << ui16(100) << i->first;
//wait till turn is done
boost::unique_lock<boost::mutex> lock(mTurn);
while(makingTurn)
{
cTurn.wait(lock);
}
}
}
}

View File

@@ -1,8 +1,23 @@
#pragma once
#include "../global.h"
#include <set>
class CVCMIServer;
class CGameState;
class CConnection;
struct StartInfo;
class CGameHandler
{
CGameState *gs;
CVCMIServer *s;
std::map<int,CConnection*> connections;
std::set<CConnection*> conns;
public:
CGameHandler(void);
~CGameHandler(void);
void init(StartInfo *si, int Seed);
void handleConnection(std::set<int> players, CConnection &c);
void run();
void newTurn();
friend class CVCMIServer;
};

View File

@@ -112,10 +112,15 @@
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
EnableFiberSafeOptimizations="true"
StringPooling="true"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
EnableFunctionLevelLinking="false"
WarningLevel="3"
DebugInformationFormat="3"
DebugInformationFormat="0"
DisableSpecificWarnings="4251"
/>
<Tool
Name="VCManagedResourceCompilerTool"
@@ -130,7 +135,7 @@
Name="VCLinkerTool"
AdditionalDependencies="VCMI_lib.lib zdll.lib"
AdditionalLibraryDirectories="G:\vcmt\repa\libs"
GenerateDebugInformation="true"
GenerateDebugInformation="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
@@ -184,6 +189,10 @@
RelativePath=".\CGameHandler.h"
>
</File>
<File
RelativePath=".\CVCMIServer.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"

View File

@@ -1,148 +1,143 @@
#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include "../global.h"
#include "../lib/Connection.h"
#include "../CGameState.h"
#include "zlib.h"
#include <boost/thread.hpp>
#include <tchar.h>
#include "CVCMIServer.h"
#include <boost/crc.hpp>
#include <boost/serialization/split_member.hpp>
#include "../StartInfo.h"
#include "../map.h"
#include "../hch/CLodHandler.h"
#include "../lib/VCMI_Lib.h"
#include "CGameHandler.h"
std::string NAME = NAME_VER + std::string(" (server)");
using boost::asio::ip::tcp;
using namespace boost;
using namespace boost::asio;
using namespace boost::asio::ip;
mutex smx1;
class CVCMIServer
CVCMIServer::CVCMIServer()
: io(new io_service()), acceptor(new tcp::acceptor(*io, tcp::endpoint(tcp::v4(), 3030)))
{
CGameState *gs;
tcp::acceptor acceptor;
std::map<int,CConnection*> connections;
std::set<CConnection*> conns;
ui32 seed;
public:
CVCMIServer(io_service& io_service)
: acceptor(io_service, tcp::endpoint(tcp::v4(), 3030))
}
CVCMIServer::~CVCMIServer()
{
delete io;
delete acceptor;
}
void CVCMIServer::newGame(CConnection &c)
{
CGameHandler gh;
boost::system::error_code error;
StartInfo *si = new StartInfo;
ui8 clients;
c >> clients; //how many clients should be connected - TODO: support more than one
c >> *si; //get start options
int problem;
#ifdef _MSC_VER
FILE *f;
problem = fopen_s(&f,si->mapname.c_str(),"r");
#else
FILE * f = fopen(si->mapname.c_str(),"r");
problem = !f;
#endif
if(problem)
{
start();
c << ui8(problem); //WRONG!
return;
}
void setUpConnection(CConnection *c, std::string mapname, si32 checksum)
else
{
ui8 quantity, pom;
(*c) << mapname << checksum << seed;
(*c) >> quantity;
for(int i=0;i<quantity;i++)
{
(*c) >> pom;
smx1.lock();
connections[pom] = c;
conns.insert(c);
smx1.unlock();
}
fclose(f);
c << ui8(0); //OK!
}
void newGame(CConnection &c)
gh.init(si,rand());
CConnection* cc; //tcp::socket * ss;
for(int i=0; i<clients; i++)
{
boost::system::error_code error;
StartInfo *si = new StartInfo;
ui8 clients;
std::string mapname;
c >> clients;
c >> mapname;
//getting map
gzFile map = gzopen(mapname.c_str(),"rb");
if(!map){ c << int8_t(1); return; }
std::vector<unsigned char> mapstr; int pom;
while((pom=gzgetc(map))>=0)
if(!i)
{
mapstr.push_back(pom);
cc=&c;
}
gzclose(map);
//map is decompressed
c << int8_t(0); //OK!
gs = new CGameState();
gs->scenarioOps = si;
c > *si; //get start options
boost::crc_32_type result;
result.process_bytes(&(*mapstr.begin()),mapstr.size());
int checksum = result.checksum();
std::cout << "Checksum:" << checksum << std::endl;
CConnection* cc; tcp::socket * ss;
for(int i=0; i<clients; i++)
else
{
if(!i)
tcp::socket * s = new tcp::socket(acceptor->io_service());
acceptor->accept(*s,error);
if(error) //retry
{
cc=&c;
std::cout<<"Cannot establish connection - retrying..." << std::endl;
i--;
continue;
}
else
{
tcp::socket * s = new tcp::socket(acceptor.io_service());
acceptor.accept(*s,error);
if(error) //retry
{
std::cout<<"Cannot establish connection - retrying..." << std::endl;
i--;
continue;
}
cc = new CConnection(s,NAME,std::cout);
}
setUpConnection(cc,mapname,checksum);
}
//TODO: wait for other connections
cc = new CConnection(s,NAME,std::cout);
}
gh.conns.insert(cc);
}
void start()
gh.run();
}
void CVCMIServer::start()
{
boost::system::error_code error;
std::cout<<"Listening for connections at port " << acceptor->local_endpoint().port() << std::endl;
tcp::socket * s = new tcp::socket(acceptor->io_service());
acceptor->accept(*s,error);
if (error)
{
srand ( time(NULL) );
seed = rand();
boost::system::error_code error;
std::cout<<"Listening for connections at port " << acceptor.local_endpoint().port() << std::endl;
tcp::socket * s = new tcp::socket(acceptor.io_service());
acceptor.accept(*s,error);
if (error)
std::cout<<"Got connection but there is an error " << std::endl;
return;
}
CConnection connection(s,NAME,std::cout);
std::cout<<"Got connection!" << std::endl;
while(1)
{
uint8_t mode;
connection >> mode;
switch (mode)
{
std::cout<<"Got connection but there is an error " << std::endl;
case 0:
connection.socket->close();
exit(0);
break;
case 1:
connection.socket->close();
return;
}
CConnection connection(s,NAME,std::cout);
std::cout<<"Got connection!" << std::endl;
while(1)
{
uint8_t mode;
connection >> mode;
switch (mode)
{
case 0:
connection.socket->close();
exit(0);
break;
case 1:
connection.socket->close();
return;
break;
case 2:
newGame(connection);
break;
}
break;
case 2:
newGame(connection);
break;
}
}
};
}
int _tmain(int argc, _TCHAR* argv[])
{
try
{
io_service io_service;
CVCMIServer server(io_service);
while(1)
server.start();
io_service.run();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
CLodHandler h3bmp;
h3bmp.init("Data\\H3bitmap.lod","Data");
initDLL(&h3bmp);
srand ( (unsigned int)time(NULL) );
try
{
io_service io_service;
CVCMIServer server;
while(1)
server.start();
io_service.run();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
catch(...)
{
;
}
return 0;
}