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:
		| @@ -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); | ||||
| 			} | ||||
|  | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -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; | ||||
| }; | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user