1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

New file for VCMI_Server - NetPacksServer.cpp

Redone client -> server protocol.
This commit is contained in:
Michał W. Urbańczyk 2009-03-09 10:37:49 +00:00
parent d5da904c1f
commit 4653ca6b29
18 changed files with 1708 additions and 1241 deletions

View File

@ -1708,8 +1708,6 @@ void CBattleInterface::spellCasted(SpellCasted * sc)
SDL_framerateDelay(LOCPLINT->mainFPSmng);
}
SDL_SetClipRect(screen, &buf); //restoring previous clip rect
int b=0; //TODO use me
break; //for 15 and 16 cases
}
case 17: //lightning bolt

View File

@ -97,11 +97,7 @@ bool CCallback::moveHero(int ID, CPath * path, int idtype, int pathType)
if (pathType==0)
CPathfinder::convertPath(path,pathType);
if (pathType>1)
#ifndef __GNUC__
throw std::exception("Unknown path format");
#else
throw std::exception();
#endif
throw std::string("Unknown path format");
CPath * ourPath = path;
if(!ourPath)
@ -111,13 +107,14 @@ bool CCallback::moveHero(int ID, CPath * path, int idtype, int pathType)
int3 stpos(ourPath->nodes[i].coord.x, ourPath->nodes[i].coord.y, hero->pos.z),
endpos(ourPath->nodes[i-1].coord.x, ourPath->nodes[i-1].coord.y, hero->pos.z);
HeroMoveDetails curd(stpos,endpos,hero);
*cl->serv << ui16(501) << hero->id << stpos << endpos;
*cl->serv << &MoveHero(endpos,hero->id);
{//wait till there is server answer
boost::unique_lock<boost::mutex> lock(*mess.mx);
while(std::find_if(mess.res->begin(),mess.res->end(),&isType<501>) == mess.res->end())
mess.cv->wait(lock);
std::set<CPack*>::iterator itr = std::find_if(mess.res->begin(),mess.res->end(),&isType<501>);
TryMoveHero *tmh = static_cast<TryMoveHero*>(*itr);
TryMoveHero *tmh = dynamic_cast<TryMoveHero*>(*itr);
mess.res->erase(itr);
if(!tmh->result)
{
@ -132,12 +129,12 @@ bool CCallback::moveHero(int ID, CPath * path, int idtype, int pathType)
void CCallback::selectionMade(int selection, int asker)
{
*cl->serv << ui16(2001) << ui32(asker) << ui32(selection);
*cl->serv << &QueryReply(asker,selection);
}
void CCallback::recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount)
{
if(player!=obj->tempOwner) return;
*cl->serv << ui16(506) << obj->id << ID << amount;
*cl->serv << &RecruitCreatures(obj->id,ID,amount);
}
@ -145,20 +142,18 @@ bool CCallback::dismissCreature(const CArmedInstance *obj, int stackPos)
{
if(((player>=0) && obj->tempOwner != player) || obj->army.slots.size()<2)
return false;
*cl->serv << ui16(503) << obj->id << ui8(stackPos);
*cl->serv << &DisbandCreature(stackPos,obj->id);
return true;
}
bool CCallback::upgradeCreature(const CArmedInstance *obj, int stackPos, int newID)
{
*cl->serv << ui16(507) << obj->id << ui8(stackPos) << ui32(newID);
*cl->serv << &UpgradeCreature(stackPos,obj->id,newID);
return false;
}
void CCallback::endTurn()
{
tlog5 << "Player "<<(unsigned)player<<" end his turn."<<std::endl;
cl->serv->wmx->lock();
*cl->serv << ui16(100); //report that we ended turn
cl->serv->wmx->unlock();
*cl->serv << &EndTurn(); //report that we ended turn
}
UpgradeInfo CCallback::getUpgradeInfo(const CArmedInstance *obj, int stackPos) const
{
@ -388,7 +383,7 @@ int CCallback::swapCreatures(const CGObjectInstance *s1, const CGObjectInstance
{
if(s1->tempOwner != player || s2->tempOwner != player)
return -1;
*cl->serv << ui16(502) << ui8(1) << s1->id << ui8(p1) << s2->id << ui8(p2);
*cl->serv << &ArrangeStacks(1,p1,p2,s1->id,s2->id,0);
return 0;
}
@ -398,7 +393,7 @@ int CCallback::mergeStacks(const CGObjectInstance *s1, const CGObjectInstance *s
{
return -1;
}
*cl->serv << ui16(502) << ui8(2) << s1->id << ui8(p1) << s2->id << ui8(p2);
*cl->serv << &ArrangeStacks(2,p1,p2,s1->id,s2->id,0);
return 0;
}
int CCallback::splitStack(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2, int val)
@ -407,14 +402,14 @@ int CCallback::splitStack(const CGObjectInstance *s1, const CGObjectInstance *s2
{
return -1;
}
*cl->serv << ui16(502) << ui8(3) << s1->id << ui8(p1) << s2->id << ui8(p2) << si32(val);
*cl->serv << &ArrangeStacks(3,p1,p2,s1->id,s2->id,val);
return 0;
}
bool CCallback::dismissHero(const CGHeroInstance *hero)
{
if(player!=hero->tempOwner) return false;
*cl->serv << ui16(500) << hero->id;
*cl->serv << &DismissHero(hero->id);
return true;
}
@ -443,7 +438,7 @@ bool CCallback::buildBuilding(const CGTownInstance *town, si32 buildingID)
if(b->resources[i] > gs->players[player].resources[i])
return false; //lack of resources
*cl->serv << ui16(504) << town->id << buildingID;
*cl->serv << &BuildStructure(town->id,buildingID);
return true;
}
@ -483,7 +478,7 @@ CStack* CCallback::battleGetStackByID(int ID)
int CCallback::battleMakeAction(BattleAction* action)
{
*cl->serv << ui16(3003) << *action;
*cl->serv << &MakeAction(*action);
return 0;
}
@ -612,7 +607,7 @@ void CCallback::swapGarrisonHero( const CGTownInstance *town )
void CCallback::buyArtifact(const CGHeroInstance *hero, int aid)
{
if(hero->tempOwner != player) return;
*cl->serv << ui16(510) << hero->id << ui32(aid);
*cl->serv << &BuyArtifact(hero->id,aid);
}
std::vector < const CGObjectInstance * > CCallback::getBlockingObjs( int3 pos ) const
@ -681,13 +676,13 @@ void CCallback::trade( int mode, int id1, int id2, int val1 )
{
int p1, p2;
getMarketOffer(id1,id2,p1,p2,mode);
*cl->serv << ui16(511) << ui8(player) << ui32(mode) << ui32(id1) << ui32(id2) << ui32(val1);
*cl->serv << &TradeOnMarketplace(player,mode,id1,id2,val1);
}
void CCallback::setFormation(const CGHeroInstance * hero, bool tight)
{
const_cast<CGHeroInstance*>(hero)->army.formation = tight;
*cl->serv << ui16(512) << hero->id << ui8(tight);
*cl->serv << &SetFormation(hero->id,tight);
}
void CCallback::setSelection(const CArmedInstance * obj)
@ -695,17 +690,20 @@ void CCallback::setSelection(const CArmedInstance * obj)
SetSelection ss;
ss.player = player;
ss.id = obj->id;
*cl->serv << ui16(514) << ss;
*cl->serv << &ss;
}
void CCallback::recruitHero(const CGTownInstance *town, const CGHeroInstance *hero)
{
ui8 i=0;
for(;i<gs->players[player].availableHeroes.size();i++)
for(; i<gs->players[player].availableHeroes.size(); i++)
{
if(gs->players[player].availableHeroes[i] == hero)
break;
if(i>1) return;
*cl->serv << ui16(515) << town->id << i;
{
*cl->serv << &HireHero(town->id,i);
return;
}
}
}
std::vector<const CGHeroInstance *> CCallback::getAvailableHeroes(const CGTownInstance * town) const

View File

@ -1116,7 +1116,8 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
j->second.first = vti->town->upgradedCreatures[ (j->second.first-197) / 2 ];
}
}
players[vti->getOwner()].towns.push_back(vti);
if(vti->getOwner() != 255)
getPlayer(vti->getOwner())->towns.push_back(vti);
}
for(std::map<ui8, PlayerState>::iterator k=players.begin(); k!=players.end(); ++k)
@ -1297,8 +1298,8 @@ float CGameState::getMarketEfficiency( int player, int mode/*=0*/ )
boost::shared_lock<boost::shared_mutex> lock(*mx);
if(mode) return -1; //todo - support other modes
int mcount = 0;
for(int i=0;i<players[player].towns.size();i++)
if(vstd::contains(players[player].towns[i]->builtBuildings,14))
for(int i=0;i<getPlayer(player)->towns.size();i++)
if(vstd::contains(getPlayer(player)->towns[i]->builtBuildings,14))
mcount++;
float ret = std::min(((float)mcount+1.0f)/20.0f,0.5f);
return ret;
@ -1453,7 +1454,7 @@ int CGameState::canBuildStructure( const CGTownInstance *t, int ID )
CBuilding * pom = VLC->buildh->buildings[t->subID][ID];
for(int res=0;res<7;res++) //TODO: support custom amount of resources
{
if(pom->resources[res] > players[t->tempOwner].resources[res])
if(pom->resources[res] > getPlayer(t->tempOwner)->resources[res])
ret = 6; //lack of res
}
@ -1491,6 +1492,19 @@ void CGameState::apply(CPack *pack)
applier->apps[typeList.getTypeID(pack)]->applyOnGS(this,pack);
}
PlayerState * CGameState::getPlayer( ui8 color )
{
if(vstd::contains(players,color))
{
return &players[color];
}
else
{
tlog2 << "Warning: Cannot find info for player " << int(color) << std::endl;
return NULL;
}
}
int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting)
{
int attackerAttackBonus = attacker->creature->attack + (attackerHero ? attackerHero->getPrimSkillLevel(0) : 0);
@ -1637,7 +1651,7 @@ int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, con
dmgBonusMultiplier *= 0.8f;
}
return (float)damageBase * (float)attacker->amount * dmgBonusMultiplier;
return int( (float)damageBase * (float)attacker->amount * dmgBonusMultiplier );
}
void BattleInfo::calculateCasualties( std::set<std::pair<ui32,si32> > *casualties )

View File

@ -224,6 +224,7 @@ public:
boost::shared_mutex *mx;
PlayerState *getPlayer(ui8 color);
void init(StartInfo * si, Mapa * map, int Seed);
void loadTownDInfos();
void randomizeObject(CGObjectInstance *cur);
@ -257,10 +258,10 @@ public:
//recreating towns/heroes vectors in players entries
for(int i=0; i<map->towns.size(); i++)
if(map->towns[i]->tempOwner < PLAYER_LIMIT)
players[map->towns[i]->tempOwner].towns.push_back(map->towns[i]);
getPlayer(map->towns[i]->tempOwner)->towns.push_back(map->towns[i]);
for(int i=0; i<map->heroes.size(); i++)
if(map->heroes[i]->tempOwner < PLAYER_LIMIT)
players[map->heroes[i]->tempOwner].heroes.push_back(map->heroes[i]);
getPlayer(map->heroes[i]->tempOwner)->heroes.push_back(map->heroes[i]);
//recreating available heroes
for(std::map<ui8,PlayerState>::iterator i=players.begin(); i!=players.end(); i++)
{

View File

@ -41,6 +41,7 @@
#include "lib/Connection.h"
#include "lib/VCMI_Lib.h"
#include <cstdlib>
#include "lib/NetPacks.h"
#if __MINGW32__
#undef main
@ -328,6 +329,6 @@ void processCommand(const std::string &message, CClient *&client)
}
else if(client && client->serv && client->serv->connected) //send to server
{
*client->serv << ui16(513) << message;
*client->serv << &PlayerMessage(255,message);
}
}

View File

@ -1,4 +1,4 @@
0.7 -> 0.71 (as for r726)
0.7 -> 0.71 (as for r751)
GENERAL:
* fixed scrolling behind window problem (now it's possible to scroll with CTRL + arrows)
* morale/luck system and corresponding sec. skills supported
@ -30,7 +30,14 @@ BATTLES:
* spells not known by hero can't be casted
* spell books won't be placed in War Machine slots after battle
* attack is now possible when hex under cursor is not displayed
* glowing effect of yellow border around creatures
* blue glowing border around hovered creature
* made animation on battlefield more smooth
* standing stacks have more static animation
* fixes for two-hex creatures actions
* fixed hero casting spell animation
* corrected stack death animation
* correct handling of flying creatures in battles
* a few tweaks in battle path/available hexes calculation (more of them is needed)
* fixed positions of stack queue and battle result window when resolution is != 800x600
* corrected duration of frenzy spell which was incorrect in certain cases

View File

@ -137,7 +137,7 @@ void CClient::close()
tlog3 << "Connection has been requested to be closed.\n";
boost::unique_lock<boost::mutex>(*serv->wmx);
*serv << ui16(99);
*serv << &CloseServer();
tlog3 << "Sent closing signal to the server\n";
serv->close();
tlog3 << "Our socket has been closed.\n";
@ -151,7 +151,7 @@ void CClient::save(const std::string & fname)
return;
}
*serv << ui16(98) << fname;
*serv << &SaveGame(fname);
}
void CClient::load( const std::string & fname )

View File

@ -85,7 +85,7 @@ public:
void startBattleI(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb){}; //use hero=NULL for no hero
void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb){}; //for hero<=>neutral army
void setAmount(int objid, ui32 val){};
void moveHero(int hid, int3 pos, bool instant){};
void moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker = 255){};
void giveHeroBonus(GiveBonus * bonus){};
void setMovePoints(SetMovePoints * smp){};
void setManaPoints(int hid, int val){};

2
int3.h
View File

@ -35,7 +35,7 @@ public:
}
operator bool() const
{
return slots.size();
return slots.size()>0;
}
};

View File

@ -7,15 +7,33 @@
const CGObjectInstance* IGameCallback::getObj(int objid)
{
if(objid < 0 || objid >= gs->map->objects.size())
{
tlog1 << "Cannot get object with id " << objid << std::endl;
return NULL;
}
else if (!gs->map->objects[objid])
{
tlog1 << "Cannot get object with id " << objid << ". Object was removed.\n";
return NULL;
}
return gs->map->objects[objid];
}
const CGHeroInstance* IGameCallback::getHero(int objid)
{
return dynamic_cast<const CGHeroInstance*>(gs->map->objects[objid]);
const CGObjectInstance *obj = getObj(objid);
if(obj)
return dynamic_cast<const CGHeroInstance*>(obj);
else
return NULL;
}
const CGTownInstance* IGameCallback::getTown(int objid)
{
return dynamic_cast<const CGTownInstance*>(gs->map->objects[objid]);
const CGObjectInstance *obj = getObj(objid);
if(obj)
return dynamic_cast<const CGTownInstance*>(gs->map->objects[objid]);
else
return NULL;
}
int IGameCallback::getOwner(int heroID)
@ -45,10 +63,10 @@ int IGameCallback::getHeroCount( int player, bool includeGarrisoned )
{
int ret = 0;
if(includeGarrisoned)
return gs->players[player].heroes.size();
return gs->getPlayer(player)->heroes.size();
else
for(int i=0; i < gs->players[player].heroes.size(); i++)
if(!gs->players[player].heroes[i]->inTownGarrison)
for(int i=0; i < gs->getPlayer(player)->heroes.size(); i++)
if(!gs->getPlayer(player)->heroes[i]->inTownGarrison)
ret++;
return ret;
}

View File

@ -59,7 +59,7 @@ public:
virtual void startBattleI(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb)=0; //use hero=NULL for no hero
virtual void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb)=0; //for hero<=>neutral army
virtual void setAmount(int objid, ui32 val)=0;
virtual void moveHero(int hid, int3 pos, bool instant)=0;
virtual void moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker = 255)=0;
virtual void giveHeroBonus(GiveBonus * bonus)=0;
virtual void setMovePoints(SetMovePoints * smp)=0;
virtual void setManaPoints(int hid, int val)=0;
@ -67,5 +67,6 @@ public:
virtual void changeObjPos(int objid, int3 newPos, ui8 flags)=0;
friend struct CPackForClient;
friend struct CPackForServer;
};
#endif // __IGAMECALLBACK_H__

View File

@ -8,6 +8,8 @@
class CClient;
class CGameState;
class CGameHandler;
class CConnection;
struct CPack
{
@ -20,27 +22,36 @@ struct CPack
{
tlog1 << "CPack serialized... this should not happen!\n";
}
DLL_EXPORT void applyGs(CGameState *gs)
{};
};
struct CPackForClient : public CPack
{
CGameState* GS(CClient *cl);
CPackForClient(){type = 0;};
CPackForClient(){type = 1;};
CGameState* GS(CClient *cl);
void applyFirstCl(CClient *cl)//called before applying to gs
{
//tlog1 << "CPackForClient::applyFirstCl - We should not be here!\n";
};
DLL_EXPORT void applyGs(CGameState *gs)
{
//tlog1 << "CPackForClient::applyGs - We should not be here!\n";
};
{};
void applyCl(CClient *cl)//called after applying to gs
{
//tlog1 << "CPackForClient::applyCl - We should not be here!\n";
};
{};
};
struct CPackForServer : public CPack
{
CConnection *c;
CGameState* GS(CGameHandler *gh);
CPackForServer()
{
type = 2;
c = NULL;
};
void applyGh(CGameHandler *gh)//called after applying to gs
{};
};
struct Query : public CPackForClient
{
ui32 id;
@ -80,8 +91,11 @@ struct MetaString : public CPack //2001 helper for object scrips
MetaString(){type = 2001;};
};
/***********************************************************************************************************/
struct SystemMessage : public CPackForClient //95
{
SystemMessage(const std::string Text) : text(Text){type = 95;};
SystemMessage(){type = 95;};
void applyCl(CClient *cl);
@ -394,38 +408,7 @@ struct SetHeroArtifacts : public CPackForClient //509
{
h & hid & artifacts & artifWorn;
}
};
struct PlayerMessage : public CPackForClient //513
{
PlayerMessage(){type = 513;};
PlayerMessage(ui8 Player, const std::string &Text)
:player(Player),text(Text)
{type = 513;};
void applyCl(CClient *cl);
ui8 player;
std::string text;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & text & player;
}
};
struct SetSelection : public CPackForClient //514
{
SetSelection(){type = 514;};
DLL_EXPORT void applyGs(CGameState *gs);
ui8 player;
ui32 id;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & id & player;
}
};
};
struct HeroRecruited : public CPackForClient //515
{
@ -793,4 +776,296 @@ struct ShowInInfobox : public CPackForClient //107
h & player & c & text;
}
};
/***********************************************************************************************************/
struct SaveGame : public CPackForServer
{
SaveGame(){};
SaveGame(const std::string &Fname) :fname(Fname){};
std::string fname;
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & fname;
}
};
struct CloseServer : public CPackForServer
{
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{}
};
struct EndTurn : public CPackForServer
{
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{}
};
struct DismissHero : public CPackForServer
{
DismissHero(){};
DismissHero(si32 HID) : hid(hid) {};
si32 hid;
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & hid;
}
};
struct MoveHero : public CPackForServer
{
MoveHero(){};
MoveHero(const int3 &Dest, si32 HID) : dest(Dest), hid(HID){};
int3 dest;
si32 hid;
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & dest & hid;
}
};
struct ArrangeStacks : public CPackForServer
{
ArrangeStacks(){};
ArrangeStacks(ui8 W, ui8 P1, ui8 P2, si32 ID1, si32 ID2, si32 VAL)
:what(W),p1(P1),p2(P2),id1(ID1),id2(ID2),val(VAL) {};
ui8 what; //1 - swap; 2 - merge; 3 - split
ui8 p1, p2; //positions of first and second stack
si32 id1, id2; //ids of objects with garrison
si32 val;
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & what & p1 & p2 & id1 & id2 & val;
}
};
struct DisbandCreature : public CPackForServer
{
DisbandCreature(){};
DisbandCreature(ui8 Pos, si32 ID):pos(Pos),id(ID){};
ui8 pos; //stack pos
si32 id; //object id
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & pos & id;
}
};
struct BuildStructure : public CPackForServer
{
BuildStructure(){};
BuildStructure(si32 TID, si32 BID):tid(TID),bid(BID){};
si32 bid, tid; //structure and town ids
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & tid & bid;
}
};
struct RecruitCreatures : public CPackForServer
{
RecruitCreatures(){};
RecruitCreatures(si32 TID, si32 CRID, si32 Amount):tid(TID),crid(CRID),amount(Amount){};
si32 tid; //town id
ui32 crid, amount;//creature ID and amount
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & tid & crid & amount;
}
};
struct UpgradeCreature : public CPackForServer
{
UpgradeCreature(){};
UpgradeCreature(ui8 Pos, si32 ID, si32 CRID):pos(Pos),id(ID), cid(CRID){};
ui8 pos; //stack pos
si32 id; //object id
si32 cid; //id of type to which we want make upgrade
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & pos & id & cid;
}
};
struct GarrisonHeroSwap : public CPackForServer
{
GarrisonHeroSwap(){};
GarrisonHeroSwap(si32 TID):tid(TID){};
si32 tid;
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & tid;
}
};
struct ExchangeArtifacts : public CPackForServer
{
ExchangeArtifacts(){};
ExchangeArtifacts(si32 H1, si32 H2, ui16 S1, ui16 S2)
:hid1(H1),hid2(H2),slot1(S1),slot2(S2){};
si32 hid1, hid2;
ui16 slot1, slot2;
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & hid1 & hid2 & slot1 & slot2;
}
};
struct BuyArtifact : public CPackForServer
{
BuyArtifact(){};
BuyArtifact(si32 HID, si32 AID):hid(HID),aid(AID){};
si32 hid, aid; //hero and artifact id
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & hid & aid;
}
};
struct TradeOnMarketplace : public CPackForServer
{
TradeOnMarketplace(){};
TradeOnMarketplace(ui8 Player, ui8 Mode, /*si32 ID, */ui32 R1, ui32 R2, ui32 Val)
:player(Player),mode(Mode),/*id(ID),*/r1(R1),r2(R2),val(Val){};
ui8 player;
ui8 mode;//0 - res<->res;
//si32 id; //object id
ui32 r1, r2; //mode 0: r1 - sold resource, r2 - bought res
ui32 val; //units of sold resource
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & player & mode & /*id & */r1 & r2 & val;
}
};
struct SetFormation : public CPackForServer
{
SetFormation(){};
SetFormation(si32 HID, ui8 Formation):hid(HID),formation(Formation){};
si32 hid;
ui8 formation;
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & hid & formation;
}
};
struct HireHero : public CPackForServer
{
HireHero(){};
HireHero(si32 HID, si32 TID):hid(HID),tid(TID){};
si32 hid, tid; //available hero serial and town id
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & hid & tid;
}
};
struct QueryReply : public CPackForServer
{
QueryReply(){};
QueryReply(ui32 QID, ui32 Answer):qid(QID),answer(Answer){};
ui32 qid, answer; //hero and artifact id
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & qid & answer;
}
};
struct MakeAction : public CPackForServer
{
MakeAction(){};
MakeAction(const BattleAction &BA):ba(ba){};
BattleAction ba;
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & ba;
}
};
struct MakeCustomAction : public CPackForServer
{
MakeCustomAction(){};
MakeCustomAction(const BattleAction &BA):ba(ba){};
BattleAction ba;
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & ba;
}
};
/***********************************************************************************************************/
struct PlayerMessage : public CPackForClient, public CPackForServer //513
{
PlayerMessage(){CPackForClient::type = 513;};
PlayerMessage(ui8 Player, const std::string &Text)
:player(Player),text(Text)
{CPackForClient::type = 513;};
void applyCl(CClient *cl);
void applyGs(CGameState *gs){};
void applyGh(CGameHandler *gh);
ui8 player;
std::string text;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & text & player;
}
};
struct SetSelection : public CPackForClient, public CPackForServer //514
{
SetSelection(){CPackForClient::type = 514;};
DLL_EXPORT void applyGs(CGameState *gs);
void applyGh(CGameHandler *gh);
ui8 player;
ui32 id;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & id & player;
}
};
#endif //__NETPACKS_H__

View File

@ -14,13 +14,13 @@
DLL_EXPORT void SetResource::applyGs( CGameState *gs )
{
gs->players[player].resources[resid] = val;
gs->getPlayer(player)->resources[resid] = val;
}
DLL_EXPORT void SetResources::applyGs( CGameState *gs )
{
for(int i=0;i<res.size();i++)
gs->players[player].resources[i] = res[i];
gs->getPlayer(player)->resources[i] = res[i];
}
DLL_EXPORT void SetPrimSkill::applyGs( CGameState *gs )
@ -127,15 +127,15 @@ DLL_EXPORT void SetMovePoints::applyGs( CGameState *gs )
DLL_EXPORT void FoWChange::applyGs( CGameState *gs )
{
BOOST_FOREACH(int3 t, tiles)
gs->players[player].fogOfWarMap[t.x][t.y][t.z] = mode;
gs->getPlayer(player)->fogOfWarMap[t.x][t.y][t.z] = mode;
}
DLL_EXPORT void SetAvailableHeroes::applyGs( CGameState *gs )
{
gs->players[player].availableHeroes.clear();
gs->getPlayer(player)->availableHeroes.clear();
CGHeroInstance *h = (hid1>=0 ? gs->hpool.heroesPool[hid1] : NULL);
gs->players[player].availableHeroes.push_back(h);
gs->getPlayer(player)->availableHeroes.push_back(h);
if(h && flags & 1)
{
h->army.slots.clear();
@ -143,7 +143,7 @@ DLL_EXPORT void SetAvailableHeroes::applyGs( CGameState *gs )
}
h = (hid2>=0 ? gs->hpool.heroesPool[hid2] : NULL);
gs->players[player].availableHeroes.push_back(h);
gs->getPlayer(player)->availableHeroes.push_back(h);
if(flags & 2)
{
h->army.slots.clear();
@ -180,8 +180,8 @@ DLL_EXPORT void RemoveObject::applyGs( CGameState *gs )
std::vector<CGHeroInstance*>::iterator nitr = std::find(gs->map->heroes.begin(), gs->map->heroes.end(),h);
gs->map->heroes.erase(nitr);
int player = h->tempOwner;
nitr = std::find(gs->players[player].heroes.begin(), gs->players[player].heroes.end(), h);
gs->players[player].heroes.erase(nitr);
nitr = std::find(gs->getPlayer(player)->heroes.begin(), gs->getPlayer(player)->heroes.end(), h);
gs->getPlayer(player)->heroes.erase(nitr);
if(h->visitedTown)
{
if(h->inTownGarrison)
@ -213,7 +213,7 @@ void TryMoveHero::applyGs( CGameState *gs )
gs->map->addBlockVisTiles(h);
}
BOOST_FOREACH(int3 t, fowRevealed)
gs->players[h->getOwner()].fogOfWarMap[t.x][t.y][t.z] = 1;
gs->getPlayer(h->getOwner())->fogOfWarMap[t.x][t.y][t.z] = 1;
}
DLL_EXPORT void SetGarrisons::applyGs( CGameState *gs )
@ -295,7 +295,7 @@ DLL_EXPORT void HeroRecruited::applyGs( CGameState *gs )
h->initHeroDefInfo();
gs->map->heroes.push_back(h);
gs->players[h->tempOwner].heroes.push_back(h);
gs->getPlayer(h->getOwner())->heroes.push_back(h);
gs->map->addBlockVisTiles(h);
t->visitingHero = h;
h->visitedTown = t;
@ -310,7 +310,7 @@ DLL_EXPORT void GiveHero::applyGs( CGameState *gs )
h->movement = h->maxMovePoints(true);
h->initHeroDefInfo();
gs->map->heroes.push_back(h);
gs->players[h->tempOwner].heroes.push_back(h);
gs->getPlayer(h->getOwner())->heroes.push_back(h);
gs->map->addBlockVisTiles(h);
h->inTownGarrison = false;
}
@ -476,5 +476,5 @@ DLL_EXPORT void YourTurn::applyGs( CGameState *gs )
DLL_EXPORT void SetSelection::applyGs( CGameState *gs )
{
gs->players[player].currentSelection = id;
gs->getPlayer(player)->currentSelection = id;
}

View File

@ -29,7 +29,7 @@ template<typename Serializer> DLL_EXPORT void registerTypes1(Serializer &s)
}
//second set of types - derivatives of CPack (network VCMI packages)
//second set of types - derivatives of CPack for client (network VCMI packages)
template<typename Serializer> DLL_EXPORT void registerTypes2(Serializer &s)
{
s.registerType<SystemMessage>();
@ -53,7 +53,6 @@ template<typename Serializer> DLL_EXPORT void registerTypes2(Serializer &s)
s.registerType<SetAvailableCreatures>();
s.registerType<SetHeroesInTown>();
s.registerType<SetHeroArtifacts>();
s.registerType<SetSelection>();
s.registerType<HeroRecruited>();
s.registerType<GiveHero>();
s.registerType<NewTurn>();
@ -75,6 +74,35 @@ template<typename Serializer> DLL_EXPORT void registerTypes2(Serializer &s)
s.registerType<SpellCasted>();
s.registerType<SetStackEffect>();
s.registerType<ShowInInfobox>();
s.registerType<SetSelection>();
s.registerType<PlayerMessage>();
}
template<typename Serializer> DLL_EXPORT void registerTypes3(Serializer &s)
{
s.registerType<SaveGame>();
s.registerType<CloseServer>();
s.registerType<EndTurn>();
s.registerType<DismissHero>();
s.registerType<MoveHero>();
s.registerType<ArrangeStacks>();
s.registerType<DisbandCreature>();
s.registerType<BuildStructure>();
s.registerType<RecruitCreatures>();
s.registerType<UpgradeCreature>();
s.registerType<GarrisonHeroSwap>();
s.registerType<ExchangeArtifacts>();
s.registerType<BuyArtifact>();
s.registerType<TradeOnMarketplace>();
s.registerType<SetFormation>();
s.registerType<HireHero>();
s.registerType<QueryReply>();
s.registerType<MakeAction>();
s.registerType<MakeCustomAction>();
s.registerType<SetSelection>();
s.registerType<PlayerMessage>();
}
//register all
@ -82,4 +110,5 @@ template<typename Serializer> DLL_EXPORT void registerTypes(Serializer &s)
{
registerTypes1(s);
registerTypes2(s);
registerTypes3(s);
}

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,7 @@
#include "../CGameState.h"
#include "../lib/Connection.h"
#include "../lib/IGameCallback.h"
#include "../lib/BattleAction.h"
#include <boost/function.hpp>
#include <boost/thread.hpp>
class CVCMIServer;
@ -56,13 +57,13 @@ public:
class CGameHandler : public IGameCallback
{
public:
static ui32 QID;
CVCMIServer *s;
std::map<int,CConnection*> connections; //player color -> connection to clinet with interface of that player
PlayerStatuses states; //player color -> player state
std::set<CConnection*> conns;
void sendMessageTo(CConnection &c, const std::string &message);
void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
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
@ -71,7 +72,7 @@ class CGameHandler : public IGameCallback
void checkForBattleEnd( std::vector<CStack*> &stacks );
void setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army1, CCreatureSet &army2, CGHeroInstance * hero1, CGHeroInstance * hero2 );
public:
CGameHandler(void);
~CGameHandler(void);
@ -102,7 +103,7 @@ public:
void startBattleI(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb); //use hero=NULL for no hero
void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb); //for hero<=>neutral army
void setAmount(int objid, ui32 val);
void moveHero(int hid, int3 pos, bool instant);
void moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker = 255);
void giveHeroBonus(GiveBonus * bonus);
void setMovePoints(SetMovePoints * smp);
void setManaPoints(int hid, int val);
@ -112,58 +113,38 @@ public:
void init(StartInfo *si, int Seed);
void handleConnection(std::set<int> players, CConnection &c);
int getPlayerAt(CConnection *c) const;
void playerMessage( ui8 player, const std::string &message);
void makeBattleAction(BattleAction &ba);
void makeCustomAction(BattleAction &ba);
void queryReply( ui32 qid, ui32 answer );
void hireHero( ui32 tid, ui8 hid );
void setFormation( si32 hid, ui8 formation );
void tradeResources( ui32 val, ui8 player, ui32 id1, ui32 id2 );
void buyArtifact( ui32 hid, si32 aid );
void swapArtifacts( si32 hid1, si32 hid2, ui16 slot1, ui16 slot2 );
void garrisonSwap(si32 tid);
void upgradeCreature( ui32 objid, ui8 pos, ui32 upgID );
void recruitCreatures(si32 objid, ui32 crid, ui32 cram);
void buildStructure(si32 tid, si32 bid);
void disbandCreature( si32 id, ui8 pos );
void arrangeStacks( si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2, si32 val );
void save(const std::string &fname);
void close();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & QID & states;
}
//template <typename T> void applyAndAsk(Query<T> * sel, ui8 player, boost::function<void(ui32)> &callback)
//{
// gsm.lock();
// sel->id = QID;
// callbacks[QID] = callback;
// states.addQuery(player,QID);
// QID++;
// sendAndApply(sel);
// gsm.unlock();
//}
//template <typename T> void ask(Query<T> * sel, ui8 player, const CFunctionList<void(ui32)> &callback)
//{
// gsm.lock();
// sel->id = QID;
// callbacks[QID] = callback;
// states.addQuery(player,QID);
// sendToAllClients(sel);
// QID++;
// gsm.unlock();
//}
//template <typename T>void sendToAllClients(CPack<T> * info)
//{
// for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++)
// {
// (*i)->wmx->lock();
// **i << info->getType() << *info->This();
// (*i)->wmx->unlock();
// }
//}
//template <typename T>void sendAndApply(CPack<T> * info)
//{
// gs->apply(info);
// sendToAllClients(info);
//}
void sendMessageToAll(const std::string &message);
void sendMessageTo(CConnection &c, const std::string &message);
void applyAndAsk(Query * sel, ui8 player, boost::function<void(ui32)> &callback);
void ask(Query * sel, ui8 player, const CFunctionList<void(ui32)> &callback);
//template <typename T>void sendDataToClients(const T & data)
//{
// for(std::set<CConnection*>::iterator i=conns.begin(); i!=conns.end();i++)
// {
// (*i)->wmx->lock();
// **i << data;
// (*i)->wmx->unlock();
// }
//}
void sendToAllClients(CPack * info);
void sendAndApply(CPack * info);
void sendToAllClients(CPackForClient * info);
void sendAndApply(CPackForClient * info);
void run(bool resume);
void newTurn();

140
server/NetPacksServer.cpp Normal file
View File

@ -0,0 +1,140 @@
#include "../lib/NetPacks.h"
#include "CGameHandler.h"
#define PLAYER_OWNS(id) (gh->getPlayerAt(c)==gh->getOwner(id))
#define ERROR_AND_RETURN {if(c) *c << &SystemMessage("You don't own this object!"); \
tlog1<<"Player is not allowed to perform this action!\n"; \
return;}
#define ERROR_IF_NOT_OWNS(id) if(!PLAYER_OWNS(id)) ERROR_AND_RETURN
CGameState* CPackForServer::GS(CGameHandler *gh)
{
return gh->gs;
}
void SaveGame::applyGh( CGameHandler *gh )
{
gh->sendMessageTo(*c,"Saving...");
gh->save(fname);
gh->sendMessageTo(*c,"Game has been succesfully saved!");
}
void CloseServer::applyGh( CGameHandler *gh )
{
gh->close();
}
void EndTurn::applyGh( CGameHandler *gh )
{
gh->states.setFlag(GS(gh)->currentPlayer,&PlayerStatus::makingTurn,false);
}
void DismissHero::applyGh( CGameHandler *gh )
{
ERROR_IF_NOT_OWNS(hid);
gh->removeObject(hid);
}
void MoveHero::applyGh( CGameHandler *gh )
{
ERROR_IF_NOT_OWNS(hid);
gh->moveHero(hid,dest,0,gh->getPlayerAt(c));
}
void ArrangeStacks::applyGh( CGameHandler *gh )
{
ERROR_IF_NOT_OWNS(id1);
ERROR_IF_NOT_OWNS(id2);
gh->arrangeStacks(id1,id2,what,p1,p2,val);
}
void DisbandCreature::applyGh( CGameHandler *gh )
{
ERROR_IF_NOT_OWNS(id);
gh->disbandCreature(id,pos);
}
void BuildStructure::applyGh( CGameHandler *gh )
{
ERROR_IF_NOT_OWNS(tid);
gh->buildStructure(tid,bid);
}
void RecruitCreatures::applyGh( CGameHandler *gh )
{
ERROR_IF_NOT_OWNS(tid);
gh->recruitCreatures(tid,crid,amount);
}
void UpgradeCreature::applyGh( CGameHandler *gh )
{
ERROR_IF_NOT_OWNS(id);
gh->upgradeCreature(id,pos,cid);
}
void GarrisonHeroSwap::applyGh( CGameHandler *gh )
{
ERROR_IF_NOT_OWNS(tid);
gh->garrisonSwap(tid);
}
void ExchangeArtifacts::applyGh( CGameHandler *gh )
{
ERROR_IF_NOT_OWNS(hid1);
ERROR_IF_NOT_OWNS(hid2);
gh->swapArtifacts(hid1,hid2,slot1,slot2);
}
void BuyArtifact::applyGh( CGameHandler *gh )
{
ERROR_IF_NOT_OWNS(hid);
gh->buyArtifact(hid,aid);
}
void TradeOnMarketplace::applyGh( CGameHandler *gh )
{
if(gh->getPlayerAt(c) != player) ERROR_AND_RETURN;
gh->tradeResources(val,player,r1,r2);
}
void SetFormation::applyGh( CGameHandler *gh )
{
ERROR_IF_NOT_OWNS(hid);
gh->setFormation(hid,formation);
}
void HireHero::applyGh( CGameHandler *gh )
{
ERROR_IF_NOT_OWNS(tid);
gh->hireHero(tid,hid);
}
void QueryReply::applyGh( CGameHandler *gh )
{
gh->queryReply(qid,answer);
}
void MakeAction::applyGh( CGameHandler *gh )
{
if(gh->getPlayerAt(c) != GS(gh)->curB->getStack(GS(gh)->curB->activeStack)->owner) ERROR_AND_RETURN;
gh->makeBattleAction(ba);
}
void MakeCustomAction::applyGh( CGameHandler *gh )
{
if(gh->getPlayerAt(c) != GS(gh)->curB->getStack(GS(gh)->curB->activeStack)->owner) ERROR_AND_RETURN;
gh->makeCustomAction(ba);
}
void PlayerMessage::applyGh( CGameHandler *gh )
{
if(gh->getPlayerAt(c) != player) ERROR_AND_RETURN;
gh->playerMessage(player,text);
}
void SetSelection::applyGh( CGameHandler *gh )
{
if(gh->getPlayerAt(c) != player) ERROR_AND_RETURN;
gh->sendToAllClients(this);
}

View File

@ -264,6 +264,10 @@
RelativePath=".\CVCMIServer.cpp"
>
</File>
<File
RelativePath=".\NetPacksServer.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"