2008-07-25 20:28:28 +03:00
# include "../CCallback.h"
# include "../CConsoleHandler.h"
2008-11-09 00:29:19 +02:00
# include "../CGameInfo.h"
# include "../CGameState.h"
# include "../CPlayerInterface.h"
# include "../StartInfo.h"
# include "../hch/CArtHandler.h"
2009-01-11 00:08:18 +02:00
# include "../hch/CDefObjInfoHandler.h"
2008-11-09 00:29:19 +02:00
# include "../hch/CGeneralTextHandler.h"
2009-01-11 00:08:18 +02:00
# include "../hch/CHeroHandler.h"
# include "../hch/CTownHandler.h"
2008-11-09 00:29:19 +02:00
# include "../hch/CObjectHandler.h"
2009-01-11 00:08:18 +02:00
# include "../hch/CBuildingHandler.h"
# include "../hch/CSpellHandler.h"
2008-11-09 00:29:19 +02:00
# include "../lib/Connection.h"
2009-01-11 00:08:18 +02:00
# include "../lib/Interprocess.h"
2008-07-26 16:57:32 +03:00
# include "../lib/NetPacks.h"
2008-11-09 00:29:19 +02:00
# include "../lib/VCMI_Lib.h"
# include "../map.h"
# include "../mapHandler.h"
# include "CConfigHandler.h"
# include "Client.h"
2008-07-27 20:07:37 +03:00
# include <boost/bind.hpp>
2008-08-01 14:21:15 +03:00
# include <boost/foreach.hpp>
2008-11-09 00:29:19 +02:00
# include <boost/thread.hpp>
2008-07-30 20:51:19 +03:00
# include <boost/thread/shared_mutex.hpp>
2008-12-27 03:01:59 +02:00
# include <sstream>
2008-07-28 15:44:08 +03:00
CSharedCond < std : : set < IPack * > > mess ( new std : : set < IPack * > ) ;
2009-01-11 00:08:18 +02:00
extern std : : string NAME ;
namespace intpr = boost : : interprocess ;
2008-07-28 15:44:08 +03:00
2009-01-30 23:28:02 +02:00
void CClient : : init ( )
2008-07-25 20:28:28 +03:00
{
2009-02-01 16:11:41 +02:00
IObjectInterface : : cb = this ;
2009-01-11 00:08:18 +02:00
serv = NULL ;
gs = NULL ;
cb = NULL ;
2009-01-31 00:23:13 +02:00
try
{
shared = new SharedMem ( ) ;
} HANDLE_EXCEPTION
2009-01-30 23:28:02 +02:00
}
CClient : : CClient ( void )
{
init ( ) ;
2008-07-25 20:28:28 +03:00
}
CClient : : CClient ( CConnection * con , StartInfo * si )
2009-01-11 00:08:18 +02:00
{
2009-01-30 23:28:02 +02:00
init ( ) ;
2009-01-11 00:08:18 +02:00
newGame ( con , si ) ;
2008-07-25 20:28:28 +03:00
}
CClient : : ~ CClient ( void )
{
2009-01-30 23:28:02 +02:00
delete shared ;
2008-07-25 20:28:28 +03:00
}
void CClient : : process ( int what )
{
2008-09-29 00:01:49 +03:00
static BattleAction curbaction ;
2008-07-25 20:28:28 +03:00
switch ( what )
{
2009-02-01 16:11:41 +02:00
case 95 : //system message
{
std : : string m ;
* serv > > m ;
tlog4 < < " System message from server: " < < m < < std : : endl ;
break ;
}
2008-11-15 02:55:19 +02:00
case 100 : //one of our interfaces has turn
2008-07-26 16:57:32 +03:00
{
ui8 player ;
* serv > > player ; //who?
2008-09-19 11:16:19 +03:00
tlog5 < < " It's turn of " < < ( unsigned ) player < < " player. " < < std : : endl ;
2008-11-15 02:55:19 +02:00
gs - > currentPlayer = player ;
2008-07-28 15:44:08 +03:00
boost : : thread ( boost : : bind ( & CGameInterface : : yourTurn , playerint [ player ] ) ) ;
2008-07-26 16:57:32 +03:00
break ;
}
case 101 :
{
NewTurn n ;
* serv > > n ;
2008-09-19 11:16:19 +03:00
tlog5 < < " New day: " < < ( unsigned ) n . day < < " . Applying changes... " ;
2008-07-26 16:57:32 +03:00
gs - > apply ( & n ) ;
2008-09-19 11:16:19 +03:00
tlog5 < < " done! " < < std : : endl ;
2008-07-26 16:57:32 +03:00
break ;
}
2008-07-31 00:27:15 +03:00
case 102 : //set resource amount
{
SetResource sr ;
* serv > > sr ;
2009-01-06 20:42:20 +02:00
tlog5 < < " Set amount of " < < CGI - > generaltexth - > restypes [ sr . resid ]
2008-07-31 00:27:15 +03:00
< < " of player " < < ( unsigned ) sr . player < < " to " < < sr . val < < std : : endl ;
gs - > apply ( & sr ) ;
playerint [ sr . player ] - > receivedResource ( sr . resid , sr . val ) ;
break ;
}
case 103 : //show info dialog
{
InfoWindow iw ;
* serv > > iw ;
2008-07-31 13:35:22 +03:00
std : : vector < Component * > comps ;
2008-12-21 21:17:35 +02:00
for ( size_t i = 0 ; i < iw . components . size ( ) ; i + + ) {
2008-07-31 13:35:22 +03:00
comps . push_back ( & iw . components [ i ] ) ;
2008-12-21 21:17:35 +02:00
}
2008-08-17 17:09:30 +03:00
std : : string str = toString ( iw . text ) ;
playerint [ iw . player ] - > showInfoDialog ( str , comps ) ;
2008-07-31 13:35:22 +03:00
break ;
2008-07-31 00:27:15 +03:00
}
2008-08-01 14:21:15 +03:00
case 104 :
{
SetResources sr ;
* serv > > sr ;
2008-09-19 11:16:19 +03:00
tlog5 < < " Set amount of resources of player " < < ( unsigned ) sr . player < < std : : endl ;
2008-08-01 14:21:15 +03:00
gs - > apply ( & sr ) ;
playerint [ sr . player ] - > receivedResource ( - 1 , - 1 ) ;
break ;
}
2008-08-04 18:56:36 +03:00
case 105 :
{
SetPrimSkill sps ;
* serv > > sps ;
2008-09-19 11:16:19 +03:00
tlog5 < < " Changing hero primary skill " < < std : : endl ;
2008-08-04 18:56:36 +03:00
gs - > apply ( & sps ) ;
playerint [ gs - > getHero ( sps . id ) - > tempOwner ] - > heroPrimarySkillChanged ( gs - > getHero ( sps . id ) , sps . which , sps . val ) ;
break ;
}
2008-08-13 03:44:31 +03:00
case 106 :
{
SetSecSkill sr ;
* serv > > sr ;
2008-09-19 11:16:19 +03:00
tlog5 < < " Changing hero secondary skill " < < std : : endl ;
2008-08-13 03:44:31 +03:00
gs - > apply ( & sr ) ;
//TODO? - maybe inform interfaces
break ;
}
2008-08-04 18:56:36 +03:00
case 107 :
{
ShowInInfobox sii ;
* serv > > sii ;
SComponent sc ( sii . c ) ;
sc . description = toString ( sii . text ) ;
if ( playerint [ sii . player ] - > human )
static_cast < CPlayerInterface * > ( playerint [ sii . player ] ) - > showComp ( sc ) ;
break ;
}
2008-08-13 12:28:06 +03:00
case 108 :
{
HeroVisitCastle vc ;
* serv > > vc ;
gs - > apply ( & vc ) ;
if ( vc . start ( ) & & ! vc . garrison ( ) & & vstd : : contains ( playerint , gs - > getHero ( vc . hid ) - > tempOwner ) )
{
playerint [ gs - > getHero ( vc . hid ) - > tempOwner ] - > heroVisitsTown ( gs - > getHero ( vc . hid ) , gs - > getTown ( vc . tid ) ) ;
}
break ;
}
2008-09-12 11:51:46 +03:00
case 109 :
{
ChangeSpells vc ;
* serv > > vc ;
2008-09-19 11:16:19 +03:00
tlog5 < < " Changing spells of hero " < < vc . hid < < std : : endl ;
2008-09-12 11:51:46 +03:00
gs - > apply ( & vc ) ;
break ;
}
2008-10-19 02:20:48 +03:00
case 110 :
{
SetMana sm ;
* serv > > sm ;
tlog5 < < " Setting mana value of hero " < < sm . hid < < " to " < < sm . val < < std : : endl ;
gs - > apply ( & sm ) ;
CGHeroInstance * h = gs - > getHero ( sm . hid ) ;
if ( vstd : : contains ( playerint , h - > tempOwner ) )
playerint [ h - > tempOwner ] - > heroManaPointsChanged ( h ) ;
break ;
}
case 111 :
{
SetMovePoints smp ;
* serv > > smp ;
tlog5 < < " Setting movement points of hero " < < smp . hid < < " to " < < smp . val < < std : : endl ;
gs - > apply ( & smp ) ;
CGHeroInstance * h = gs - > getHero ( smp . hid ) ;
if ( vstd : : contains ( playerint , h - > tempOwner ) )
playerint [ h - > tempOwner ] - > heroMovePointsChanged ( h ) ;
break ;
}
case 112 :
{
FoWChange fc ;
* serv > > fc ;
tlog5 < < " Changing FoW of player " < < ( int ) fc . player < < std : : endl ;
gs - > apply ( & fc ) ;
if ( ! vstd : : contains ( playerint , fc . player ) )
break ;
if ( fc . mode )
playerint [ fc . player ] - > tileRevealed ( fc . tiles ) ;
else
playerint [ fc . player ] - > tileHidden ( fc . tiles ) ;
break ;
}
2008-10-26 22:58:34 +02:00
case 113 :
{
SetAvailableHeroes sav ;
* serv > > sav ;
tlog5 < < " Setting available heroes for player " < < ( int ) sav . player < < std : : endl ;
gs - > apply ( & sav ) ;
break ;
}
2009-02-03 07:28:05 +02:00
case 115 :
{
GiveBonus gb ;
* serv > > gb ;
tlog5 < < " Hero receives bonus \n " ;
gs - > apply ( & gb ) ;
break ;
}
2008-08-02 00:41:38 +03:00
case 500 :
{
2008-08-13 07:41:11 +03:00
RemoveObject rh ;
2008-08-02 00:41:38 +03:00
* serv > > rh ;
2008-08-13 07:41:11 +03:00
CGObjectInstance * obj = gs - > map - > objects [ rh . id ] ;
2008-08-17 12:11:16 +03:00
CGI - > mh - > removeObject ( obj ) ;
gs - > apply ( & rh ) ;
2008-08-13 07:41:11 +03:00
if ( obj - > ID = = 34 )
{
2008-08-17 12:11:16 +03:00
CGHeroInstance * h = static_cast < CGHeroInstance * > ( obj ) ;
2008-09-19 11:16:19 +03:00
tlog5 < < " Removing hero with id = " < < ( unsigned ) rh . id < < std : : endl ;
2008-08-13 07:41:11 +03:00
playerint [ h - > tempOwner ] - > heroKilled ( h ) ;
}
2008-08-02 00:41:38 +03:00
break ;
}
2008-07-28 15:44:08 +03:00
case 501 : //hero movement response - we have to notify interfaces and callback
{
2008-07-30 20:51:19 +03:00
TryMoveHero * th = new TryMoveHero ; //will be deleted by callback after processing
2008-07-28 15:44:08 +03:00
* serv > > * th ;
2008-09-19 11:16:19 +03:00
tlog5 < < " HeroMove: id= " < < th - > id < < " \t Result: " < < ( unsigned ) th - > result < < " \t Position " < < th - > end < < std : : endl ;
2008-07-28 15:44:08 +03:00
2008-09-23 13:58:54 +03:00
HeroMoveDetails hmd ( th - > start , th - > end , static_cast < CGHeroInstance * > ( gs - > map - > objects [ th - > id ] ) ) ;
hmd . style = th - > result - 1 ;
hmd . successful = th - > result ;
if ( th - > result > 1 )
CGI - > mh - > removeObject ( hmd . ho ) ;
2008-07-28 15:44:08 +03:00
gs - > apply ( th ) ;
2008-09-23 13:58:54 +03:00
if ( th - > result > 1 )
CGI - > mh - > printObject ( hmd . ho ) ;
2008-07-28 15:44:08 +03:00
int player = gs - > map - > objects [ th - > id ] - > getOwner ( ) ;
if ( playerint [ player ] )
{
2008-10-19 02:20:48 +03:00
playerint [ player ] - > tileRevealed ( th - > fowRevealed ) ;
2008-08-06 01:11:32 +03:00
//std::for_each(th->fowRevealed.begin(),th->fowRevealed.end(),boost::bind(&CGameInterface::tileRevealed,playerint[player],_1));
2008-07-28 15:44:08 +03:00
}
2008-11-15 02:55:19 +02:00
//notify interfaces about move
2008-07-28 15:44:08 +03:00
for ( std : : map < ui8 , CGameInterface * > : : iterator i = playerint . begin ( ) ; i ! = playerint . end ( ) ; i + + )
{
2008-11-15 02:55:19 +02:00
if ( i - > first > = PLAYER_LIMIT ) continue ;
2008-07-28 15:44:08 +03:00
if ( gs - > players [ i - > first ] . fogOfWarMap [ th - > start . x - 1 ] [ th - > start . y ] [ th - > start . z ] | | gs - > players [ i - > first ] . fogOfWarMap [ th - > end . x - 1 ] [ th - > end . y ] [ th - > end . z ] )
{
i - > second - > heroMoved ( hmd ) ;
}
}
//add info for callback
2008-09-23 13:58:54 +03:00
if ( th - > result < 2 )
{
mess . mx - > lock ( ) ;
mess . res - > insert ( th ) ;
mess . mx - > unlock ( ) ;
mess . cv - > notify_all ( ) ;
}
2008-07-28 15:44:08 +03:00
break ;
}
2008-07-31 16:21:42 +03:00
case 502 :
{
SetGarrisons sg ;
* serv > > sg ;
2008-09-19 11:16:19 +03:00
tlog5 < < " Setting garrisons. " < < std : : endl ;
2008-07-31 16:21:42 +03:00
gs - > apply ( & sg ) ;
for ( std : : map < ui32 , CCreatureSet > : : iterator i = sg . garrs . begin ( ) ; i ! = sg . garrs . end ( ) ; i + + )
playerint [ gs - > map - > objects [ i - > first ] - > tempOwner ] - > garrisonChanged ( gs - > map - > objects [ i - > first ] ) ;
break ;
}
2008-08-01 14:21:15 +03:00
case 503 :
{
2008-08-10 07:46:16 +03:00
//SetStrInfo ssi;
//*serv >> ssi;
//gs->apply(&ssi);
2008-08-01 14:21:15 +03:00
//TODO: notify interfaces
break ;
}
case 504 :
{
NewStructures ns ;
* serv > > ns ;
2008-08-20 09:57:53 +03:00
CGTownInstance * town = static_cast < CGTownInstance * > ( gs - > map - > objects [ ns . tid ] ) ;
2008-09-19 11:16:19 +03:00
tlog5 < < " New structure(s) in " < < ns . tid < < " " < < town - > name < < " - " < < * ns . bid . begin ( ) < < std : : endl ;
2008-08-01 14:21:15 +03:00
gs - > apply ( & ns ) ;
BOOST_FOREACH ( si32 bid , ns . bid )
2008-08-20 09:57:53 +03:00
{
if ( bid = = 13 ) //for or capitol
{
town - > defInfo = gs - > capitols [ town - > subID ] ;
}
if ( bid = = 7 )
{
town - > defInfo = gs - > forts [ town - > subID ] ;
}
playerint [ town - > tempOwner ] - > buildChanged ( town , bid , 1 ) ;
}
2008-08-01 14:21:15 +03:00
break ;
}
2008-08-10 07:46:16 +03:00
case 506 :
{
SetAvailableCreatures ns ;
* serv > > ns ;
2008-09-19 11:16:19 +03:00
tlog5 < < " Setting available creatures in " < < ns . tid < < std : : endl ;
2008-08-10 07:46:16 +03:00
gs - > apply ( & ns ) ;
2008-08-30 00:41:32 +03:00
CGTownInstance * t = gs - > getTown ( ns . tid ) ;
if ( vstd : : contains ( playerint , t - > tempOwner ) )
playerint [ t - > tempOwner ] - > availableCreaturesChanged ( t ) ;
2008-08-10 07:46:16 +03:00
break ;
}
2008-08-16 11:47:41 +03:00
case 508 :
{
SetHeroesInTown inTown ;
* serv > > inTown ;
2008-09-19 11:16:19 +03:00
tlog5 < < " Setting heroes in town " < < inTown . tid < < std : : endl ;
2008-08-16 11:47:41 +03:00
gs - > apply ( & inTown ) ;
CGTownInstance * t = gs - > getTown ( inTown . tid ) ;
if ( vstd : : contains ( playerint , t - > tempOwner ) )
playerint [ t - > tempOwner ] - > heroInGarrisonChange ( t ) ;
break ;
}
2008-08-20 22:02:48 +03:00
case 509 :
{
SetHeroArtifacts sha ;
* serv > > sha ;
2008-09-19 11:16:19 +03:00
tlog5 < < " Setting artifacts of hero " < < sha . hid < < std : : endl ;
2008-08-20 22:02:48 +03:00
gs - > apply ( & sha ) ;
2008-08-25 13:25:16 +03:00
CGHeroInstance * t = gs - > getHero ( sha . hid ) ;
if ( vstd : : contains ( playerint , t - > tempOwner ) )
playerint [ t - > tempOwner ] - > heroArtifactSetChanged ( t ) ;
2008-08-20 22:02:48 +03:00
break ;
}
2008-10-19 02:20:48 +03:00
case 513 :
{
ui8 color ;
std : : string message ;
* serv > > color > > message ;
tlog4 < < " Player " < < ( int ) color < < " sends a message: " < < message < < std : : endl ;
break ;
}
2008-12-27 03:01:59 +02:00
case 514 :
{
SetSelection ss ;
* serv > > ss ;
tlog5 < < " Selection of player " < < ( int ) ss . player < < " set to " < < ss . id < < std : : endl ;
gs - > apply ( & ss ) ;
break ;
}
2008-10-26 22:58:34 +02:00
case 515 :
{
HeroRecruited hr ;
* serv > > hr ;
tlog5 < < " New hero bought \n " ;
CGHeroInstance * h = gs - > hpool . heroesPool [ hr . hid ] ;
gs - > apply ( & hr ) ;
CGI - > mh - > initHeroDef ( h ) ;
//CGI->mh->printObject(h);
playerint [ h - > tempOwner ] - > heroCreated ( h ) ;
playerint [ h - > tempOwner ] - > heroInGarrisonChange ( gs - > getTown ( hr . tid ) ) ;
break ;
}
2008-07-30 20:51:19 +03:00
case 1001 :
{
SetObjectProperty sop ;
* serv > > sop ;
2008-09-19 11:16:19 +03:00
tlog5 < < " Setting " < < ( unsigned ) sop . what < < " property of " < < sop . id < < " object to " < < sop . val < < std : : endl ;
2008-07-30 20:51:19 +03:00
gs - > apply ( & sop ) ;
break ;
}
case 1002 :
{
SetHoverName shn ;
* serv > > shn ;
2008-09-19 11:16:19 +03:00
tlog5 < < " Setting a name of " < < shn . id < < " object to " < < toString ( shn . name ) < < std : : endl ;
2008-12-27 03:01:59 +02:00
gs - > apply ( & shn ) ;
2008-08-04 18:56:36 +03:00
break ;
}
2008-08-13 03:44:31 +03:00
case 2000 :
{
HeroLevelUp bs ;
* serv > > bs ;
2008-09-19 11:16:19 +03:00
tlog5 < < " Hero levels up! " < < std : : endl ;
2008-08-13 03:44:31 +03:00
gs - > apply ( & bs ) ;
CGHeroInstance * h = gs - > getHero ( bs . heroid ) ;
if ( vstd : : contains ( playerint , h - > tempOwner ) )
2008-08-17 17:09:30 +03:00
{
2008-09-18 16:54:54 +03:00
boost : : function < void ( ui32 ) > callback = boost : : function < void ( ui32 ) > ( boost : : bind ( & CCallback : : selectionMade , LOCPLINT - > cb , _1 , bs . id ) ) ;
2008-08-17 17:09:30 +03:00
playerint [ h - > tempOwner ] - > heroGotLevel ( ( const CGHeroInstance * ) h , ( int ) bs . primskill , bs . skills , callback ) ;
}
2008-08-13 03:44:31 +03:00
break ;
}
case 2001 :
{
SelectionDialog sd ;
* serv > > sd ;
2008-09-19 11:16:19 +03:00
tlog5 < < " Showing selection dialog " < < std : : endl ;
2008-08-13 03:44:31 +03:00
std : : vector < Component * > comps ;
2008-12-21 21:17:35 +02:00
for ( size_t i = 0 ; i < sd . components . size ( ) ; + + i ) {
2008-08-13 03:44:31 +03:00
comps . push_back ( & sd . components [ i ] ) ;
2008-12-21 21:17:35 +02:00
}
2008-08-17 17:09:30 +03:00
std : : string str = toString ( sd . text ) ;
playerint [ sd . player ] - > showSelDialog ( str , comps , sd . id ) ;
2008-08-13 03:44:31 +03:00
break ;
}
2008-08-22 15:21:09 +03:00
case 2002 :
{
YesNoDialog ynd ;
* serv > > ynd ;
2008-09-19 11:16:19 +03:00
tlog5 < < " Showing yes/no dialog " < < std : : endl ;
2008-08-22 15:21:09 +03:00
std : : vector < Component * > comps ;
2008-12-21 21:17:35 +02:00
for ( size_t i = 0 ; i < ynd . components . size ( ) ; + + i ) {
2008-08-22 15:21:09 +03:00
comps . push_back ( & ynd . components [ i ] ) ;
2008-12-21 21:17:35 +02:00
}
2008-08-22 15:21:09 +03:00
std : : string str = toString ( ynd . text ) ;
playerint [ ynd . player ] - > showYesNoDialog ( str , comps , ynd . id ) ;
break ;
}
2008-08-04 18:56:36 +03:00
case 3000 :
{
BattleStart bs ;
* serv > > bs ; //uses new to allocate memory for battleInfo - must be deleted when battle is over
2008-09-19 11:16:19 +03:00
tlog5 < < " Starting battle! " < < std : : endl ;
2008-08-04 18:56:36 +03:00
gs - > apply ( & bs ) ;
if ( playerint . find ( gs - > curB - > side1 ) ! = playerint . end ( ) )
playerint [ gs - > curB - > side1 ] - > battleStart ( & gs - > curB - > army1 , & gs - > curB - > army2 , gs - > curB - > tile , gs - > getHero ( gs - > curB - > hero1 ) , gs - > getHero ( gs - > curB - > hero2 ) , 0 ) ;
if ( playerint . find ( gs - > curB - > side2 ) ! = playerint . end ( ) )
playerint [ gs - > curB - > side2 ] - > battleStart ( & gs - > curB - > army1 , & gs - > curB - > army2 , gs - > curB - > tile , gs - > getHero ( gs - > curB - > hero1 ) , gs - > getHero ( gs - > curB - > hero2 ) , 1 ) ;
break ;
}
case 3001 :
{
BattleNextRound bnr ;
* serv > > bnr ;
2008-09-19 11:16:19 +03:00
tlog5 < < " Round nr " < < bnr . round < < std : : endl ;
2008-08-04 18:56:36 +03:00
gs - > apply ( & bnr ) ;
//tell players about next round
if ( playerint . find ( gs - > curB - > side1 ) ! = playerint . end ( ) )
playerint [ gs - > curB - > side1 ] - > battleNewRound ( bnr . round ) ;
if ( playerint . find ( gs - > curB - > side2 ) ! = playerint . end ( ) )
playerint [ gs - > curB - > side2 ] - > battleNewRound ( bnr . round ) ;
break ;
}
case 3002 :
{
BattleSetActiveStack sas ;
* serv > > sas ;
2008-09-19 11:16:19 +03:00
tlog5 < < " Active stack: " < < sas . stack < < std : : endl ;
2008-08-04 18:56:36 +03:00
gs - > apply ( & sas ) ;
2008-08-06 02:33:08 +03:00
int owner = gs - > curB - > getStack ( sas . stack ) - > owner ;
2008-11-15 02:55:19 +02:00
boost : : thread ( boost : : bind ( & CClient : : waitForMoveAndSend , this , owner ) ) ;
2008-08-04 18:56:36 +03:00
break ;
}
case 3003 :
{
BattleResult br ;
* serv > > br ;
2008-09-19 11:16:19 +03:00
tlog5 < < " Battle ends. Winner: " < < ( unsigned ) br . winner < < " . Type of end: " < < ( unsigned ) br . result < < std : : endl ;
2008-08-04 18:56:36 +03:00
if ( playerint . find ( gs - > curB - > side1 ) ! = playerint . end ( ) )
playerint [ gs - > curB - > side1 ] - > battleEnd ( & br ) ;
if ( playerint . find ( gs - > curB - > side2 ) ! = playerint . end ( ) )
playerint [ gs - > curB - > side2 ] - > battleEnd ( & br ) ;
gs - > apply ( & br ) ;
2008-08-05 02:04:15 +03:00
break ;
}
case 3004 :
{
BattleStackMoved br ;
* serv > > br ;
2008-09-19 11:16:19 +03:00
tlog5 < < " Stack " < < br . stack < < " moves to the tile " < < br . tile < < std : : endl ;
2008-08-05 02:04:15 +03:00
if ( playerint . find ( gs - > curB - > side1 ) ! = playerint . end ( ) )
2008-09-29 00:01:49 +03:00
playerint [ gs - > curB - > side1 ] - > battleStackMoved ( br . stack , br . tile ) ;
2008-08-05 02:04:15 +03:00
if ( playerint . find ( gs - > curB - > side2 ) ! = playerint . end ( ) )
2008-09-29 00:01:49 +03:00
playerint [ gs - > curB - > side2 ] - > battleStackMoved ( br . stack , br . tile ) ;
2008-08-05 02:04:15 +03:00
gs - > apply ( & br ) ;
2008-07-30 20:51:19 +03:00
break ;
}
2008-10-18 14:41:24 +03:00
case 3005 :
{
BattleStackAttacked bsa ;
* serv > > bsa ;
gs - > apply ( & bsa ) ;
if ( playerint . find ( gs - > curB - > side1 ) ! = playerint . end ( ) )
playerint [ gs - > curB - > side1 ] - > battleStackAttacked ( & bsa ) ;
if ( playerint . find ( gs - > curB - > side2 ) ! = playerint . end ( ) )
playerint [ gs - > curB - > side2 ] - > battleStackAttacked ( & bsa ) ;
break ;
}
2008-08-09 02:02:32 +03:00
case 3006 :
{
BattleAttack ba ;
* serv > > ba ;
2008-09-19 11:16:19 +03:00
tlog5 < < " Stack: " < < ba . stackAttacking < < " is attacking stack " < < ba . bsa . stackAttacked < < std : : endl ;
2008-10-11 16:14:52 +03:00
if ( playerint . find ( gs - > curB - > side1 ) ! = playerint . end ( ) )
playerint [ gs - > curB - > side1 ] - > battleAttack ( & ba ) ;
if ( playerint . find ( gs - > curB - > side2 ) ! = playerint . end ( ) )
playerint [ gs - > curB - > side2 ] - > battleAttack ( & ba ) ;
2008-08-09 02:02:32 +03:00
gs - > apply ( & ba ) ;
2008-10-11 16:14:52 +03:00
if ( playerint . find ( gs - > curB - > side1 ) ! = playerint . end ( ) )
playerint [ gs - > curB - > side1 ] - > battleStackAttacked ( & ba . bsa ) ;
if ( playerint . find ( gs - > curB - > side2 ) ! = playerint . end ( ) )
playerint [ gs - > curB - > side2 ] - > battleStackAttacked ( & ba . bsa ) ;
2008-08-09 02:02:32 +03:00
break ;
}
2008-09-29 00:01:49 +03:00
case 3007 :
{
* serv > > curbaction ;
2008-10-18 14:41:24 +03:00
tlog5 < < " Action started. ID: " < < ( int ) curbaction . actionType < < " . Destination: " < < curbaction . destinationTile < < std : : endl ;
2008-09-29 00:01:49 +03:00
if ( playerint . find ( gs - > curB - > side1 ) ! = playerint . end ( ) )
playerint [ gs - > curB - > side1 ] - > actionStarted ( & curbaction ) ;
if ( playerint . find ( gs - > curB - > side2 ) ! = playerint . end ( ) )
playerint [ gs - > curB - > side2 ] - > actionStarted ( & curbaction ) ;
2008-11-15 17:26:08 +02:00
gs - > apply ( & StartAction ( curbaction ) ) ;
2008-09-29 00:01:49 +03:00
break ;
}
case 3008 :
{
tlog5 < < " Action ended! \n " ;
if ( ! gs - > curB )
{
tlog2 < < " There is no battle state! \n " ;
break ;
}
if ( playerint . find ( gs - > curB - > side1 ) ! = playerint . end ( ) )
playerint [ gs - > curB - > side1 ] - > actionFinished ( & curbaction ) ;
if ( playerint . find ( gs - > curB - > side2 ) ! = playerint . end ( ) )
playerint [ gs - > curB - > side2 ] - > actionFinished ( & curbaction ) ;
break ;
}
2008-10-18 14:41:24 +03:00
case 3009 :
{
tlog5 < < " Spell casted! \n " ;
SpellCasted sc ;
* serv > > sc ;
gs - > apply ( & sc ) ;
2008-11-09 00:29:19 +02:00
if ( playerint . find ( gs - > curB - > side1 ) ! = playerint . end ( ) )
playerint [ gs - > curB - > side1 ] - > battleSpellCasted ( & sc ) ;
if ( playerint . find ( gs - > curB - > side2 ) ! = playerint . end ( ) )
playerint [ gs - > curB - > side2 ] - > battleSpellCasted ( & sc ) ;
break ;
}
case 3010 :
{
tlog5 < < " Effect set! \n " ;
SetStackEffect sse ;
* serv > > sse ;
gs - > apply ( & sse ) ;
SpellCasted sc ;
2009-01-16 19:58:41 +02:00
sc . id = sse . effect . id ;
2008-11-09 00:29:19 +02:00
sc . side = 3 ; //doesn't matter
sc . skill = sse . effect . level ;
sc . tile = gs - > curB - > getStack ( sse . stack ) - > position ;
2008-10-18 14:41:24 +03:00
if ( playerint . find ( gs - > curB - > side1 ) ! = playerint . end ( ) )
playerint [ gs - > curB - > side1 ] - > battleSpellCasted ( & sc ) ;
if ( playerint . find ( gs - > curB - > side2 ) ! = playerint . end ( ) )
playerint [ gs - > curB - > side2 ] - > battleSpellCasted ( & sc ) ;
break ;
}
2008-07-30 20:51:19 +03:00
case 9999 :
break ;
2008-07-25 20:28:28 +03:00
default :
2008-12-27 03:01:59 +02:00
{
std : : ostringstream ex ;
ex < < " Not supported server message (type= " < < what < < " ) " ;
throw ex . str ( ) ;
}
2008-07-25 20:28:28 +03:00
}
}
2008-08-04 18:56:36 +03:00
void CClient : : waitForMoveAndSend ( int color )
{
2008-08-30 00:41:32 +03:00
try
{
BattleAction ba = playerint [ color ] - > activeStack ( gs - > curB - > activeStack ) ;
* serv < < ui16 ( 3002 ) < < ba ;
return ;
} HANDLE_EXCEPTION
2008-09-19 11:16:19 +03:00
tlog1 < < " We should not be here! " < < std : : endl ;
2008-08-04 18:56:36 +03:00
}
2008-07-25 20:28:28 +03:00
void CClient : : run ( )
{
try
{
ui16 typ ;
while ( 1 )
{
* serv > > typ ;
process ( typ ) ;
}
} HANDLE_EXCEPTION
2008-08-04 12:05:52 +03:00
}
2008-08-25 13:25:16 +03:00
void CClient : : close ( )
{
2009-01-11 00:08:18 +02:00
if ( ! serv )
return ;
2008-09-19 11:16:19 +03:00
tlog3 < < " Connection has been requested to be closed. \n " ;
2008-08-28 20:36:34 +03:00
boost : : unique_lock < boost : : mutex > ( * serv - > wmx ) ;
* serv < < ui16 ( 99 ) ;
2009-01-11 00:08:18 +02:00
tlog3 < < " Sent closing signal to the server \n " ;
2008-08-25 13:25:16 +03:00
serv - > close ( ) ;
2008-09-19 11:16:19 +03:00
tlog3 < < " Our socket has been closed. \n " ;
2008-08-25 13:25:16 +03:00
}
2008-11-16 03:06:15 +02:00
void CClient : : save ( const std : : string & fname )
{
* serv < < ui16 ( 98 ) < < fname ;
}
2008-12-27 03:01:59 +02:00
2009-01-11 00:08:18 +02:00
void CClient : : load ( const std : : string & fname )
{
tlog0 < < " \n \n Loading procedure started! \n \n " ;
timeHandler tmh ;
close ( ) ; //kill server
tlog0 < < " Sent kill signal to the server: " < < tmh . getDif ( ) < < std : : endl ;
VLC - > clear ( ) ; //delete old handlers
delete CGI - > mh ;
delete CGI - > state ;
//TODO: del callbacks
for ( std : : map < ui8 , CGameInterface * > : : iterator i = playerint . begin ( ) ; i ! = playerint . end ( ) ; i + + )
{
delete i - > second ; //delete player interfaces
}
tlog0 < < " Deleting old data: " < < tmh . getDif ( ) < < std : : endl ;
char portc [ 10 ] ;
SDL_itoa ( conf . cc . port , portc , 10 ) ;
runServer ( portc ) ; //create new server
tlog0 < < " Restarting server: " < < tmh . getDif ( ) < < std : : endl ;
{
2009-02-01 16:11:41 +02:00
ui32 ver ;
2009-01-11 00:08:18 +02:00
char sig [ 8 ] ;
CMapHeader dum ;
CGI - > mh = new CMapHandler ( ) ;
CLoadFile lf ( fname + " .vlgm1 " ) ;
2009-02-01 16:11:41 +02:00
lf > > sig > > ver > > dum > > * sig ;
2009-01-11 00:08:18 +02:00
tlog0 < < " Reading save signature: " < < tmh . getDif ( ) < < std : : endl ;
lf > > * VLC ;
CGI - > setFromLib ( ) ;
tlog0 < < " Reading handlers: " < < tmh . getDif ( ) < < std : : endl ;
lf > > gs ;
tlog0 < < " Reading gamestate: " < < tmh . getDif ( ) < < std : : endl ;
CGI - > state = gs ;
CGI - > mh - > map = gs - > map ;
CGI - > mh - > init ( ) ;
tlog0 < < " Initing maphandler: " < < tmh . getDif ( ) < < std : : endl ;
}
waitForServer ( ) ;
tlog0 < < " Waiting for server: " < < tmh . getDif ( ) < < std : : endl ;
serv = new CConnection ( conf . cc . server , portc , NAME ) ;
tlog0 < < " Setting up connection: " < < tmh . getDif ( ) < < std : : endl ;
ui8 pom8 ;
* serv < < ui8 ( 3 ) < < ui8 ( 1 ) ; //load game; one client
* serv < < fname ;
* serv > > pom8 ;
if ( pom8 )
throw " Server cannot open the savegame! " ;
else
tlog0 < < " Server opened savegame properly. \n " ;
* serv < < ui8 ( gs - > scenarioOps - > playerInfos . size ( ) + 1 ) ; //number of players + neutral
for ( size_t i = 0 ; i < gs - > scenarioOps - > playerInfos . size ( ) ; i + + )
{
* serv < < ui8 ( gs - > scenarioOps - > playerInfos [ i ] . color ) ; //players
}
* serv < < ui8 ( 255 ) ; // neutrals
tlog0 < < " Sent info to server: " < < tmh . getDif ( ) < < std : : endl ;
for ( size_t i = 0 ; i < gs - > scenarioOps - > playerInfos . size ( ) ; + + i ) //initializing interfaces for players
{
ui8 color = gs - > scenarioOps - > playerInfos [ i ] . color ;
CCallback * cb = new CCallback ( gs , color , this ) ;
if ( ! gs - > scenarioOps - > playerInfos [ i ] . human ) {
playerint [ color ] = static_cast < CGameInterface * > ( CAIHandler : : getNewAI ( cb , conf . cc . defaultAI ) ) ;
}
else {
playerint [ color ] = new CPlayerInterface ( color , i ) ;
}
gs - > currentPlayer = color ;
playerint [ color ] - > init ( cb ) ;
tlog0 < < " Setting up interface for player " < < ( int ) color < < " : " < < tmh . getDif ( ) < < std : : endl ;
}
playerint [ 255 ] = CAIHandler : : getNewAI ( cb , conf . cc . defaultAI ) ;
playerint [ 255 ] - > init ( new CCallback ( gs , 255 , this ) ) ;
tlog0 < < " Setting up interface for neutral \" player \" " < < tmh . getDif ( ) < < std : : endl ;
}
2008-12-27 03:01:59 +02:00
int CClient : : getCurrentPlayer ( )
{
return gs - > currentPlayer ;
}
int CClient : : getSelectedHero ( )
{
return IGameCallback : : getSelectedHero ( getCurrentPlayer ( ) ) - > id ;
2009-01-11 00:08:18 +02:00
}
void CClient : : newGame ( CConnection * con , StartInfo * si )
{
timeHandler tmh ;
CGI - > state = new CGameState ( ) ;
tlog0 < < " \t Gamestate: " < < tmh . getDif ( ) < < std : : endl ;
serv = con ;
CConnection & c ( * con ) ;
////////////////////////////////////////////////////
ui8 pom8 ;
c < < ui8 ( 2 ) < < ui8 ( 1 ) ; //new game; one client
c < < * si ;
c > > pom8 ;
if ( pom8 )
throw " Server cannot open the map! " ;
else
tlog0 < < " Server opened map properly. \n " ;
c < < ui8 ( si - > playerInfos . size ( ) + 1 ) ; //number of players + neutral
for ( size_t i = 0 ; i < si - > playerInfos . size ( ) ; i + + )
{
c < < ui8 ( si - > playerInfos [ i ] . color ) ; //players
}
c < < ui8 ( 255 ) ; // neutrals
ui32 seed , sum ;
std : : string mapname ;
c > > mapname > > sum > > seed ;
tlog0 < < " \t Sending/Getting info to/from the server: " < < tmh . getDif ( ) < < std : : endl ;
Mapa * mapa = new Mapa ( mapname ) ;
tlog0 < < " Reading and detecting map file (together): " < < tmh . getDif ( ) < < std : : endl ;
tlog0 < < " \t Server checksum for " < < mapname < < " : " < < sum < < std : : endl ;
tlog0 < < " \t Our checksum for the map: " < < mapa - > checksum < < std : : endl ;
if ( mapa - > checksum ! = sum )
{
tlog1 < < " Wrong map checksum!!! " < < std : : endl ;
throw std : : string ( " Wrong checksum " ) ;
}
tlog0 < < " \t Using random seed: " < < seed < < std : : endl ;
gs = CGI - > state ;
gs - > scenarioOps = si ;
gs - > init ( si , mapa , seed ) ;
CGI - > mh = new CMapHandler ( ) ;
tlog0 < < " Initializing GameState (together): " < < tmh . getDif ( ) < < std : : endl ;
CGI - > mh - > map = mapa ;
tlog0 < < " Creating mapHandler: " < < tmh . getDif ( ) < < std : : endl ;
CGI - > mh - > init ( ) ;
tlog0 < < " Initializing mapHandler (together): " < < tmh . getDif ( ) < < std : : endl ;
for ( size_t i = 0 ; i < CGI - > state - > scenarioOps - > playerInfos . size ( ) ; + + i ) //initializing interfaces for players
{
ui8 color = gs - > scenarioOps - > playerInfos [ i ] . color ;
CCallback * cb = new CCallback ( gs , color , this ) ;
if ( ! gs - > scenarioOps - > playerInfos [ i ] . human ) {
playerint [ color ] = static_cast < CGameInterface * > ( CAIHandler : : getNewAI ( cb , conf . cc . defaultAI ) ) ;
}
else {
playerint [ color ] = new CPlayerInterface ( color , i ) ;
}
gs - > currentPlayer = color ;
playerint [ color ] - > init ( cb ) ;
}
playerint [ 255 ] = CAIHandler : : getNewAI ( cb , conf . cc . defaultAI ) ;
playerint [ 255 ] - > init ( new CCallback ( gs , 255 , this ) ) ;
}
void CClient : : runServer ( const char * portc )
{
static std : : string comm = std : : string ( SERVER_NAME ) + " " + portc + " > server_log.txt " ; //needs to be static, if not - will be probably destroyed before new thread reads it
boost : : thread servthr ( boost : : bind ( system , comm . c_str ( ) ) ) ; //runs server executable; //TODO: will it work on non-windows platforms?
}
void CClient : : waitForServer ( )
{
2009-01-30 23:28:02 +02:00
intpr : : scoped_lock < intpr : : interprocess_mutex > slock ( shared - > sr - > mutex ) ;
while ( ! shared - > sr - > ready )
2009-01-11 00:08:18 +02:00
{
2009-01-30 23:28:02 +02:00
shared - > sr - > cond . wait ( slock ) ;
2009-01-11 00:08:18 +02:00
}
2009-01-30 23:28:02 +02:00
}