1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-06-23 00:28:08 +02:00

should be fine...

This commit is contained in:
Michał W. Urbańczyk
2009-03-07 15:54:12 +00:00
parent e9ebc7de5b
commit 5ebb54ec59
8 changed files with 121 additions and 69 deletions

View File

@ -117,11 +117,15 @@ bool CCallback::moveHero(int ID, CPath * path, int idtype, int pathType)
while(std::find_if(mess.res->begin(),mess.res->end(),&isType<501>) == mess.res->end()) while(std::find_if(mess.res->begin(),mess.res->end(),&isType<501>) == mess.res->end())
mess.cv->wait(lock); mess.cv->wait(lock);
std::set<CPack*>::iterator itr = std::find_if(mess.res->begin(),mess.res->end(),&isType<501>); std::set<CPack*>::iterator itr = std::find_if(mess.res->begin(),mess.res->end(),&isType<501>);
TryMoveHero tmh = *static_cast<TryMoveHero*>(*itr); TryMoveHero *tmh = static_cast<TryMoveHero*>(*itr);
mess.res->erase(itr); mess.res->erase(itr);
if(!tmh.result) if(!tmh->result)
{
delete tmh;
return false; return false;
} }
delete tmh;
}
} }
return true; return true;
} }

View File

@ -59,11 +59,11 @@ public:
} }
template<typename T> void registerType(const T * t=NULL) template<typename T> void registerType(const T * t=NULL)
{ {
ui16 ID = typeList.registerType(&typeid(T)); ui16 ID = typeList.registerType(t);
apps[ID] = new CApplyOnGS<T>; apps[ID] = new CApplyOnGS<T>;
} }
} applier; } *applier = NULL;
std::string DLL_EXPORT toString(MetaString &ms) std::string DLL_EXPORT toString(MetaString &ms)
{ {
@ -806,6 +806,7 @@ CGameState::CGameState()
map = NULL; map = NULL;
curB = NULL; curB = NULL;
scenarioOps = NULL; scenarioOps = NULL;
applier = new CGSApplier;
} }
CGameState::~CGameState() CGameState::~CGameState()
{ {
@ -813,6 +814,7 @@ CGameState::~CGameState()
delete map; delete map;
delete curB; delete curB;
delete scenarioOps; delete scenarioOps;
delete applier;
} }
void CGameState::init(StartInfo * si, Mapa * map, int Seed) void CGameState::init(StartInfo * si, Mapa * map, int Seed)
{ {
@ -1471,7 +1473,7 @@ int CGameState::canBuildStructure( const CGTownInstance *t, int ID )
void CGameState::apply(CPack *pack) void CGameState::apply(CPack *pack)
{ {
applier.apps[typeList.getTypeID(pack)]->applyOnGS(this,pack); applier->apps[typeList.getTypeID(pack)]->applyOnGS(this,pack);
} }
int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting) int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting)

View File

@ -64,14 +64,15 @@ public:
} }
template<typename T> void registerType(const T * t=NULL) template<typename T> void registerType(const T * t=NULL)
{ {
ui16 ID = typeList.registerType(&typeid(T)); ui16 ID = typeList.registerType(t);
apps[ID] = new CApplyOnCL<T>; apps[ID] = new CApplyOnCL<T>;
} }
} applier; } *applier = NULL;
void CClient::init() void CClient::init()
{ {
applier = new CCLApplier;
IObjectInterface::cb = this; IObjectInterface::cb = this;
serv = NULL; serv = NULL;
gs = NULL; gs = NULL;
@ -93,6 +94,7 @@ CClient::CClient(CConnection *con, StartInfo *si)
} }
CClient::~CClient(void) CClient::~CClient(void)
{ {
delete applier;
delete shared; delete shared;
} }
void CClient::waitForMoveAndSend(int color) void CClient::waitForMoveAndSend(int color)
@ -108,18 +110,24 @@ void CClient::waitForMoveAndSend(int color)
void CClient::run() void CClient::run()
{ {
CPack *pack; CPack *pack;
try while(1)
{ {
*serv >> pack; *serv >> pack;
CBaseForCLApply *apply = applier.apps[typeList.getTypeID(pack)]; CBaseForCLApply *apply = applier->apps[typeList.getTypeID(pack)];
if(apply)
{
apply->applyOnClBefore(this,pack); apply->applyOnClBefore(this,pack);
gs->apply(pack); gs->apply(pack);
apply->applyOnClAfter(this,pack); apply->applyOnClAfter(this,pack);
tlog5 << "Applied server message of type " << typeid(*pack).name() << std::endl;
}
else
{
tlog1 << "Unknown server message. Type: " << pack->type << ". Typeinfo: " << typeid(*pack).name() << std::endl;
}
delete pack; delete pack;
pack = NULL; pack = NULL;
} HANDLE_EXCEPTION }
} }
void CClient::close() void CClient::close()

View File

@ -26,6 +26,8 @@ CTypeList typeList;
void CConnection::init() void CConnection::init()
{ {
registerTypes(static_cast<CISer<CConnection>&>(*this));
registerTypes(static_cast<COSer<CConnection>&>(*this));
#ifdef LIL_ENDIAN #ifdef LIL_ENDIAN
myEndianess = true; myEndianess = true;
#else #else
@ -200,19 +202,21 @@ CTypeList::CTypeList()
ui16 CTypeList::registerType( const type_info *type ) ui16 CTypeList::registerType( const type_info *type )
{ {
std::map<const type_info *,ui16>::const_iterator i = types.find(type); TTypeMap::const_iterator i = types.find(type);
if(i != types.end()) if(i != types.end())
return i->second; return i->second; //type found, return ID
//type not found - add it to the list and return given ID
ui16 id = types.size() + 1; ui16 id = types.size() + 1;
types[type] = id; types.insert(std::make_pair(type,id));
return id; return id;
} }
ui16 CTypeList::getTypeID( const type_info *type ) ui16 CTypeList::getTypeID( const type_info *type )
{ {
if(vstd::contains(types,type)) TTypeMap::const_iterator i = types.find(type);
return types[type]; if(i != types.end())
return i->second;
else else
return 0; return 0;
} }

View File

@ -53,21 +53,40 @@ enum SerializationLvl
Serializable Serializable
}; };
struct TypeComparer
{
bool operator()(const type_info *a, const type_info *b)
{
return a->before(*b);
}
};
class DLL_EXPORT CTypeList class DLL_EXPORT CTypeList
{ {
std::map<const type_info *,ui16> types; typedef std::multimap<const type_info *,ui16,TypeComparer> TTypeMap;
TTypeMap types;
public: public:
CTypeList(); CTypeList();
ui16 registerType(const type_info *type); ui16 registerType(const type_info *type);
template <typename T> ui16 registerType(const T * t) template <typename T> ui16 registerType(const T * t)
{ {
return registerType(&typeid(*t)); return registerType(getTypeInfo(t));
} }
ui16 getTypeID(const type_info *type); ui16 getTypeID(const type_info *type);
template <typename T> ui16 getTypeID(const T * t) template <typename T> ui16 getTypeID(const T * t)
{ {
return getTypeID(&typeid(*t)); return getTypeID(getTypeInfo(t));
}
template <typename T> const type_info * getTypeInfo(const T * t = NULL)
{
if(t)
return &typeid(*t);
else
return &typeid(T);
} }
}; };
@ -230,8 +249,8 @@ public:
template<typename T> void registerType(const T * t=NULL) template<typename T> void registerType(const T * t=NULL)
{ {
ui16 ID = typeList.registerType(&typeid(T)); ui16 ID = typeList.registerType(t);
savers[ID] = new CPointerSaver<Serializer,T>; savers[ID] = new CPointerSaver<COSer<Serializer>,T>;
} }
Serializer * This() Serializer * This()
@ -404,8 +423,8 @@ public:
template<typename T> void registerType(const T * t=NULL) template<typename T> void registerType(const T * t=NULL)
{ {
ui16 ID = typeList.registerType(&typeid(T)); ui16 ID = typeList.registerType(t);
loaders[ID] = new CPointerLoader<Serializer,T>; loaders[ID] = new CPointerLoader<CISer<Serializer>,T>;
} }
Serializer * This() Serializer * This()

View File

@ -14,28 +14,30 @@ struct CPack
ui16 type; ui16 type;
CPack(){}; CPack(){};
~CPack(){}; virtual ~CPack(){};
ui16 getType() const{return type;} ui16 getType() const{return type;}
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
tlog1 << "CPack serialized... this should not happen!\n";
} }
}; };
struct CPackForClient : public CPack struct CPackForClient : public CPack
{ {
CGameState* GS(CClient *cl); CGameState* GS(CClient *cl);
CPackForClient(){type = 0;};
void applyFirstCl(CClient *cl)//called before applying to gs void applyFirstCl(CClient *cl)//called before applying to gs
{ {
tlog1 << "CPackForClient::applyFirstCl - We should not be here!\n"; //tlog1 << "CPackForClient::applyFirstCl - We should not be here!\n";
}; };
DLL_EXPORT void applyGs(CGameState *gs) DLL_EXPORT void applyGs(CGameState *gs)
{ {
tlog1 << "CPackForClient::applyGs - We should not be here!\n"; //tlog1 << "CPackForClient::applyGs - We should not be here!\n";
}; };
void applyCl(CClient *cl)//called after applying to gs void applyCl(CClient *cl)//called after applying to gs
{ {
tlog1 << "CPackForClient::applyCl - We should not be here!\n"; //tlog1 << "CPackForClient::applyCl - We should not be here!\n";
}; };
}; };
@ -311,7 +313,7 @@ struct TryMoveHero : public CPackForClient //501
TryMoveHero(){type = 501;}; TryMoveHero(){type = 501;};
void applyFirstCl(CClient *cl); void applyFirstCl(CClient *cl);
void applyCl(CClient *cl); void applyCl(CClient *cl);
void applyqGs(CGameState *gs); void applyGs(CGameState *gs);
ui32 id, movePoints; ui32 id, movePoints;
ui8 result; //0 - failed; 1- succes -normal move; 2 - teleportation, 3 - instant jump ui8 result; //0 - failed; 1- succes -normal move; 2 - teleportation, 3 - instant jump
@ -397,6 +399,9 @@ struct SetHeroArtifacts : public CPackForClient //509
struct PlayerMessage : public CPackForClient //513 struct PlayerMessage : public CPackForClient //513
{ {
PlayerMessage(){type = 513;}; PlayerMessage(){type = 513;};
PlayerMessage(ui8 Player, const std::string &Text)
:player(Player),text(Text)
{type = 513;};
void applyCl(CClient *cl); void applyCl(CClient *cl);
ui8 player; ui8 player;

View File

@ -9,8 +9,8 @@
#include "../hch/CTownHandler.h" #include "../hch/CTownHandler.h"
#include "../CGameState.h" #include "../CGameState.h"
#include "../lib/CondSh.h" #include "../lib/CondSh.h"
#include "../lib/Connection.h"
#include "../lib/NetPacks.h" #include "../lib/NetPacks.h"
#include "../lib/Connection.h"
#include "../lib/VCMI_Lib.h" #include "../lib/VCMI_Lib.h"
#include "../map.h" #include "../map.h"
#include "CGameHandler.h" #include "CGameHandler.h"
@ -24,7 +24,6 @@
#include <boost/thread/xtime.hpp> #include <boost/thread/xtime.hpp>
#endif #endif
extern bool end2; extern bool end2;
#include "../lib/BattleAction.h"
#ifdef min #ifdef min
#undef min #undef min
#endif #endif
@ -343,7 +342,7 @@ void CGameHandler::startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile
ba.side = !next->attackerOwned; ba.side = !next->attackerOwned;
ba.stackNumber = next->ID; ba.stackNumber = next->ID;
sendAndApply(&StartAction(ba)); sendAndApply(&StartAction(ba));
sendDataToClients(ui16(3008)); sendAndApply(&EndAction());
checkForBattleEnd(stacks); //check if this "action" ended the battle (not likely but who knows...) checkForBattleEnd(stacks); //check if this "action" ended the battle (not likely but who knows...)
continue; continue;
} }
@ -988,9 +987,7 @@ upgend:
std::string message; std::string message;
c >> message; c >> message;
bool cheated=true; bool cheated=true;
sendDataToClients(ui16(513)); sendAndApply(&PlayerMessage(*players.begin(),message));
sendDataToClients(ui8(*players.begin()));
sendDataToClients(message);
if(message == "vcmiistari") //give all spells and 999 mana if(message == "vcmiistari") //give all spells and 999 mana
{ {
SetMana sm; SetMana sm;
@ -1084,9 +1081,7 @@ upgend:
if(cheated) if(cheated)
{ {
message = "CHEATER!!!"; message = "CHEATER!!!";
sendDataToClients(ui16(513)); sendAndApply(&PlayerMessage(*players.begin(),message));
sendDataToClients(ui8(*players.begin()));
sendDataToClients(message);
} }
break; break;
} }
@ -1154,14 +1149,14 @@ upgend:
{ {
sendAndApply(&StartAction(ba)); //start movement sendAndApply(&StartAction(ba)); //start movement
moveStack(ba.stackNumber,ba.destinationTile); //move moveStack(ba.stackNumber,ba.destinationTile); //move
sendDataToClients(ui16(3008)); //end movement sendAndApply(&EndAction());
break; break;
} }
case 3: //defend case 3: //defend
case 8: //wait case 8: //wait
{ {
sendAndApply(&StartAction(ba)); sendAndApply(&StartAction(ba));
sendDataToClients(ui16(3008)); sendAndApply(&EndAction());
break; break;
} }
case 4: //retreat/flee case 4: //retreat/flee
@ -1211,7 +1206,7 @@ upgend:
) )
{ {
tlog3 << "Attack cannot be performed!"; tlog3 << "Attack cannot be performed!";
sendDataToClients(ui16(3008)); //end movement and attack sendAndApply(&EndAction());
break; break;
} }
@ -1240,7 +1235,7 @@ upgend:
prepareAttack(bat,curStack,stackAtEnd); prepareAttack(bat,curStack,stackAtEnd);
sendAndApply(&bat); sendAndApply(&bat);
} }
sendDataToClients(ui16(3008)); //end movement and attack sendAndApply(&EndAction());
break; break;
} }
case 7: //shoot case 7: //shoot
@ -1277,7 +1272,7 @@ upgend:
sendAndApply(&bat); sendAndApply(&bat);
} }
sendDataToClients(ui16(3008)); //end shooting sendAndApply(&EndAction());
break; break;
} }
} }
@ -1519,7 +1514,7 @@ upgend:
- Weakness - Weakness
- Death Ripple */ - Death Ripple */
sendDataToClients(ui16(3008)); //end casting sendAndApply(&EndAction());
break; break;
} }
} }
@ -1808,7 +1803,11 @@ void CGameHandler::run(bool resume)
if((i->second.towns.size()==0 && i->second.heroes.size()==0) || i->second.color<0 || i->first>=PLAYER_LIMIT ) continue; //players has not towns/castle - loser if((i->second.towns.size()==0 && i->second.heroes.size()==0) || i->second.color<0 || i->first>=PLAYER_LIMIT ) continue; //players has not towns/castle - loser
states.setFlag(i->first,&PlayerStatus::makingTurn,true); states.setFlag(i->first,&PlayerStatus::makingTurn,true);
gs->currentPlayer = i->first; gs->currentPlayer = i->first;
*connections[i->first] << ui16(100) << i->first; {
YourTurn yt;
yt.player = i->first;
*connections[i->first] << &yt;
}
//wait till turn is done //wait till turn is done
boost::unique_lock<boost::mutex> lock(states.mx); boost::unique_lock<boost::mutex> lock(states.mx);
@ -2289,9 +2288,11 @@ void CGameHandler::setObjProperty( int objid, int prop, int val )
sendAndApply(&sob); sendAndApply(&sob);
} }
void CGameHandler::sendMessageTo( CConnection &c, std::string message ) void CGameHandler::sendMessageTo( CConnection &c, const std::string &message )
{ {
c << ui16(95) << message; SystemMessage sm;
sm.text = message;
c << &sm;
} }
void CGameHandler::giveHeroBonus( GiveBonus * bonus ) void CGameHandler::giveHeroBonus( GiveBonus * bonus )
@ -2350,3 +2351,19 @@ void CGameHandler::ask( Query * sel, ui8 player, const CFunctionList<void(ui32)>
QID++; QID++;
gsm.unlock(); gsm.unlock();
} }
void CGameHandler::sendToAllClients( CPack * info )
{
for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++)
{
(*i)->wmx->lock();
**i << info;
(*i)->wmx->unlock();
}
}
void CGameHandler::sendAndApply( CPack * info )
{
gs->apply(info);
sendToAllClients(info);
}

View File

@ -62,7 +62,7 @@ class CGameHandler : public IGameCallback
PlayerStatuses states; //player color -> player state PlayerStatuses states; //player color -> player state
std::set<CConnection*> conns; std::set<CConnection*> conns;
void sendMessageTo(CConnection &c, std::string message); void sendMessageTo(CConnection &c, const std::string &message);
void giveSpells(const CGTownInstance *t, const CGHeroInstance *h); void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
void moveStack(int stack, int dest); void moveStack(int stack, int dest);
void startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb); //use hero=NULL for no hero void startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb); //use hero=NULL for no hero
@ -153,24 +153,17 @@ public:
//} //}
void applyAndAsk(Query * sel, ui8 player, boost::function<void(ui32)> &callback); void applyAndAsk(Query * sel, ui8 player, boost::function<void(ui32)> &callback);
void ask(Query * sel, ui8 player, const CFunctionList<void(ui32)> &callback); void ask(Query * sel, ui8 player, const CFunctionList<void(ui32)> &callback);
template <typename T>void sendDataToClients(const T & data) //template <typename T>void sendDataToClients(const T & data)
{ //{
for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++) // for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++)
{ // {
(*i)->wmx->lock(); // (*i)->wmx->lock();
**i << data; // **i << data;
(*i)->wmx->unlock(); // (*i)->wmx->unlock();
} // }
} //}
void sendToAllClients(CPack * info) void sendToAllClients(CPack * info);
{ void sendAndApply(CPack * info);
}
void sendAndApply(CPack * info)
{
//gs->apply(info);
//sendToAllClients(info);
}
void run(bool resume); void run(bool resume);
void newTurn(); void newTurn();