26 #include "kgamepropertyhandler.h"
27 #include "kgameproperty.h"
30 #include "kgameerror.h"
31 #include "kgamesequence.h"
33 #include "kgamemessage.h"
41 #include <tqptrqueue.h>
45 #include <krandomsequence.h>
48 #define KGAME_LOAD_COOKIE 4210
57 mUniquePlayerNumber = 0;
58 mPolicy=KGame::PolicyLocal;
62 int mUniquePlayerNumber;
63 TQPtrQueue<KPlayer> mAddPlayerList;
64 KRandomSequence* mRandom;
72 KGame::KGamePlayerList mPlayerList;
73 KGame::KGamePlayerList mInactivePlayerList;
79 TQValueList<int> mInactiveIdList;
86 kdDebug(11001) << k_funcinfo <<
" - " <<
this <<
", sizeof(KGame)=" <<
sizeof(
KGame) << endl;
91 d->mProperties->registerHandler(KGameMessage::IdGameProperty,
94 d->mMaxPlayer.registerData(KGamePropertyBase::IdMaxPlayer,
this, i18n(
"MaxPlayers"));
95 d->mMaxPlayer.setLocal(-1);
96 d->mMinPlayer.registerData(KGamePropertyBase::IdMinPlayer,
this, i18n(
"MinPlayers"));
97 d->mMinPlayer.setLocal(0);
98 d->mGameStatus.registerData(KGamePropertyBase::IdGameStatus,
this, i18n(
"GameStatus"));
99 d->mGameStatus.setLocal(Init);
101 d->mRandom =
new KRandomSequence;
102 d->mRandom->setSeed(0);
122 kdDebug(11001) << k_funcinfo << endl;
125 delete d->mGameSequence;
128 kdDebug(11001) << k_funcinfo <<
" done" << endl;
134 deleteInactivePlayers();
138 void KGame::deletePlayers()
141 KGamePlayerList tmp = d->mPlayerList;
143 while((player=tmp.first()))
151 void KGame::deleteInactivePlayers()
154 while((player=d->mInactivePlayerList.first()))
157 d->mInactivePlayerList.remove(player);
164 if (filename.isNull())
169 if (!f.open(IO_ReadOnly))
173 TQDataStream s( &f );
180 {
return loadgame(stream,
false,reset); }
192 kdWarning(11001) <<
"Trying to load different game version we="<<
cookie() <<
" saved=" << c << endl;
197 if (resetgame)
reset();
203 stream >> d->mUniquePlayerNumber;
211 d->mRandom->setSeed(newseed);
236 stream >> playercount;
237 kdDebug(11001) <<
"Loading KGame " << playercount <<
" KPlayer objects " << endl;
238 for (i=0;i<playercount;i++)
246 if (cookie==KGAME_LOAD_COOKIE) {
247 kdDebug(11001) <<
" Game loaded propertly"<<endl;
249 kdError(11001) <<
" Game loading error. probably format error"<<endl;
269 if (filename.isNull())
274 if (!f.open(IO_WriteOnly))
278 TQDataStream s( &f );
285 {
return savegame(stream,
false,saveplayers); }
297 stream << d->mUniquePlayerNumber;
298 int newseed=(int)d->mRandom->getLong(65535);
300 d->mRandom->setSeed(newseed);
317 stream << (TQ_INT16)KGAME_LOAD_COOKIE;
326 stream << (TQ_INT32)p->
rtti();
327 stream << (TQ_INT32)p->
id();
339 TQ_INT32 cnt=list->count();
340 kdDebug(11001) <<
"Saving KGame " << cnt <<
" KPlayer objects " << endl;
343 for ( player=list->first(); player != 0; player=list->next() )
351 kdWarning(11001) <<
" No user defined player created. Creating default KPlayer. This crashes if you have overwritten KPlayer!!!! " << endl;
356 TQ_INT32 rtti,id,iovalue;
357 stream >> rtti >>
id >> iovalue;
361 kdDebug(11001) << k_funcinfo <<
"Player "<<
id <<
" not found...asking user to create one " << endl;
376 newplayer->
load(stream);
379 newplayer->setVirtual(
true);
388 for (TQPtrListIterator<KPlayer> it(d->mPlayerList); it.current(); ++it)
390 if (it.current()->id() == id)
395 for (TQPtrListIterator<KPlayer> it(d->mInactivePlayerList); it.current(); ++it)
397 if (it.current()->id() == id)
414 kdDebug(11001) << k_funcinfo <<
": " <<
"; maxPlayers=" <<
maxPlayers() <<
" playerCount=" <<
playerCount() << endl;
417 kdFatal(11001) <<
"trying to add NULL player in KGame::addPlayer()" << endl;
423 kdWarning(11001) <<
"cannot add more than " <<
maxPlayers() <<
" players - deleting..." << endl;
428 if (newplayer->
id() == 0)
430 d->mUniquePlayerNumber++;
431 newplayer->setId(KGameMessage::createPlayerId(d->mUniquePlayerNumber,
gameId()));
432 kdDebug(11001) << k_funcinfo <<
"NEW!!! player " << newplayer <<
" now has id " << newplayer->
id() << endl;
438 kdDebug(11001) << k_funcinfo <<
"player " << newplayer <<
" already has an id: " << newplayer->
id() << endl;
442 TQDataStream stream(buffer,IO_WriteOnly);
452 if (
policy()==PolicyClean)
454 d->mAddPlayerList.enqueue(newplayer);
464 kdFatal(11001) <<
"trying to add NULL player in KGame::systemAddPlayer()" << endl;
467 if (newplayer->
id() == 0)
469 kdWarning(11001) << k_funcinfo <<
"player " << newplayer <<
" has no ID" << endl;
474 kdError(11001) <<
"ERROR: Double adding player !!!!! NOT GOOD !!!!!! " << newplayer->
id() <<
"...I delete it again" << endl;
479 kdDebug(11001) <<
"Trying to add player " << newplayer <<
" maxPlayers="<<
maxPlayers()<<
" playerCount="<<
playerCount() << endl;
481 d->mPlayerList.append(newplayer);
483 kdDebug(11001) <<
"Player: isVirtual=" << newplayer->
isVirtual() << endl;
484 kdDebug(11001) <<
" id=" << newplayer->
id() <<
" #Players="
485 << d->mPlayerList.count() <<
" added " << newplayer
486 <<
" (virtual=" << newplayer->
isVirtual() <<
")" << endl;
494 kdDebug(11001) << k_funcinfo <<
": id (" << player->
id() <<
") to be removed " << player << endl;
504 kdDebug(11001) << k_funcinfo <<
": sending IdRemovePlayer "<<player->
id() << endl;
514 kdFatal(11001) <<
"trying to remove NULL player in KGame::removePlayer()" << endl;
517 kdDebug(11001) << k_funcinfo <<
": id (" << player->
id() <<
") to be removed " << player << endl;
525 kdDebug(11001) << k_funcinfo <<
": sending IdRemovePlayer "<<player->
id() << endl;
534 kdDebug(11001) << k_funcinfo << endl;
537 kdWarning(11001) <<
"cannot remove NULL player" << endl;
540 if (!systemRemove(player,deleteit))
542 kdWarning(11001) <<
"player " << player <<
"(" << player->
id() <<
") Could not be found!" << endl;
547 kdWarning(11001) << k_funcinfo
": not enough players, PAUSING game\n" << endl;
552 bool KGame::systemRemove(
KPlayer* p,
bool deleteit)
556 kdWarning(11001) <<
"cannot remove NULL player" << endl;
560 kdDebug(11001) << k_funcinfo <<
": Player (" << p->
id() <<
") to be removed " << p << endl;
562 if (d->mPlayerList.count() == 0)
568 result = d->mPlayerList.remove(p);
588 kdDebug(11001) <<
"Inactivate player " << player->
id() << endl;
608 kdDebug(11001) <<
" Inactivate player " << player->
id() << endl;
610 int pid=player->
id();
618 d->mPlayerList.remove(player);
619 d->mInactivePlayerList.prepend(player);
625 d->mInactiveIdList.prepend(pid);
636 kdDebug(11001) << k_funcinfo <<
": activate " << player->
id() << endl;
654 kdDebug(11001) << k_funcinfo <<
": activate " << player->
id() << endl;
656 d->mInactivePlayerList.remove(player);
661 d->mInactiveIdList.remove(player->
id());
669 {
if (
isAdmin()) { d->mMaxPlayer.changeValue(maxnumber); } }
672 {
if (
isAdmin()) { d->mMinPlayer.changeValue(minnumber); } }
675 {
return d->mMinPlayer.value(); }
678 {
return d->mMaxPlayer.value(); }
681 {
return d->mPlayerList.count(); }
684 {
return d->mGameStatus.value(); }
687 {
return d->mGameStatus.value() == Run; }
690 {
return d->mProperties; }
694 {
return &d->mInactivePlayerList; }
697 {
return &d->mInactivePlayerList; }
700 {
return &d->mPlayerList; }
703 {
return &d->mPlayerList; }
706 {
return d->mRandom; }
713 kdError(11001) << k_funcinfo <<
": NULL player" << endl;
718 kdError(11001) << k_funcinfo <<
": game not running" << endl;
722 kdDebug(11001) << k_funcinfo <<
": transmitting playerInput over network" << endl;
731 kdError(11001) << k_funcinfo <<
": NULL player" << endl;
736 kdError(11001) << k_funcinfo <<
": game not running" << endl;
739 kdDebug(11001) <<
"KGame: Got playerInput from messageServer... sender: " << sender << endl;
746 kdDebug(11001) << k_funcinfo<<
": switching off player input"<<endl;
760 kdDebug(11001) << k_funcinfo<<
"player input finished for "<<player->
id()<<endl;
783 TQTimer::singleShot(0,
this,TQT_SLOT(
prepareNext()));
801 delete d->mGameSequence;
802 d->mGameSequence = sequence;
803 if (d->mGameSequence)
805 d->mGameSequence->setGame(
this);
811 return d->mGameSequence;
834 kdDebug(11001) << k_funcinfo <<
": GAMESTATUS CHANGED to" << status << endl;
837 kdDebug(11001) << k_funcinfo <<
": not enough players, pausing game\n" << endl;
840 d->mGameStatus = status;
855 if (KGameMessage::isPlayer(receiver))
866 kdDebug(11001) <<
"player is here but not active" << endl;
870 kdDebug(11001) <<
"no player found" << endl;
877 if (d->mProperties->processMessage(stream, msgid, sender ==
gameId()))
885 case KGameMessage::IdSetupGame:
890 kdDebug(11001) <<
" ===================> (Client) " << k_funcinfo <<
": Got IdSetupGame ================== " << endl;
891 kdDebug(11001) <<
"our game id is " <<
gameId() <<
" Lib version=" << v <<
" App Cookie=" << c << endl;
895 kdError(11001) <<
"IdGameSetup: Negotiate Game: cookie mismatch I'am="<<
cookie()<<
" master="<<c<<endl;
899 else if (v!=KGameMessage::version())
901 sendError(KGameError::Version, KGameError::errVersion(v));
908 kdDebug(11001) <<
"========== (Client) Setup game done\n";
911 case KGameMessage::IdSetupGameContinue:
913 kdDebug(11001) <<
"=====>(Master) " << k_funcinfo <<
" - IdSetupGameContinue" << endl;
914 setupGameContinue(stream, sender);
917 case KGameMessage::IdActivatePlayer:
921 kdDebug(11001) <<
"Got IdActivatePlayer id=" <<
id << endl;
928 case KGameMessage::IdInactivatePlayer:
932 kdDebug(11001) <<
"Got IdInactivatePlayer id=" <<
id << endl;
939 case KGameMessage::IdAddPlayer:
941 kdDebug(11001) << k_funcinfo <<
": Got IdAddPlayer" << endl;
948 kdDebug(11001) <<
"dequeue previously added player" << endl;
949 newplayer = d->mAddPlayerList.dequeue();
960 case KGameMessage::IdRemovePlayer:
964 kdDebug(11001) << k_funcinfo <<
": Got IdRemovePlayer " <<
id << endl;
976 kdWarning(11001) << k_funcinfo <<
"Cannot find player " <<
id << endl;
980 case KGameMessage::IdGameLoad:
982 kdDebug(11001) <<
"====> (Client) " << k_funcinfo <<
": Got IdGameLoad" << endl;
986 case KGameMessage::IdGameSetupDone:
990 kdDebug(11001) <<
"====> (CLIENT) " << k_funcinfo <<
": Got IdGameSetupDone for client "
991 << cid <<
" we are =" <<
gameId() << endl;
995 case KGameMessage::IdGameConnected:
999 kdDebug(11001) <<
"====> (ALL) " << k_funcinfo <<
": Got IdGameConnected for client "<< cid <<
" we are =" <<
gameId() << endl;
1004 case KGameMessage::IdSyncRandom:
1008 kdDebug(11001) <<
"CLIENT: setting random seed to " << newseed << endl;
1009 d->mRandom->setSeed(newseed);
1012 case KGameMessage::IdDisconnect:
1018 kdDebug(11001) <<
"client " << sender <<
" leaves game" << endl;
1021 kdDebug(11001) <<
"leaving the game" << endl;
1030 if (msgid < KGameMessage::IdUser)
1032 kdError(11001) <<
"incorrect message id " << msgid <<
" - emit anyway"
1035 kdDebug(11001) << k_funcinfo <<
": User data msgid " << msgid << endl;
1036 emit
signalNetworkData(msgid - KGameMessage::IdUser,((TQBuffer*)stream.device())->readAll(),receiver,sender);
1046 void KGame::setupGameContinue(TQDataStream& stream, TQ_UINT32 sender)
1053 TQValueList<int> inactivateIds;
1055 KGamePlayerList newPlayerList;
1056 newPlayerList.setAutoDelete(
true);
1060 kdDebug(11001) <<
" Master got player " << player->
id() <<
" rawgame=" << KGameMessage::rawGameId(player->
id()) <<
" from sender " << sender << endl;
1061 if (KGameMessage::rawGameId(player->
id()) != sender)
1063 kdError(11001) <<
"Client tries to add player with wrong game id - cheat possible" << endl;
1067 newPlayerList.append(player);
1068 kdDebug(11001) <<
" newplayerlist appended " << player->
id() << endl;
1075 kdDebug(11001) <<
" Master calculates how many players to activate client has cnt=" << cnt << endl;
1076 kdDebug(11001) <<
" The game has " <<
playerCount() <<
" active players" << endl;
1077 kdDebug(11001) <<
" The user deactivated "<< inactivateIds.count() <<
" player already " << endl;
1078 kdDebug(11001) <<
" MaxPlayers for this game is " <<
maxPlayers() << endl;
1083 kdDebug(11001) <<
" havePlayers " << cnt+
playerCount()-inactivateIds.count() << endl;
1086 kdDebug(11001) <<
" Still to deacticvate "
1090 int currentPriority=0x7fff;
1093 for ( player=newPlayerList.first(); player != 0; player=newPlayerList.next() )
1096 if (inactivateIds.find(player->
id())!=inactivateIds.end())
1103 currentPlayer=player;
1109 for ( player=d->mPlayerList.first(); player != 0; player=d->mPlayerList.next() )
1112 if (inactivateIds.find(player->
id())!=inactivateIds.end())
1119 currentPlayer=player;
1126 kdDebug(11001) <<
"Marking player " << currentPlayer->
id() <<
" for inactivation" << endl;
1127 inactivateIds.append(currentPlayer->
id());
1131 kdError(11001) <<
"Couldn't find a player to dectivate..That is not so good..." << endl;
1136 kdDebug(11001) <<
"Alltogether deactivated " << inactivateIds.count() <<
" players" << endl;
1138 TQValueList<int>::Iterator it;
1139 for ( it = inactivateIds.begin(); it != inactivateIds.end(); ++it )
1142 kdDebug(11001) <<
" pid=" << pid << endl;
1147 for ( it = inactivateIds.begin(); it != inactivateIds.end(); ++it )
1150 if (KGameMessage::rawGameId(pid) == sender)
1154 kdDebug(11001) <<
" -> the network needs to deactivate " << pid <<endl;
1160 if (
policy()!=PolicyLocal)
1167 kdError(11001) <<
" We should deactivate a player, but cannot find it...not good." << endl;
1172 for ( player=newPlayerList.first(); player != 0; player=newPlayerList.next() )
1174 kdDebug(11001) <<
" newplayerlist contains " << player->
id() << endl;
1176 if (inactivateIds.find(player->
id())!=inactivateIds.end())
1180 kdDebug(11001) <<
" -> the client can ******** reactivate ******** " << player->
id() << endl;
1185 TQByteArray bufferS;
1186 TQDataStream streamS(bufferS,IO_WriteOnly);
1198 void KGame::setupGame(TQ_UINT32 sender)
1200 TQByteArray bufferS;
1201 TQDataStream streamS(bufferS,IO_WriteOnly);
1204 KGamePlayerList mTmpList(d->mPlayerList);
1205 TQ_INT32 cnt=mTmpList.count();
1206 kdDebug(11001) <<
"Client: playerlistcount=" << d->mPlayerList.count() <<
" tmplistcout=" << cnt << endl;
1210 TQPtrListIterator<KPlayer> it(mTmpList);
1212 while (it.current())
1214 player=it.current();
1217 player->setId(KGameMessage::createPlayerId(player->
id(),
gameId()));
1225 if (d->mPlayerList.count() > 0 || cnt!=0)
1227 kdFatal(11001) <<
"KGame::setupGame(): Player list is not empty! or cnt!=0=" <<cnt << endl;
1236 int newseed=(int)d->mRandom->getLong(65535);
1238 d->mRandom->setSeed(newseed);
1244 kdDebug(11001) <<
"------------------- KGAME -------------------------" << endl;
1245 kdDebug(11001) <<
"this: " <<
this << endl;
1246 kdDebug(11001) <<
"uniquePlayer " << d->mUniquePlayerNumber << endl;
1247 kdDebug(11001) <<
"gameStatus " <<
gameStatus() << endl;
1248 kdDebug(11001) <<
"MaxPlayers : " <<
maxPlayers() << endl;
1249 kdDebug(11001) <<
"NoOfPlayers : " <<
playerCount() << endl;
1250 kdDebug(11001) <<
"NoOfInactive: " << d->mInactivePlayerList.count() << endl;
1251 kdDebug(11001) <<
"---------------------------------------------------" << endl;
1264 kdDebug(11001) <<
"======= SERVER DISCONNECT ======="<<endl;
1265 kdDebug(11001) <<
"+++ (CLIENT)++++++++" << k_funcinfo <<
": our GameID="<<
gameId() << endl;
1270 KGamePlayerList removeList;
1271 kdDebug(11001) <<
"Playerlist of client=" << d->mPlayerList.count() <<
" count" << endl;
1272 kdDebug(11001) <<
"Inactive Playerlist of client=" << d->mInactivePlayerList.count() <<
" count" << endl;
1273 for ( player=d->mPlayerList.first(); player != 0; player=d->mPlayerList.next() )
1276 if (KGameMessage::rawGameId(player->
id()) !=
gameId() &&
gameId()!=0)
1278 kdDebug(11001) <<
"Player " << player->
id() <<
" belongs to a removed game" << endl;
1279 removeList.append(player);
1283 for ( player=removeList.first(); player != 0; player=removeList.next() )
1289 kdDebug(11001) <<
" ---> Removing player " << player->
id() << endl;
1295 kdDebug(11001) <<
" our game id is after setMaster " <<
gameId() << endl;
1297 KGamePlayerList mReList(d->mInactivePlayerList);
1298 for ( player=mReList.first(); player != 0; player=mReList.next() )
1306 kdDebug(11001) <<
" Players activated player-cnt=" <<
playerCount() << endl;
1308 for ( player=d->mPlayerList.first(); player != 0; player=d->mPlayerList.next() )
1310 int oldid=player->
id();
1311 d->mUniquePlayerNumber++;
1312 player->setId(KGameMessage::createPlayerId(d->mUniquePlayerNumber,
gameId()));
1313 kdDebug(11001) <<
"Player id " << oldid <<
" changed to " << player->
id() <<
" as we are now local" << endl;
1317 for ( player=d->mPlayerList.first(); player != 0; player=d->mPlayerList.next() )
1321 kdDebug(11001) <<
"+++++++++++" << k_funcinfo <<
" DONE=" << endl;
1327 kdDebug(11001) <<
"++++(SERVER)+++++++" << k_funcinfo <<
" clientId=" << clientID << endl;
1332 KGamePlayerList removeList;
1333 kdDebug(11001) <<
"Playerlist of client=" << d->mPlayerList.count() <<
" count" << endl;
1334 for ( player=d->mPlayerList.first(); player != 0; player=d->mPlayerList.next() )
1336 if (KGameMessage::rawGameId(player->
id())==clientID)
1338 kdDebug(11001) <<
"Player " << player->
id() <<
" belongs to the removed game" << endl;
1339 removeList.append(player);
1343 for ( player=removeList.first(); player != 0; player=removeList.next() )
1350 kdDebug(11001) <<
" ---> Removing player " << player->
id() << endl;
1357 for (
unsigned int idx=0;idx<d->mInactiveIdList.count();idx++)
1359 TQValueList<int>::Iterator it1 = d->mInactiveIdList.at(idx);
1378 kdDebug(11001) <<
"===========================" << k_funcinfo <<
": clientID=" << clientID <<
" =========================== "<< endl;
1381 kdError(11001) << k_funcinfo <<
": Serious WARNING..only gameAdmin should call this" << endl;
1386 TQDataStream streamGS(buffer,IO_WriteOnly);
1393 TQ_INT16 v=KGameMessage::version();
1404 for ( player=d->mPlayerList.first(); player != 0; player=d->mPlayerList.next() )
1406 if (player && player->
group()==group)
1415 {
return sendGroupMessage(((TQBuffer*)msg.device())->buffer(), msgid, sender, group); }
1420 TQDataStream stream(buffer, IO_WriteOnly);
1446 {
return d->mProperties->find(
id); }
1462 for (TQPtrListIterator<KPlayer> it(d->mPlayerList); it.current(); ++it)
1466 for (TQPtrListIterator<KPlayer> it(d->mInactivePlayerList); it.current(); ++it)