File indexing completed on 2024-10-06 06:48:47

0001 /* This file is part of KsirK.
0002    Copyright (C) 2004-2007 Gael de Chalendar <kleag@free.fr>
0003 
0004    KsirK is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU General Public
0006    License as published by the Free Software Foundation, either version 2
0007    of the License, or (at your option) any later version.
0008 
0009    This program is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    General Public License for more details.
0013 
0014    You should have received a copy of the GNU General Public License
0015    along with this program; if not, write to the Free Software
0016    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
0017    02110-1301, USA
0018 */
0019 
0020 #include "gameautomaton.h"
0021 
0022 #include "ksirksettings.h"
0023 #include "kgamewin.h"
0024 #include "aiplayer.h"
0025 #include "aiColsonPlayer.h"
0026 #include "aiplayerio.h"
0027 #include "onu.h"
0028 #include "dice.h"
0029 #include "goal.h"
0030 #include "country.h"
0031 #include "KMessageParts.h"
0032 #include "newgamesetup.h"
0033 #include "krightdialog.h"
0034 #include "Dialogs/joingame.h"
0035 #if HAVE_JABBER_SUPPORT
0036 #include "Jabber/kmessagejabber.h"
0037 #endif
0038 #include "newplayerdata.h"
0039 #include "gamesequence.h"
0040 
0041 #include <QLayout>
0042 #include <QSpinBox>
0043 #include <QPixmap>
0044 #include <QMouseEvent>
0045 #include <QFile>
0046 #include <QUuid>
0047 #include <QInputDialog>
0048 
0049 #include <KLazyLocalizedString>
0050 #include <KLocalizedString>
0051 #include <KLineEdit>
0052 #include <KMessageBox>
0053 
0054 #define USE_UNSTABLE_LIBKDEGAMESPRIVATE_API
0055 #include <libkdegamesprivate/kgame/kmessageclient.h>
0056 #include <libkdegamesprivate/kgame/kmessageserver.h>
0057 #include <libkdegamesprivate/kgame/kgamechat.h>
0058 
0059 #include <errno.h>
0060 #include <sys/types.h>
0061 #include <signal.h>
0062 #include <QCache>
0063 
0064 namespace Ksirk{
0065 namespace GameLogic {
0066 
0067 const char* GameAutomaton::GameStateNames[] = {
0068     "INIT",
0069     "INTERLUDE",
0070     "NEWARMIES",
0071     "WAIT",
0072     "WAIT1",
0073     "WAIT_RECYCLING",
0074     "ATTACK",
0075     "ATTACK2",
0076     "INVADE",
0077     "SHIFT1",
0078     "SHIFT2",
0079     "FIGHT_BRING",
0080     "FIGHT_ANIMATE",
0081     "FIGHT_BRINGBACK",
0082     "WAITDEFENSE",
0083     "EXPLOSION_ANIMATE",
0084     "WAIT_PLAYERS",
0085     "GAME_OVER",
0086     "INVALID",
0087     "STARTING_GAME"
0088 };
0089 
0090 const char* GameAutomaton::KsirkMessagesIdsNames[] = {
0091 "CountryOwner", // 257
0092 "PlayerPutsArmy", // 258
0093 "StateChange", // 259
0094 "PlayerChange", // 260
0095 "RegisterCountry", // 261
0096 "PlayerAvailArmies", // 262
0097 "ResetPlayersDistributionData", // 263
0098 "ChangeItem", // 264
0099 "DisplayRecyclingButtons", // 265
0100 "ClearHighlighting", // 266
0101 "ActionRecycling", // 267
0102 "ClearGameActionsToolbar", // 268
0103 "DisplayDefenseButtons", // 269
0104 "ActionDefense", // 270
0105 "FirstCountry", // 271
0106 "SecondCountry", // 272
0107 "InitCombatMovement", // 273
0108 "AnimCombat", // 274
0109  // 275
0110 "TerminateAttackSequence", // 276
0111 "DecrNbArmies", // 277
0112 "StartLocalCurrentAI", // 278
0113 "Invade", // 279
0114 "Retreat", // 280
0115 "NextPlayerNormal", // 281
0116 "NextPlayerRecycling", // 282
0117 "ShowArmiesToPlace", // 283
0118 "PlayerPutsInitialArmy", // 284
0119 "PlayerRemovesArmy", //285
0120 "VoteRecyclingFinished", // 286
0121 "CancelShiftSource", // 287
0122 "ChangePlayerNation", // 288
0123 "ChangePlayerName", // 289
0124 "StartGame", // 290
0125 "SetNation", // 291
0126 "SetBarFlagButton", // 292
0127 "FinishMoves", // 293
0128 "AnimExplosion", // 294
0129 "SetupOnePlayer", // 295
0130 "SetupWaitedPlayer", // 296
0131 "ValidateWaitedPlayerPassword", // 297
0132 "ValidPassword", // 298
0133 "InvalidPassword", // 299
0134 "SetupCountries", // 300
0135 "AddMsgIdPair", // 301
0136 "CheckGoal", // 302
0137 "SetGoalFor", // 303
0138 "GoalForIs", // 304
0139 "Winner", // 305
0140 "NbPlayers", // 306
0141 "FinalizePlayers", // 307
0142 "Acknowledge", // 308
0143 "DisplayGoals", // 309
0144 "DisplayFightResult", // 310
0145 "MoveSlide", // 311
0146 "InvasionFinished", // 312
0147 "AttackAuto", // 313
0148 "DisplayRecycleDetails", // 314
0149 "CurrentPlayerPlayed", // 315
0150 "NewGameSetupMsg", // 316
0151 };
0152 
0153 #define KSIRK_DEFAULT_PORT 20000
0154 
0155 GameAutomaton::GameAutomaton() :
0156     KGame(),
0157     m_aicannotrunhack(true),
0158     m_state(INIT),
0159     m_game(nullptr),
0160     m_networkPlayersNumber(0),
0161     m_currentPlayer(""),
0162     m_currentPlayerPlayed(false),
0163     m_savedState(INVALID),
0164     m_goals(),
0165     m_useGoals(true),
0166     m_attackAuto(false),
0167     m_defenseAuto(false),
0168     m_port(KSIRK_DEFAULT_PORT),
0169     m_startingGame(false)
0170 {
0171   m_skin = "skins/default";
0172   //   qCDebug(KSIRK_LOG);
0173 //   m_stateId = m_state.registerData(dataHandler(),KGamePropertyBase::PolicyDirty,QString("m_state"));
0174   m_skinId = m_skin.registerData(dataHandler(),KGamePropertyBase::PolicyDirty,QString("m_skin"));
0175 //   m_currentPlayerId = m_currentPlayer.registerData(dataHandler(),KGamePropertyBase::PolicyDirty,QString("m_currentPlayer"));
0176 //   m_events.registerData(dataHandler(),KGamePropertyBase::PolicyDirty,QString("m_events"));
0177 
0178     setGameSequence(new GameSequence(this));
0179 
0180   // Connect the most important slot which tells us which properties are
0181   // changed
0182   connect(this,&KGame::signalPropertyChanged,
0183           this,&GameAutomaton::slotPropertyChanged);
0184   
0185   connect(this,&KGame::signalPlayerJoinedGame,
0186           this,&GameAutomaton::slotPlayerJoinedGame);
0187   
0188   connect(this,&KGame::signalNetworkData,
0189           this,&GameAutomaton::slotNetworkData);
0190   
0191   connect(this,&KGame::signalClientJoinedGame,
0192           this,&GameAutomaton::slotClientJoinedGame);
0193   
0194   connect(messageClient(),&KMessageClient::connectionBroken,
0195           this,&GameAutomaton::slotConnectionToServerBroken);
0196   
0197   connect(messageServer(),&KMessageServer::connectionLost,
0198           this,&GameAutomaton::slotConnectionToClientBroken);
0199 
0200   setPolicy(KGame::PolicyDirty,true);
0201   
0202 //   qCDebug(KSIRK_LOG) << "finished";
0203 }
0204 
0205 GameAutomaton::~GameAutomaton()
0206 {
0207   qCDebug(KSIRK_LOG);
0208   qDeleteAll(m_goals);
0209 }
0210 
0211 void GameAutomaton::init(KGameWindow* gw)
0212 {
0213   m_game = gw;
0214 }
0215 
0216 GameAutomaton::GameState GameAutomaton::state() const
0217 {
0218   return m_state;
0219 }
0220     
0221 void GameAutomaton::state(GameAutomaton::GameState state) 
0222 {
0223   qCDebug(KSIRK_LOG) << "new state (id=" << state << ") is " << GameStateNames[state];
0224   m_state = state;
0225   m_game->setSaveGameActionEnabled(m_state == WAIT);
0226   m_game->setContextualHelpActionEnabled(m_state, currentPlayer() && currentPlayer()->isAI());
0227   QByteArray buffer;
0228   QDataStream stream(&buffer, QIODevice::WriteOnly);
0229   stream << state;
0230   sendMessage(buffer,StateChange);
0231 }
0232 
0233 Player* GameAutomaton::getAnyLocalPlayer()
0234 {
0235   PlayersArray::iterator it = playerList()->begin();
0236   PlayersArray::iterator it_end = playerList()->end();
0237   for (; it != it_end; it++)
0238   {
0239     if ( !((Player*)(*it))->isVirtual() )
0240     {
0241       return (Player*)(*it);
0242     }
0243   }
0244   return nullptr;
0245 }
0246 
0247 GameAutomaton::GameState GameAutomaton::run()
0248 {
0249 //   qCDebug(KSIRK_LOG) << "(KGame running=" <<  (gameStatus()==KGame::Run) << ")";
0250   if (m_game == nullptr || gameStatus() == KGame::Pause)
0251   {
0252     QTimer::singleShot(200, this, &GameAutomaton::run);
0253     return m_state;
0254   }
0255       
0256   activateNeededAIPlayers();
0257 
0258   QString event = "";
0259   QPointF point;
0260   if (!m_events.empty())
0261   {
0262     QPair< QString, QPointF > pair = m_events.front();
0263     event = pair.first;
0264     point = pair.second;
0265     m_events.pop_front();
0266   }
0267 
0268 //   qCDebug(KSIRK_LOG) << "Handling " << stateName() << " ; " << event << " ; " << point;
0269 //   if (currentPlayer())
0270 //   {
0271 //     qCDebug(KSIRK_LOG) << "current player=" << currentPlayer()->name() << " is active=" << currentPlayer()->isActive();
0272 //   }
0273   if (event == "requestForAck")
0274   {
0275     qCDebug(KSIRK_LOG) << "requestForAck";
0276   }
0277   if((event == "actionRButtonDown" || event == "actionLButtonDown") && (m_state != INIT && m_state != NEWARMIES && m_state != INTERLUDE && m_state != WAIT_RECYCLING))
0278   {
0279      if (m_game->getRightDialog()->isOpen())
0280      {
0281         m_game->getRightDialog()->close();
0282      }
0283   }
0284 
0285   if (event == "actionNewGame")
0286   {
0287     if (m_game->actionNewGame(GameAutomaton::None))
0288     {
0289       state(INIT);
0290       QTimer::singleShot(200, this, &GameAutomaton::run);
0291       return INIT;
0292     }
0293     else
0294     {
0295       QTimer::singleShot(200, this, &GameAutomaton::run);
0296       return m_state;
0297     }
0298   }
0299   if (event == "actionOpenGame")
0300   {
0301     if (m_game->actionOpenGame())
0302     {
0303       qCDebug(KSIRK_LOG) << "opened";
0304       bool ok;
0305       m_port = QInputDialog::getInt(m_game,
0306               i18n("KsirK - Network configuration"), 
0307               i18n("Please type in the port number on which to offer connections:"), 
0308               m_port, 0, 32000, 1, &ok);
0309       offerConnections(m_port);
0310       state(WAIT_PLAYERS);
0311       QTimer::singleShot(200, this, &GameAutomaton::run);
0312       return WAIT_PLAYERS;
0313     }
0314     else
0315     {
0316       qCDebug(KSIRK_LOG) << "opened";
0317       QTimer::singleShot(200, this, &GameAutomaton::run);
0318       return m_state;
0319     }
0320   }
0321   if (event == "actionJoinNetworkGame")
0322   {
0323     joinNetworkGame();
0324     QTimer::singleShot(200, this, &GameAutomaton::run);
0325     return m_state;
0326   }
0327 
0328   switch (m_state)
0329   {
0330   case INIT:
0331     if (currentPlayer() != nullptr && isAdmin())
0332     {
0333       if  ( (event == "actionLButtonDown") && (m_game->playerPutsInitialArmy(point)) )
0334       {
0335         m_choosedToRecycleNumber = 0;
0336         m_game->initRecycling();
0337         state(WAIT_RECYCLING);
0338       }
0339     }
0340     break;
0341   case ATTACK:
0342         state(ATTACK2);
0343     break;
0344   case ATTACK2:
0345     qCDebug(KSIRK_LOG) << "Handling ATTACK2";
0346     if (isAdmin())
0347     {
0348       QByteArray buffer;
0349       switch ( m_game->attacked(point) )
0350       {
0351         case 0:
0352           qCDebug(KSIRK_LOG) << "handling attacked value; 0";
0353           state(WAIT);
0354         break;
0355         case 1:
0356           qCDebug(KSIRK_LOG) << "handling attacked value; 1";
0357           sendMessage(buffer,CurrentPlayerPlayed);
0358           state(WAITDEFENSE);
0359         break;
0360         case 2:
0361           qCDebug(KSIRK_LOG) << "handling attacked value; 2";
0362           sendMessage(buffer,CurrentPlayerPlayed);
0363           qCDebug(KSIRK_LOG) << "calling defense(1)";
0364           m_game-> defense(1);
0365           qCDebug(KSIRK_LOG) << "setting state to FIGHT_BRING";
0366           state(FIGHT_BRING);
0367         break;
0368         case 3:
0369           qCDebug(KSIRK_LOG) << "handling attacked value; 3";
0370           // AI action: nothing to do.
0371         break;
0372         default:
0373           qCCritical(KSIRK_LOG) << "Unknown return value from attacked";
0374           exit(1);
0375       }
0376     }
0377     qCDebug(KSIRK_LOG) << "handling of ATTACK2 finished !";
0378   break;
0379   case EXPLOSION_ANIMATE:
0380   break;
0381   case FIGHT_ANIMATE:
0382   break;
0383   case FIGHT_BRING:
0384   break;
0385   case FIGHT_BRINGBACK:
0386     // no more moving fighter returning home
0387 
0388 //     qCDebug(KSIRK_LOG) << "$$$$$$$STATE FIGHT_BRINGBACK $$$$$$$$$$$" << m_game->haveAnimFighters();
0389 
0390     if (!m_game->haveAnimFighters() && isAdmin())
0391     {
0392       QByteArray buffer;
0393       QDataStream stream(&buffer, QIODevice::WriteOnly);
0394       sendMessage(buffer,TerminateAttackSequence);
0395     }
0396     break;
0397   case INTERLUDE:
0398     if  (event == "playersLooped")
0399     {
0400       m_choosedToRecycleNumber = 0;
0401       m_game->initRecycling();
0402       state(WAIT_RECYCLING);
0403     }
0404     else if  (event == "actionLButtonDown" ) 
0405     {
0406       QByteArray buffer;
0407       QDataStream stream(&buffer, QIODevice::WriteOnly);
0408       stream << point;
0409 //       qCDebug(KSIRK_LOG) << "Sending message PlayerPutsArmy " << point ;
0410       sendMessage(buffer,PlayerPutsInitialArmy);
0411     }
0412     else if (event == "actionRButtonDown") 
0413     {
0414       QByteArray buffer;
0415       QDataStream stream(&buffer, QIODevice::WriteOnly);
0416       stream << point;
0417       sendMessage(buffer,PlayerRemovesArmy);
0418     }
0419     else if (event == "actionNextPlayer") 
0420     {
0421       QByteArray buffer;
0422       QDataStream stream(&buffer, QIODevice::WriteOnly);
0423       stream << -1;
0424       sendMessage(buffer,NextPlayerRecycling);
0425     }
0426     else if (event == "actionRecycling") 
0427     {
0428       QByteArray buffer;
0429       sendMessage(buffer,ActionRecycling);
0430     }
0431     else if (event == "actionRecyclingFinished") 
0432     {
0433       qCDebug(KSIRK_LOG) << "actionRecyclingFinished";
0434       QByteArray buffer;
0435       QDataStream stream(&buffer, QIODevice::WriteOnly);
0436 //       stream << currentPlayer()->name();
0437       PlayersArray::iterator it = playerList()->begin();
0438       PlayersArray::iterator it_end = playerList()->end();
0439       quint32 nbLocal = 0;
0440       for (; it != it_end; it++)
0441       {
0442         if ( !((Player*)(*it))->isVirtual() )
0443         {
0444           qCDebug(KSIRK_LOG) << "Local:" << ((Player*)(*it))->name();
0445           nbLocal++;
0446         }
0447       }
0448       qCDebug(KSIRK_LOG) << "Nb Local:" << nbLocal;
0449       stream << nbLocal;
0450 
0451       for (it = playerList()->begin(); it != it_end; ++it)
0452       {
0453         if ( !((Player*)(*it))->isVirtual() )
0454         {
0455           stream << ((Player*)(*it))->id();
0456         }
0457       }
0458       sendMessage(buffer,VoteRecyclingFinished);
0459     }
0460     else
0461     {
0462       //        if (!event.isEmpty())
0463 //          qCCritical(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName();
0464     }
0465   break;
0466   case INVADE:
0467 //     qCDebug(KSIRK_LOG) << "$$$$$$$STATE INVADE$$$$$$$$$$$";
0468     if (event == "actionInvade1")
0469     {
0470       QByteArray buffer;
0471       QDataStream stream(&buffer, QIODevice::WriteOnly);
0472       stream << quint32(1);
0473       sendMessage(buffer,Invade);
0474     }
0475     else if (event == "actionInvade5")
0476     {
0477       QByteArray buffer;
0478       QDataStream stream(&buffer, QIODevice::WriteOnly);
0479       stream << quint32(5);
0480       sendMessage(buffer,Invade);
0481     }
0482     else if (event == "actionInvade10")
0483     {
0484       QByteArray buffer;
0485       QDataStream stream(&buffer, QIODevice::WriteOnly);
0486       stream << quint32(10);
0487       sendMessage(buffer,Invade);
0488     }
0489     else if (event == "actionRetreat1")
0490     {
0491       QByteArray buffer;
0492       QDataStream stream(&buffer, QIODevice::WriteOnly);
0493       stream << quint32(1);
0494       sendMessage(buffer,Retreat);
0495     }
0496     else if (event == "actionRetreat5")
0497     {
0498       QByteArray buffer;
0499       QDataStream stream(&buffer, QIODevice::WriteOnly);
0500       stream << quint32(5);
0501       sendMessage(buffer,Retreat);
0502     }
0503     else if (event == "actionRetreat10")
0504     {
0505       QByteArray buffer;
0506       QDataStream stream(&buffer, QIODevice::WriteOnly);
0507       stream << quint32(10);
0508       sendMessage(buffer,Retreat);
0509     }
0510     else if (event == "actionInvasionFinished")
0511     {
0512       state(WAIT);
0513       m_game-> invasionFinished();
0514     }
0515     else
0516     {
0517       //        if (!event.isEmpty())
0518 //          qCCritical(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName();
0519     }
0520   break;
0521   case NEWARMIES:
0522     if  (event == "actionLButtonDown") 
0523     {
0524       QByteArray buffer;
0525       QDataStream stream(&buffer, QIODevice::WriteOnly);
0526       stream << point << quint32(true);
0527       sendMessage(buffer,PlayerPutsArmy);
0528     }
0529     else if  (event == "actionRButtonDown") 
0530     {
0531       QByteArray buffer;
0532       QDataStream stream(&buffer, QIODevice::WriteOnly);
0533       stream << point;
0534       sendMessage(buffer,PlayerRemovesArmy);
0535     }
0536     else if (event == "actionNextPlayer") 
0537     { 
0538       QByteArray buffer;
0539       QDataStream stream(&buffer, QIODevice::WriteOnly);
0540       stream << quint32(WAIT);
0541       sendMessage(buffer,NextPlayerRecycling);
0542     }
0543 //     else
0544 //     {
0545 //              if (!event.isEmpty())
0546 //          qCCritical(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName();
0547 //     }
0548   break;
0549   case SHIFT1:
0550     if (event == "actionCancel")
0551     {
0552       m_game-> cancelAction();
0553       state(WAIT);
0554     }
0555     else if (event == "actionLButtonDown")
0556     {
0557       m_game->firstCountryAt(point);
0558     }
0559     else if (event == "actionLButtonUp")
0560     {
0561       m_game->secondCountryAt(point);
0562       if (m_game->isMoveValid(point))
0563       {
0564         m_game->startLocalCurrentAI();
0565         QByteArray buffer;
0566         sendMessage(buffer,CurrentPlayerPlayed);
0567         state(SHIFT2);
0568       }
0569       else
0570       {
0571 //         state(WAIT);
0572       }
0573     }
0574     else
0575     {
0576       //        if (!event.isEmpty())
0577 //          qCCritical(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName();
0578     }
0579   break;
0580   case SHIFT2:
0581 //     qCDebug(KSIRK_LOG) << "$$$$$$$STATE SHIFT2$$$$$$$$$$$";
0582     if (event == "actionInvade1")
0583     {
0584 //       qCDebug(KSIRK_LOG) << "actionInvade1";
0585       QByteArray buffer;
0586       QDataStream stream(&buffer, QIODevice::WriteOnly);
0587       stream << quint32(1);
0588       sendMessage(buffer,Invade);
0589     }
0590     else if (event == "actionInvade5")
0591     {
0592       QByteArray buffer;
0593       QDataStream stream(&buffer, QIODevice::WriteOnly);
0594       stream << quint32(5);
0595       sendMessage(buffer,Invade);
0596     }
0597     else if (event == "actionInvade10")
0598     {
0599       QByteArray buffer;
0600       QDataStream stream(&buffer, QIODevice::WriteOnly);
0601       stream << quint32(10);
0602       sendMessage(buffer,Invade);
0603     }
0604     else if (event == "actionRetreat1")
0605     {
0606       QByteArray buffer;
0607       QDataStream stream(&buffer, QIODevice::WriteOnly);
0608       stream << quint32(1);
0609       sendMessage(buffer,Retreat);
0610     }
0611     else if (event == "actionRetreat5")
0612     {
0613       QByteArray buffer;
0614       QDataStream stream(&buffer, QIODevice::WriteOnly);
0615       stream << quint32(5);
0616       sendMessage(buffer,Retreat);
0617     }
0618     else if (event == "actionRetreat10")
0619     {
0620       QByteArray buffer;
0621       QDataStream stream(&buffer, QIODevice::WriteOnly);
0622       stream << quint32(10);
0623       sendMessage(buffer,Retreat);
0624     }
0625     else if (event == "actionInvasionFinished")
0626     {
0627       m_game-> shiftFinished();
0628       state(WAIT);
0629     }
0630     else if (event == "actionCancel")
0631     {
0632       QByteArray buffer;
0633       QDataStream stream(&buffer, QIODevice::WriteOnly);
0634       sendMessage(buffer,CancelShiftSource);
0635     }
0636     else
0637     {
0638       //qCCritical(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName();
0639     }
0640   break;
0641   case WAIT_RECYCLING:
0642     if (event == "actionRecycling")
0643     {
0644       QByteArray buffer;
0645       sendMessage(buffer,ActionRecycling);
0646     }
0647     else if (event == "actionRecyclingFinished") 
0648     {
0649       QByteArray buffer;
0650       QDataStream stream(&buffer, QIODevice::WriteOnly);
0651 //       stream << currentPlayer()->name();
0652       PlayersArray::iterator it = playerList()->begin();
0653       PlayersArray::iterator it_end = playerList()->end();
0654       quint32 nbLocal = 0;
0655       for (; it != it_end; it++)
0656       {
0657         if ( !((Player*)(*it))->isVirtual() )
0658         {
0659           nbLocal++;
0660         }
0661       }
0662       stream << nbLocal;
0663       it = playerList()->begin();
0664       it_end = playerList()->end();
0665       for (; it != it_end; it++)
0666       {
0667         if ( !((Player*)(*it))->isVirtual() )
0668         {
0669           stream << (*it)->id();
0670         }
0671       }
0672       sendMessage(buffer,VoteRecyclingFinished);
0673     }
0674     else
0675     {
0676       if (!event.isEmpty())
0677         qCDebug(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName();
0678       else
0679       {
0680       if (allLocalPlayersComputer())
0681         {
0682           m_game->getRightDialog()->updateRecycleDetails(nullptr,true,0);
0683           m_game->displayRecyclingButtons();
0684         }
0685       }
0686     }
0687     break;
0688   case WAITDEFENSE:
0689     if (event == "actionDefense1")
0690     {
0691       QByteArray buffer;
0692       QDataStream stream(&buffer, QIODevice::WriteOnly);
0693       stream << quint32(1);
0694       sendMessage(buffer,ActionDefense);
0695     }
0696     else if (event == "actionDefense2")
0697     {
0698       QByteArray buffer;
0699       QDataStream stream(&buffer, QIODevice::WriteOnly);
0700       stream << quint32(2);
0701       sendMessage(buffer,ActionDefense);
0702     }
0703     else if ( m_game->secondCountry() != nullptr
0704           && !m_game->secondCountry()->owner()->isVirtual()
0705           && isDefenseAuto()
0706           && (m_game->secondCountry()->owner()->getNbDefense() == 0) )
0707     {
0708       quint32 nbDefense = 1;
0709       if (m_game->secondCountry()->nbArmies() > 1)
0710       {
0711         nbDefense = 2;
0712       }
0713       m_game->secondCountry()->owner()->setNbDefense(nbDefense);
0714       QByteArray buffer;
0715       QDataStream stream(&buffer, QIODevice::WriteOnly);
0716       stream << nbDefense;
0717       sendMessage(buffer,ActionDefense);
0718     }
0719     else
0720     {
0721       //        if (!event.isEmpty())
0722          qCDebug(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName();
0723     }
0724   break;
0725   case WAIT:
0726     if (event == "actionNextPlayer") 
0727     {
0728       actionNextPlayer();
0729     }
0730     else if (event == "actionLButtonDown")
0731     {
0732       if (m_game->firstCountryAt(point))
0733         state(WAIT1);
0734     }
0735     else
0736     {
0737       //        if (!event.isEmpty())
0738 //          qCCritical(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName();
0739     }
0740     // other case : state doesn't change
0741     break;
0742   case WAIT1:
0743     if (event == "actionNextPlayer")
0744     {
0745       actionNextPlayer();
0746     }
0747     else if (event == "actionAttack1")
0748     {
0749       m_game->attack(1);
0750       state(ATTACK);
0751     }
0752     else if (event == "actionAttack2")
0753     {
0754       m_game->attack(2);
0755       state(ATTACK);
0756     }
0757     else if (event == "actionAttack3")
0758     {
0759       m_game->attack(3);
0760       state(ATTACK);
0761     }
0762     else if (event == "actionInvade1")
0763     {
0764 //       qCDebug(KSIRK_LOG) << "actionInvade1";
0765       QByteArray buffer2;
0766       sendMessage(buffer2,CurrentPlayerPlayed);
0767       QByteArray buffer;
0768       QDataStream stream(&buffer, QIODevice::WriteOnly);
0769       stream << quint32(1);
0770       sendMessage(buffer,Invade);
0771 //       state(WAIT);
0772     }
0773     else if (event == "actionInvade5")
0774     {
0775       QByteArray buffer2;
0776       sendMessage(buffer2,CurrentPlayerPlayed);
0777       QByteArray buffer;
0778       QDataStream stream(&buffer, QIODevice::WriteOnly);
0779       stream << quint32(5);
0780       sendMessage(buffer,Invade);
0781 //       state(WAIT);
0782     }
0783     else if (event == "actionInvade10")
0784     {
0785       QByteArray buffer2;
0786       sendMessage(buffer2,CurrentPlayerPlayed);
0787       QByteArray buffer;
0788       QDataStream stream(&buffer, QIODevice::WriteOnly);
0789       stream << quint32(10);
0790       sendMessage(buffer,Invade);
0791 //       state(WAIT);
0792     }
0793     else if (event == "actionInvasionFinished")
0794     {
0795       m_game-> shiftFinished();
0796       state(WAIT);
0797     }
0798     else if (event == "actionLButtonUp")
0799     {
0800       qCDebug(KSIRK_LOG) << "actionLButtonUp in WAIT1";
0801       
0802       if (!currentPlayer()-> isAI())
0803       {
0804         if (m_game->isMoveValid(point) && m_game->firstCountry()->nbArmies() !=1)
0805         {
0806           m_game->secondCountryAt(point);
0807           state(WAIT);
0808           qCDebug(KSIRK_LOG) << "Sending MoveSlide";
0809           QByteArray buffer;
0810           QDataStream stream(&buffer, QIODevice::WriteOnly);
0811           sendMessage(buffer,MoveSlide);
0812         }
0813         else if (m_game->isFightValid(point)
0814                 && m_game->firstCountry()->nbArmies() != 1)
0815         {
0816           m_game->secondCountryAt(point);
0817           if (m_game->firstCountry()->nbArmies() > 3)
0818           {
0819             m_game->frame()->getAttack1Action()->setVisible(true);
0820             m_game->frame()->getAttack2Action()->setVisible(true);
0821             m_game->frame()->getAttack3Action()->setVisible(true);
0822 
0823           }
0824           else if (m_game->firstCountry()->nbArmies() > 2)
0825           {
0826             m_game->frame()->getAttack1Action()->setVisible(true);
0827             m_game->frame()->getAttack2Action()->setVisible(true);
0828             m_game->frame()->getAttack3Action()->setVisible(false);
0829           }
0830           else if (m_game->firstCountry()->nbArmies() > 1)
0831           {
0832             m_game->frame()->getAttack1Action()->setVisible(true);
0833             m_game->frame()->getAttack2Action()->setVisible(false);
0834             m_game->frame()->getAttack3Action()->setVisible(false);
0835           }
0836           m_game->frame()->setMenuPoint(QCursor::pos());
0837           m_game->frame()->getAttackContextMenu()->exec(QCursor::pos());
0838         }
0839         else
0840         {
0841           m_game-> cancelAction();
0842           state(WAIT);
0843         }
0844       }
0845       else
0846       {
0847         m_game->secondCountryAt(point);
0848       }
0849     }
0850     else if (event == "actionLButtonDown")
0851     {
0852       m_game-> cancelAction();
0853       if (m_game->firstCountryAt(point))
0854       {
0855         state(WAIT1);
0856       }
0857       state(WAIT);
0858     }
0859    break;
0860   /*case WAIT_INPUT:
0861     
0862     break;*/   
0863   case WAIT_PLAYERS:
0864     break;
0865   case GAME_OVER:
0866     break;
0867   case STARTING_GAME:
0868     break;
0869   default:
0870     qCCritical(KSIRK_LOG) << "Unhandled state: " << stateName() << ". Event was: " << event ;
0871     exit(1); // @todo handle this error
0872   }
0873 
0874   QTimer::singleShot(200, this, &GameAutomaton::run);
0875 
0876 //   m_game->initTimer();
0877   return m_state;
0878 }
0879 
0880 void GameAutomaton::activateNeededAIPlayers()
0881 {
0882 //   qCDebug(KSIRK_LOG);
0883   if ( currentPlayer() 
0884        && (currentPlayer()-> isAI() ) 
0885        && (!currentPlayer()->isVirtual())
0886        && (!(dynamic_cast< AIPlayer* >(currentPlayer())-> isRunning()))
0887      )
0888   {
0889     dynamic_cast< AIPlayer* >(currentPlayer())-> start();
0890   }
0891   if (    ( m_state == WAITDEFENSE ) 
0892        && ( m_game->secondCountry()) 
0893        && ( m_game->secondCountry()->owner())
0894        && ( m_game->secondCountry()->owner()->isAI() ) 
0895        && ( !m_game->secondCountry()->owner()->isVirtual())
0896        && ( !(dynamic_cast< AIPlayer* >(m_game->secondCountry()->owner())-> isRunning()))
0897      )
0898   {
0899     dynamic_cast< AIPlayer* >(m_game->secondCountry()->owner())-> start();
0900   }
0901 }
0902 
0903 void GameAutomaton::gameEvent(const QString& event, const QPointF& point)
0904 {
0905   m_events.push_back(qMakePair(event, point));
0906 }
0907 
0908 
0909 /** returns the name of the current state */
0910 QString GameAutomaton::stateName() const
0911 {
0912   if (m_state >= (int) sizeof(GameStateNames))
0913   {
0914     QString string;
0915     QTextStream oss(&string);
0916     oss << "Invalid stored state id: " << m_state;
0917     qCCritical(KSIRK_LOG) << string ;
0918     return string;
0919   }
0920   else
0921   {
0922     return QString::fromUtf8(GameStateNames[m_state]);
0923   }
0924 }
0925 
0926 void GameAutomaton::saveXml(QTextStream& xmlStream)
0927 {
0928     xmlStream << "<gameautomaton state=\"" << GameStateNames[m_state] << "\" />";
0929 }
0930 
0931 const QString& GameAutomaton::skin() const
0932 {
0933   return m_skin.value();
0934 }
0935 
0936 void GameAutomaton::skin(const QString& newSkin)
0937 {
0938   m_skin = newSkin;
0939 }
0940 
0941 // Called when a player input (e.g. a mouse event) is received from the KGame 
0942 // object
0943 // This is obviously the central function in the game as all player moves, 
0944 // whether network or local, end up here. So do something sensible here. 
0945 bool GameAutomaton::playerInput(QDataStream &msg, KPlayer* player)
0946 {
0947   qCDebug(KSIRK_LOG);
0948 //   if (player->isVirtual())
0949   if (!isAdmin())
0950   {
0951 //     qCDebug(KSIRK_LOG) << "Network player: nothing to do";
0952     return false;
0953   }
0954 
0955   // Convert the player to the right class
0956   Player* p = dynamic_cast<Player*>(player);
0957 
0958   QString action;
0959   QPointF point;
0960   msg >> action >> point;
0961 
0962   qCDebug(KSIRK_LOG) << " =======================================================";
0963   qCDebug(KSIRK_LOG)  << "Player " << p->name() << " id=" << player->id()
0964   << " uid=" << player->userId() << " : " << action << " at " << point
0965   << "current is" << currentPlayer()->name();
0966   
0967   if (p->name() == currentPlayer()->name()
0968     || (m_state == WAITDEFENSE) )
0969   {
0970     if (action == "actionLButtonDown")
0971       m_game->slotLeftButtonDown( point );
0972     else if (action == "actionLButtonUp")
0973       m_game->slotLeftButtonUp( point );
0974     else if (action == "actionRButtonDown")
0975       m_game->slotRightButtonDown( point );
0976     else if (action == "actionRButtonUp")
0977       m_game->slotRightButtonUp( point );
0978     else if (action == "zoomInAction")
0979       m_game->slotZoomIn();
0980     else if (action == "zoomOutAction")
0981       m_game->slotZoomOut();
0982     else if (action == "actionAttack1")
0983       m_game->slotAttack1();
0984     else if (action == "actionAttack2")
0985       m_game->slotAttack2();
0986     else if (action == "actionAttack3")
0987       m_game->slotAttack3();
0988     else if (action == "actionMove")
0989       m_game->slotMove();
0990     else if (action == "slotRecyclingFinished")
0991       m_game->slotRecyclingFinished();
0992     else if (action == "actionInvade10")
0993       m_game->slotInvade10();
0994     else if (action == "actionInvade5")
0995       m_game->slotInvade5();
0996     else if (action == "actionInvade1")
0997       m_game->slotInvade1();
0998     else if (action == "actionInvasionFinished")
0999       m_game->slotInvasionFinished();
1000     else if (action == "slotDefense1")
1001       m_game->slotDefense1();
1002     else if (action == "slotDefense2")
1003       m_game->slotDefense2();
1004     else if (action == "actionNextPlayer")
1005       m_game->slotNextPlayer();
1006   }
1007   if (action == "requestForAck")
1008   {
1009     QString ack;
1010     msg >> ack;
1011     qCDebug(KSIRK_LOG) << "acknowledging " << ack;
1012     if (p->isVirtual())
1013     {
1014       qCDebug(KSIRK_LOG) << p->name() << "is virtual; sending message";
1015       QByteArray buffer;
1016       QDataStream stream(&buffer, QIODevice::WriteOnly);
1017       stream << p->id() << ack;
1018       sendMessage(buffer,Acknowledge);
1019     }
1020     else
1021     {
1022       qCDebug(KSIRK_LOG) << p->name() << "is local; acknowledging";
1023       p->acknowledge(ack);
1024     }
1025   }
1026   return false;
1027 }
1028 
1029 // Create an IO device for the player. We could create any
1030 // device here, e.g. mouse, keyboard, computer player. In the
1031 // demo game here we have only the mouse player available.
1032 void GameAutomaton::createIO(KPlayer *player,KGameIO::IOMode io)
1033 {
1034   // Error check
1035   if (!player) return;
1036 
1037   qCDebug(KSIRK_LOG) << "createIO for " << player->name();
1038 
1039   if (io&KGameIO::MouseIO)
1040   {
1041     // Create new game mouse input
1042     KGameMouseIO *input;
1043     // We want the player to work over mouse
1044     // in our canvas view
1045     input=new KGameMouseIO(m_game->frame()->scene());
1046 
1047     // Connect mouse input to a function to process the actual input
1048     connect(
1049       input,
1050       &KGameMouseIO::signalMouseEvent,
1051       m_game->frame(),
1052       &DecoratedGameFrame::slotMouseInput);
1053 
1054     // Add the device to the player
1055     player->addGameIO(input);
1056   }
1057   else if (io&AIPLAYERIO)
1058   {
1059     if (dynamic_cast<AIPlayer*>(player) != nullptr)
1060     {
1061       /*AIPlayerIO* input =*/ new AIPlayerIO(dynamic_cast<AIPlayer*>(player));
1062     }
1063     else
1064     {
1065       qCCritical(KSIRK_LOG) << "Can create an AIPlayerIO only for AI players: " << io ;
1066     }
1067   }
1068   else
1069   {
1070     qCCritical(KSIRK_LOG) << "Cannot create the requested IO device " << io ;
1071   }
1072   qCDebug(KSIRK_LOG) << "Done createIO for " << player->name();
1073 }
1074 
1075 // Find out who will be the next player
1076 // Note: The default behaviour as we have it here is done automatically
1077 //        by the lib, too. So if all players player one after the other
1078 //        this functions is NOT needed at all.
1079 KPlayer * GameAutomaton::doNextPlayer(KPlayer */*last*/,bool /*exclusive*/)
1080 {
1081 //   qCDebug(KSIRK_LOG) << last->name();
1082 //   m_game->setCurrentPlayerToNext();
1083   // If a last player is given switch the player
1084   
1085   // Should be enough if the admin sets the turn (unclear)
1086   if (isAdmin())
1087   {
1088     currentPlayer()->setTurn(true,true);
1089 //     last->setTurn(true,true);
1090 //     qCDebug(KSIRK_LOG) << "nextPlayer::Setting turn to " << last->name() << ", " << last->id() << "("<<last->userId()<<")";
1091   }
1092   
1093   // Notify the world that whose turn it is. The main window uses
1094   // this to show a little message
1095 //   emit signalNextPlayer(next->userId().value(),next,this);
1096   
1097   // Return the next player
1098   return dynamic_cast<KPlayer *>(currentPlayer());
1099 }
1100 
1101 QDataStream& operator>>(QDataStream& s, GameAutomaton::GameState& state)
1102 {
1103   int istate;
1104   s >> istate;
1105   state = GameAutomaton::GameState(istate);
1106   return s;
1107 }
1108 
1109 
1110 bool GameAutomaton::setupPlayersNumberAndSkin(NetworkGameType netGameType)
1111 {
1112   qCDebug(KSIRK_LOG) << netGameType;
1113   m_netGameType = netGameType;
1114   m_game->newGameDialog(m_skin.value(), m_netGameType);
1115 
1116 //   m_networkPlayersNumber = ???;
1117   return false;
1118 }
1119 
1120 bool GameAutomaton::finishSetupPlayersNumberAndSkin()
1121 {
1122   qCDebug(KSIRK_LOG);
1123   
1124   setUseGoals(m_game->newGameSetup()->useGoals());
1125   state(GameLogic::GameAutomaton::INIT);
1126   savedState(GameLogic::GameAutomaton::INVALID);
1127   setNetworkPlayersNumber(m_game->newGameSetup()->nbNetworkPlayers());
1128   m_startingGame = true;
1129   state(INIT);
1130   setMinPlayers(m_game->newGameSetup()->nbPlayers());
1131   setMaxPlayers(m_game->newGameSetup()->nbPlayers());
1132   m_nbPlayers = m_game->newGameSetup()->nbPlayers();
1133   
1134   return true;
1135 }
1136 
1137 void GameAutomaton::setGoalFor(Player* player)
1138 {
1139   qCDebug(KSIRK_LOG) << player->name();
1140   unsigned int max = m_goals.size();
1141   unsigned int goalId = Dice::roll(max);
1142   QList< Goal* >::iterator it = m_goals.begin();
1143   for (unsigned int i = 1 ; i < goalId; it++,i++) {}
1144   Goal* goal = (*it);
1145   qCDebug(KSIRK_LOG) << "Goal for " << player->name() << " is of type " << goal->type();
1146   if (goal->type() == Goal::GoalPlayer)
1147   {
1148     Player* target = nullptr;
1149     while (target==nullptr || target->id() == player->id())
1150     {
1151       unsigned int max = playerList()->count();
1152       unsigned int playerNum = Dice::roll(max);
1153 //       qCDebug(KSIRK_LOG) << "Choice player num " << playerNum << " on " << max ;
1154       PlayersArray::iterator itp = playerList()->begin();
1155       unsigned int j = 1;
1156       for (; j < playerNum; j++,itp++) {}
1157       target = dynamic_cast< Player* >(*itp);
1158     }
1159     if (target != nullptr)
1160     {
1161 //       qCDebug(KSIRK_LOG) << "Target choice for " << player->name() << ": " << target->name();
1162       goal->players().push_back(target->name());
1163     }
1164     else
1165     {
1166 //       qCDebug(KSIRK_LOG) << "No target chosen for " << player->name();
1167     }
1168   }
1169   /// @note hack to avoid too easy countries goal when there is only two players
1170   else if (goal->type() == Goal::Countries 
1171     && playerList()->count() == 2)
1172   {
1173     goal->nbCountries(int(goal->nbCountries()*1.5));
1174   }
1175   QByteArray buffer;
1176   QDataStream stream(&buffer, QIODevice::WriteOnly);
1177   stream << player->id();
1178   stream << (*goal);
1179   qCDebug(KSIRK_LOG) << "Sending message GoalForIs ("<<GoalForIs<<") for " << player->name(); 
1180   sendMessage(buffer,GoalForIs);
1181 //   delete goal;
1182   m_goals.erase(it);
1183 }
1184 
1185 Country * GameAutomaton::getDefCountry ()
1186 {
1187   return this->defCountry;
1188 }
1189 
1190 bool GameAutomaton::joinNetworkGame()
1191 {
1192   qCDebug(KSIRK_LOG);
1193    if (stateName() == "INIT"
1194      || (KMessageBox::warningContinueCancel(m_game,i18n("Do you really want to end your current game and join another?"),i18n( "New game confirmation" ),KGuiItem(i18nc("@action:button", "Join New Game"))) == KMessageBox::Continue))
1195    {
1196       m_game->joinNetworkGame();
1197    }
1198    return false;
1199 }
1200 
1201 bool GameAutomaton::connectToServ()
1202 {
1203   qCDebug(KSIRK_LOG);
1204   if (messageServer() != nullptr)
1205   {
1206     QObject::disconnect(messageServer(),&KMessageServer::connectionLost,
1207                         this,&GameAutomaton::slotConnectionToClientBroken);
1208   }
1209   qCDebug(KSIRK_LOG) << "Before connectToServer";
1210   QString host = m_game->newGameSetup()->host();
1211   int port = m_game->newGameSetup()->tcpPort();
1212   bool status = connectToServer(host, port);
1213   qCDebug(KSIRK_LOG) << "After connectToServer" << status;
1214   if (messageServer())
1215     connect(messageServer(),&KMessageServer::connectionLost,
1216           this,&GameAutomaton::slotConnectionToClientBroken);
1217   return status;
1218 }
1219 
1220 #if HAVE_JABBER_SUPPORT
1221 bool GameAutomaton::joinJabberGame(const QString& nick)
1222 {
1223   if (stateName() == "INIT" || (KMessageBox::warningContinueCancel(m_game,i18n("Do you really want to end your current game and join another?"),i18n( "New game confirmation" ),KGuiItem(i18nc("@action:button", "Join New Game"))) == KMessageBox::Continue))
1224   {
1225     // stop game
1226     setGameStatus(KGame::End);
1227     state(INIT);
1228     savedState(INVALID);
1229     
1230     if (messageServer() != nullptr)
1231     {
1232       QObject::disconnect(messageServer(),&KMessageServer::connectionLost,
1233                            this,&GameAutomaton::slotConnectionToClientBroken);
1234     }
1235     
1236     qCDebug(KSIRK_LOG) << "Before connectToServer";
1237     m_game->setServerJid(nick);
1238     KMessageJabber* messageIO = new KMessageJabber(m_game->serverJid().full(), m_game->jabberClient(), this);
1239     bool status = connectToServer(messageIO);
1240     //       bool status = connectToServer(host, port);
1241     qCDebug(KSIRK_LOG) << "After connectToServer" << status;
1242     if (status)
1243     {
1244       QByteArray msg("connect");
1245       XMPP::Message message(m_game->serverJid().full());
1246       message.setType("ksirkgame");
1247       message.setId(QUuid::createUuid().toString().remove("{").remove("}").remove("-"));
1248       message.setBody(msg);
1249       m_game->jabberClient()->sendMessage(message);
1250     }
1251     //       connect(messageServer(),SIGNAL(connectionLost(KMessageIO*)),
1252                                                            //          this,SLOT(slotConnectionToClientBroken(KMessageIO*)));
1253                                                            return status;
1254   }
1255   return false;
1256 }
1257 #endif
1258 
1259 KPlayer * GameAutomaton::createPlayer(int rtti, 
1260                                     int /*io*/, 
1261                                     bool isVirtual)    
1262 {
1263   qCDebug(KSIRK_LOG) << "(" << rtti << ", " << isVirtual << ")";
1264   if (rtti == 1)
1265   {
1266     Player* p = new Player(this, "", 0, nullptr);
1267     p->setVirtual(isVirtual);
1268     if (!isVirtual)
1269     {
1270       qCDebug(KSIRK_LOG) << "Calling player createIO";
1271       createIO(p,KGameIO::IOMode(KGameIO::MouseIO));
1272     }
1273     return (KPlayer*) p;
1274   }
1275   else if (rtti == 2)
1276   {
1277     AIPlayer* aip = new AIColsonPlayer("", 0, nullptr,  *playerList(), m_game->theWorld(),
1278                                    this);
1279     aip->stop();
1280     aip->setVirtual(isVirtual);
1281     if (!isVirtual)
1282     {
1283       qCDebug(KSIRK_LOG) << "Calling player createIO";
1284       createIO(aip, KGameIO::IOMode(AIPLAYERIO));
1285     }
1286     return (KPlayer*) aip;
1287   }
1288   else 
1289   {
1290     qCCritical(KSIRK_LOG) << "No rtti given... creating a Player";
1291     Player* p = new Player(this, "", 0, nullptr);
1292     p->setVirtual(isVirtual);
1293     if (!isVirtual)
1294     {
1295       qCDebug(KSIRK_LOG) << "Calling player createIO";
1296       createIO(p,KGameIO::IOMode(KGameIO::MouseIO));
1297     }
1298     return (KPlayer*) p;
1299   }
1300 }
1301 
1302 /**
1303   * @return A pointer to the given's named player ; 0 if there is no such player
1304   */
1305 Player* GameAutomaton::playerNamed(const QString& playerName)
1306 {
1307   PlayersArray::iterator it = playerList()->begin();
1308   PlayersArray::iterator it_end = playerList()->end();
1309   for (; it != it_end; it++)
1310   {
1311     if ( (*it)-> name() ==  playerName)
1312     {
1313       return dynamic_cast<Player*>(*it);
1314     }
1315   }
1316   qCCritical(KSIRK_LOG) << "GameAutomaton::playerNamed: there is no player named " 
1317       << playerName ;
1318   return nullptr;
1319 }
1320 
1321 Player* GameAutomaton::currentPlayer() 
1322 {
1323   if (m_game && !m_currentPlayer.isEmpty())
1324   {
1325     return playerNamed(m_currentPlayer);
1326   }
1327   else return nullptr;
1328 }
1329 
1330 void GameAutomaton::currentPlayer(Player* player) 
1331 {
1332   qCDebug(KSIRK_LOG);
1333   if (player)
1334   {
1335     qCDebug(KSIRK_LOG) << " name = " << player->name();
1336     m_currentPlayer = player->name();
1337     m_currentPlayerPlayed = false;
1338     if (isAdmin())
1339     {   
1340       QByteArray buffer;
1341       QDataStream stream(&buffer, QIODevice::WriteOnly);
1342       stream << m_currentPlayer;
1343       sendMessage(buffer,PlayerChange);
1344       player->setTurn(true,true);
1345     }
1346     QByteArray buffer;
1347     QDataStream stream(&buffer, QIODevice::WriteOnly);
1348     stream << player->name();
1349     sendMessage(buffer,SetBarFlagButton);
1350     if (!player->isVirtual())
1351     {
1352       m_game->chatWidget()->setFromPlayer(player);
1353     }
1354   }
1355   else 
1356     m_currentPlayer = "";
1357 }
1358 
1359 void GameAutomaton::slotPlayerJoinedGame(KPlayer* player)
1360 {
1361   qCDebug(KSIRK_LOG) << "currently " << playerList()->count() << " / " << maxPlayers();
1362   Player* p = dynamic_cast<Player*>(player);
1363   Q_ASSERT(p);
1364   
1365   if (isAdmin())
1366   {
1367     unsigned int nbWithNation = 0;
1368     unsigned int nbWithName = 0;
1369     PlayersArray::iterator it = playerList()->begin();
1370     PlayersArray::iterator it_end = playerList()->end();
1371     for (; it != it_end; it++)
1372     {
1373       if (p->getNation()->name() == ((Player*)(*it))->getNation()->name())
1374       {
1375         nbWithNation++;
1376       }
1377       if (p->name() == ((Player*)(*it))->name())
1378       {
1379         nbWithName++;
1380       }
1381     }
1382     if (nbWithName != 1)
1383     {
1384       QByteArray buffer;
1385       QDataStream stream(&buffer, QIODevice::WriteOnly);
1386       stream << quint32(player->id());
1387       qCDebug(KSIRK_LOG) << "Sending ChangePlayerName for player id " << player->id();
1388       sendMessage(buffer,ChangePlayerName);
1389       
1390       return;
1391     }
1392     else if (nbWithNation != 1)
1393     {
1394       QByteArray buffer;
1395       QDataStream stream(&buffer, QIODevice::WriteOnly);
1396       stream << player->id();
1397       qCDebug(KSIRK_LOG) << "Sending ChangePlayerNation for player id " << player->id();
1398       sendMessage(buffer,ChangePlayerNation);
1399       
1400       return;
1401     }
1402     KMessageParts messageParts;
1403     messageParts 
1404       << kli18n("%1 (%2) joined game ; waiting for %3 players to connect").untranslatedText()
1405       << p-> name() << p->getNation()->name() 
1406       << QString::number(maxPlayers() - int(playerList()->count()));
1407     m_game->broadcastChangeItem(messageParts, ID_STATUS_MSG2);
1408     QByteArray buffer;
1409     QDataStream stream(&buffer, QIODevice::WriteOnly);
1410     qCDebug(KSIRK_LOG) << "Sending StartGame";
1411     sendMessage(buffer,StartGame);
1412   }
1413   else
1414   {
1415     if (!player->isVirtual())
1416     {
1417       m_game->showNewGameSummary();
1418     }
1419     m_game->newGameSetup()->setNbPlayers(maxPlayers());
1420   }
1421   NewPlayerData* pd = new NewPlayerData(p->name(),p->getNation()->name(),"",p->isAI(),true);
1422   if (!m_game->newGameSetup()->addPlayer(pd))
1423   {
1424     delete pd;
1425   }
1426   m_game->updateNewGameSummary();
1427 }
1428 
1429 bool GameAutomaton::startGame()
1430 {
1431   qCDebug(KSIRK_LOG) << stateName() << "nb players = " << playerList()->count() << " / " << maxPlayers();
1432   m_aicannotrunhack = true;
1433   //   qCDebug(KSIRK_LOG) << "  state is " << GameStateNames[m_state];
1434 //   qCDebug(KSIRK_LOG) << "  saved state is " << GameStateNames[m_savedState];
1435   if (isAdmin() && int(playerList()->count()) == maxPlayers()
1436       && gameStatus()!=KGame::Run)
1437   {
1438 //     m_game->haltTimer();
1439 
1440     if (m_state == INIT && m_savedState == INVALID)
1441     {
1442       firstCountriesDistribution();
1443 
1444       if (useGoals())
1445       {
1446         PlayersArray::iterator it = playerList()->begin();
1447         PlayersArray::iterator it_end = playerList()->end();
1448         for (; it != it_end; it++)
1449         {
1450           QByteArray buffer;
1451           QDataStream stream(&buffer, QIODevice::WriteOnly);
1452           stream << (*it)->id();
1453           sendMessage(buffer,SetGoalFor);
1454         }
1455       }
1456     }
1457     else if (m_state == WAIT_PLAYERS)
1458     {
1459       sendCountries();
1460       qCDebug(KSIRK_LOG) << "at " <<  __FILE__ << ", line " << __LINE__ << ", setting state to " << m_savedState ;
1461       state(m_savedState);
1462       currentPlayer(playerNamed(m_savedPlayer));
1463       m_game->displayButtonsForState(m_savedState);
1464       m_savedPlayer = "";
1465       m_savedState = INVALID;
1466     }
1467 
1468     qCDebug(KSIRK_LOG) << "Sending message FinalizePlayers";
1469     QByteArray buffer;
1470     QDataStream stream(&buffer, QIODevice::WriteOnly);
1471     sendMessage(buffer,FinalizePlayers);
1472 
1473     qCDebug(KSIRK_LOG) << "Setting game status to Run";
1474     setGameStatus(KGame::Run);
1475 //     m_game->initTimer();
1476 //     qCDebug(KSIRK_LOG) << "    true";
1477     return true;
1478   }
1479   else
1480   {
1481 //     qCDebug(KSIRK_LOG) << "    false";
1482     return false;
1483   }
1484 }
1485 
1486 void GameAutomaton::changePlayerName(Player* player)
1487 {
1488 //   qCDebug(KSIRK_LOG);
1489   
1490   QMap< QString, QString > nations = m_game->nationsList();
1491   PlayersArray::iterator it = playerList()->begin();
1492   PlayersArray::iterator it_end = playerList()->end();
1493   for (; it != it_end; it++)
1494   {
1495     QMap<QString,QString>::iterator nationsIt;
1496     nationsIt = nations.find(((Player*)(*it))-> getNation()->name());
1497     if (nationsIt !=  nations.end())
1498     {
1499       nations.erase(nationsIt);
1500     }
1501   }
1502   
1503 // Players names
1504   QString mes = "";
1505   QString nationName;
1506   
1507   QString nomEntre = player->name();
1508   
1509   bool found = true;
1510   KMessageBox::information(m_game, i18n("Please choose another name"), i18n("KsirK - Name already used!"));
1511   while(found)
1512   {
1513     bool emptyName = true;
1514     while (emptyName)
1515     {
1516       mes = i18n("Player number %1, what's your name?", 1);
1517       QString password;
1518       if (nomEntre.isEmpty())
1519       {
1520         mes = i18n("Error - Player %1, you have to choose a name.", 1);
1521         KMessageBox::error(m_game, mes);
1522         nomEntre = i18nc("@info Forged player name", "Player%1", 1);
1523       }
1524       else 
1525       {
1526         emptyName = false;
1527       }
1528     }
1529     found = false;
1530     PlayersArray::iterator it = playerList()->begin();
1531     PlayersArray::iterator it_end = playerList()->end();
1532     for (; it != it_end; it++)
1533     {
1534       if ( (*it)-> name() ==  nomEntre)
1535       {
1536         found = true;
1537         it = it_end;
1538       }
1539     }
1540     if (!found)
1541     {
1542 //     qCDebug(KSIRK_LOG) << "Creating player " << nomEntre << "(computer: " << computer << "): " << nationName ;
1543       player->setName(nomEntre);
1544     }
1545   }
1546   QByteArray buffer;
1547   QDataStream stream(&buffer, QIODevice::WriteOnly);
1548   sendMessage(buffer,StartGame);
1549 }
1550 
1551 void GameAutomaton::changePlayerNation(Player* player)
1552 {
1553 //   qCDebug(KSIRK_LOG);
1554   
1555   QMap< QString, QString > nations = m_game->nationsList();
1556   PlayersArray::iterator it = playerList()->begin();
1557   PlayersArray::iterator it_end = playerList()->end();
1558   for (; it != it_end; it++)
1559   {
1560     QMap<QString,QString>::iterator nationsIt;
1561     nationsIt = nations.find(((Player*)(*it))-> getNation()->name());
1562     if (nationsIt !=  nations.end())
1563     {
1564       nations.erase(nationsIt);
1565     }
1566   }
1567   
1568 // Players names
1569   QString mes = "";
1570   QString nationName;
1571   
1572   QString nomEntre = player->name();
1573   KMessageBox::information(m_game, i18n("Please choose another nation"), i18n("KsirK - Nation already used!"));
1574   QString password;
1575   QByteArray buffer;
1576   QDataStream stream(&buffer, QIODevice::WriteOnly);
1577   stream << player->name() << nationName;
1578   sendMessage(buffer,SetNation);
1579   QByteArray buffer2;
1580   QDataStream stream2(&buffer2, QIODevice::WriteOnly);
1581   sendMessage(buffer2,StartGame);
1582 }
1583 
1584 quint32 GameAutomaton::idForMsg(const QString& msg)
1585 {
1586   QMap<QString,quint32>::iterator it = m_msgs2ids.find(msg);
1587   if (it != m_msgs2ids.end())
1588   {
1589     return (*it);
1590   }
1591   else
1592   {
1593     quint32 id = m_msgs2ids.size();
1594     QByteArray buffer;
1595     QDataStream stream(&buffer, QIODevice::WriteOnly);
1596     stream << msg << id;
1597     sendMessage(buffer,AddMsgIdPair);
1598     return id;
1599   }
1600 }
1601 
1602 QString& GameAutomaton::msgForId(quint32 id)
1603 {
1604   return m_ids2msgs[id];
1605 }
1606 
1607 void GameAutomaton::slotPropertyChanged(KGamePropertyBase *prop,KGame *)
1608 {
1609   qCDebug(KSIRK_LOG) << prop->id() << " (skin is " << m_skinId << ")";
1610   if (prop->id() == m_skinId)
1611   {
1612     qCDebug(KSIRK_LOG) << "skin changed to: " << m_skin ;
1613     m_game->newSkin();
1614     if (m_game->theWorld()!=nullptr)
1615     {
1616       m_game->theWorld()->reset();
1617     }
1618   }
1619   qCDebug(KSIRK_LOG) << "END GameAutomaton::slotPropertyChanged " << prop->id() << " (skin is " << m_skinId << ")";
1620 }
1621 
1622 void GameAutomaton::slotClientJoinedGame(quint32 clientid, KGame* /*me*/)
1623 {
1624   qCDebug(KSIRK_LOG) << clientid;
1625   if (isAdmin() && clientid!=gameId())
1626   {
1627     QByteArray buffernbp;
1628     QDataStream streamnbp(&buffernbp, QIODevice::WriteOnly);
1629     streamnbp << m_nbPlayers;
1630     sendMessage(buffernbp,NbPlayers,clientid);
1631     
1632     QByteArray bufferngs;
1633     QDataStream streamngs(&bufferngs, QIODevice::WriteOnly);
1634     streamngs << *m_game->newGameSetup();
1635     sendMessage(bufferngs,NewGameSetupMsg,clientid);
1636     
1637     QByteArray buffer;
1638     QDataStream stream(&buffer, QIODevice::WriteOnly);
1639     if (m_game->waitedPlayers().empty())
1640     {
1641       sendMessage(buffer,SetupOnePlayer,clientid);
1642     }
1643     else
1644     {
1645       stream << quint32(m_game->waitedPlayers().size());
1646       QList<PlayerMatrix>::iterator it, it_end;
1647       it = m_game->waitedPlayers().begin(); it_end = m_game->waitedPlayers().end();
1648       for (; it != it_end; it++)
1649       {
1650         stream << (*it);
1651       }
1652       sendMessage(buffer,SetupWaitedPlayer,clientid);
1653     }
1654   }
1655 }
1656 
1657 void GameAutomaton::slotConnectionToServerBroken()
1658 {
1659   qCDebug(KSIRK_LOG);
1660 
1661 //   m_game->haltTimer();
1662   if (m_state != GAME_OVER)
1663   {
1664     int answer = KMessageBox::questionTwoActionsCancel(m_game,
1665                                                   i18n("KsirK - Lost connection to server!\nWhat do you want to do?"),
1666                                                   i18n("Starting a new game or exit."),
1667                                                   KGuiItem(i18n("New Game")),
1668                                                   KGuiItem(i18n("Exit")),
1669                                                   KGuiItem(i18n("Do nothing")));
1670     if (answer == KMessageBox::PrimaryAction)
1671     {
1672       m_game->showMainMenu();
1673     }
1674     else if (answer == KMessageBox::SecondaryAction)
1675     {
1676       exit(0);
1677     }
1678     else
1679     {
1680     }
1681   }
1682 }
1683   
1684 void GameAutomaton::slotConnectionToClientBroken(KMessageIO *)
1685 {
1686   qCDebug(KSIRK_LOG);
1687 //   m_game->haltTimer();
1688   if (m_state != GAME_OVER)
1689   {
1690     KMessageBox::information(m_game, 
1691                             i18n("Lost connection to a client.\nFor the moment, you can only save the game and start a new one or quit.\nThis will be improved in a future version."), 
1692                             i18n("KsirK - Lost connection to client!"));
1693     switch ( KMessageBox::warningTwoActions( m_game,
1694                                         i18n("Do want to save your game?"),
1695                                         QString(),
1696                                         KStandardGuiItem::save(), KStandardGuiItem::discard()) )
1697     {
1698     case KMessageBox::PrimaryAction :
1699       m_game->slotSaveGame();
1700       break;
1701     case KMessageBox::SecondaryAction :;
1702     default: ;
1703     }
1704     if (!m_game->actionNewGame(GameAutomaton::None))
1705       exit(1);
1706   }
1707 //   else
1708 //   {
1709 //     m_game->haltTimer();
1710 //   }
1711 }
1712 
1713 void GameAutomaton::finalizePlayers()
1714 {
1715   qCDebug(KSIRK_LOG);
1716   PlayersArray::iterator it = playerList()->begin();
1717   PlayersArray::iterator it_end = playerList()->end();
1718   for (; it != it_end; it++)
1719   {
1720     dynamic_cast<Player*>(*it)-> finalize();
1721   }
1722   QByteArray buffer;
1723   if (isAdmin())
1724   {
1725     sendMessage(buffer,DisplayGoals);
1726   }
1727   m_game->showMap();
1728   m_startingGame = false;
1729 }
1730 
1731 /** @return true if all players are played by computer ; false otherwise */
1732 bool GameAutomaton::allComputerPlayers()
1733 {
1734   PlayersArray::iterator it = playerList()->begin();
1735   PlayersArray::iterator it_end = playerList()->end();
1736   for (; it != it_end; it++)
1737   {
1738     if ( ! dynamic_cast<Player*>(*it)-> isAI() )
1739     {
1740       return false;
1741     }
1742   }
1743   return true;
1744 }
1745 
1746 bool GameAutomaton::allLocalPlayersComputer()
1747 {
1748   PlayersArray::iterator it = playerList()->begin();
1749   PlayersArray::iterator it_end = playerList()->end();
1750   for (; it != it_end; it++)
1751   {
1752     if ( ( ! dynamic_cast<Player*>(*it)-> isVirtual() ) &&  ( ! dynamic_cast<Player*>(*it)-> isAI() ) )
1753     {
1754       return false;
1755     }
1756   }
1757   return true;
1758 }
1759 
1760 void GameAutomaton::firstCountriesDistribution()
1761 {
1762   qCDebug(KSIRK_LOG);
1763 
1764   if (isAdmin())
1765   {
1766     PlayersArray::iterator it = playerList()->begin();
1767     PlayersArray::iterator it_end = playerList()->end();
1768     for (; it != it_end; it++)
1769     {
1770       ((Player*)(*it))->setNbAvailArmies((unsigned int)(m_game->theWorld()->getNbCountries() * 2.5 / nbPlayers() ), true);
1771     }
1772     m_game->setCurrentPlayerToFirst();
1773     qCDebug(KSIRK_LOG) << "Setup players: distributing countries";
1774     countriesDistribution();
1775 
1776 
1777   //    qCDebug(KSIRK_LOG) << " KGameWindow::setupPlayers: before initTimer";
1778 //     m_game->initTimer();
1779     m_game->setCurrentPlayerToFirst();
1780     if ( currentPlayer()-> isAI()  && (!currentPlayer()->isVirtual()) )
1781       if ( ! ( dynamic_cast<AIPlayer *>(currentPlayer())-> isRunning()) )
1782         dynamic_cast<AIPlayer *>(currentPlayer())-> start();
1783 
1784     QByteArray buffer;
1785     QDataStream stream(&buffer, QIODevice::WriteOnly);
1786     stream << currentPlayer()->name();
1787 //     stream << (quint32)m_game->availArmies();
1788     stream << (quint32)currentPlayer()->getNbAvailArmies();
1789     qCDebug(KSIRK_LOG) << "sending DisplayRecycleDetails " << currentPlayer()->name() << (quint32)currentPlayer()->getNbAvailArmies()
1790       << " at " << __FILE__ << ", line " << __LINE__;
1791 //       qCDebug(KSIRK_LOG) << "sending DisplayRecycleDetails " << currentPlayer()->name() << m_game->availArmies()
1792 //       << " at " << __FILE__ << ", line " << __LINE__;
1793       sendMessage(buffer,DisplayRecycleDetails);
1794 
1795 
1796   //    qCDebug(KSIRK_LOG) << "OUT  KGameWindow::setupPlayers";
1797 
1798   }
1799 }
1800 
1801 void GameAutomaton::countriesDistribution()
1802 {
1803   qCDebug(KSIRK_LOG);
1804   unsigned int initialNbArmies;
1805   QList< int > vect;
1806   QMap<QString,unsigned int> distributedCountriesNumberMap;
1807   PlayersArray::iterator it = playerList()->begin();
1808   initialNbArmies = ((Player*)(*playerList()->begin()))->getNbAvailArmies();
1809   PlayersArray::iterator it_end = playerList()->end();
1810   for (; it != it_end; it++)
1811   {
1812     distributedCountriesNumberMap[(*it)-> name()] = 0;
1813   }
1814   // creates a vector containing the numbers of the countries
1815   for (unsigned int i = 0; i < m_game->theWorld()->getNbCountries()  ; i++) vect.push_back(i);
1816 
1817   // do while the vector not empty (will distribute one country each turn and
1818   // remove its number from the vector)
1819   while (vect.size())
1820   {
1821     // chooses randomly a position in the remaining countries vector
1822     int h = Dice::roll(vect.size()) - 1;
1823 
1824     // moves an iterator up to the position chosen
1825     QList< int >::iterator it = vect.begin();
1826     for (int itPos = 0; itPos < h-1; itPos++) it++;
1827 
1828     // affect the country that have the number at this position
1829     QByteArray buffer;
1830     QDataStream stream(&buffer, QIODevice::WriteOnly);
1831     stream << (m_game->theWorld()->getCountries().at(*it)->name()) << currentPlayer()-> name();
1832     qCDebug(KSIRK_LOG) << (m_game->theWorld()->getCountries().at(*it)->name()) << currentPlayer()-> name();
1833     distributedCountriesNumberMap[currentPlayer()-> name()] = distributedCountriesNumberMap[currentPlayer()-> name()]+1;
1834     sendMessage(buffer,CountryOwner);
1835     //m_game->theWorld()->getCountries().at(*it)-> owner(currentPlayer());
1836     m_game->setCurrentPlayerToNext(false);
1837 
1838     // removes the chosen country number from the vector, thus reducing its size
1839     vect.erase(it);
1840   }
1841   it = playerList()->begin();
1842   it_end = playerList()->end();
1843   for (; it != it_end; it++)
1844   {
1845     ((GameLogic::Player*)(*it))->setNbAvailArmies(((GameLogic::Player*)(*it))->getNbAvailArmies() - distributedCountriesNumberMap[(*it)-> name()], true);
1846     
1847     ((GameLogic::Player*)(*it))->incrNbCountries(distributedCountriesNumberMap[(*it)-> name()]);
1848   }
1849 //   qCDebug(KSIRK_LOG) << "All countries are now distributed.";
1850   m_game->setCurrentPlayerToFirst();
1851   QString nextPlayerName = currentPlayer()->name();
1852   QByteArray buffer;
1853   QDataStream stream(&buffer, QIODevice::WriteOnly);
1854   stream << (quint32)((GameLogic::Player*)(currentPlayer()))->getNbAvailArmies();
1855 //   qCDebug(KSIRK_LOG) << "  Setting status " << nextPlayerName << " / " << m_game->availArmies();
1856   QPixmap pm = playerNamed(nextPlayerName)->getFlag()->image(0);
1857   KMessageParts messageParts;
1858   messageParts
1859     << pm
1860     << kli18n("%1: %2 armies to place").untranslatedText()
1861     << nextPlayerName
1862     <<  QString::number( initialNbArmies - distributedCountriesNumberMap[nextPlayerName]);
1863   qCDebug(KSIRK_LOG) << "Message parts size= " << messageParts.size();
1864   m_game->broadcastChangeItem(messageParts, ID_STATUS_MSG2);
1865   m_game->showMessage(i18n("Now, place your armies in your countries<br>by clicking in the target countries."));
1866   state(INTERLUDE);
1867   m_game->setNextPlayerActionEnabled(false);
1868 }
1869 
1870 void GameAutomaton::sendCountries()
1871 {
1872   QByteArray buffer;
1873   QDataStream stream(&buffer, QIODevice::WriteOnly);
1874 
1875   m_game->theWorld()->sendCountries(stream);
1876   sendMessage(buffer,SetupCountries);
1877 }
1878 
1879 void GameAutomaton::movingFigthersArrived()
1880 {
1881   qCDebug(KSIRK_LOG);
1882   state(FIGHT_ANIMATE);
1883   QByteArray buffer;
1884   QDataStream stream(&buffer, QIODevice::WriteOnly);
1885   sendMessage(buffer,AnimCombat);
1886 }
1887 
1888 void GameAutomaton::movingArmiesArrived()
1889 {
1890   qCDebug(KSIRK_LOG);
1891 //   m_game->terminateAttackSequence();
1892 }
1893 
1894 void GameAutomaton::movingArmyArrived(Country* country, unsigned int number)
1895 {
1896   qCDebug(KSIRK_LOG) << number ;
1897   country->incrNbArmies(number);
1898   country->createArmiesSprites();
1899   checkGoal(country->owner());
1900 }
1901 
1902 void GameAutomaton::firingFinished()
1903 {
1904   qCDebug(KSIRK_LOG);
1905   if (isAdmin())
1906   {
1907     m_game->resolveAttack();
1908     state(EXPLOSION_ANIMATE);
1909   }
1910 }
1911 
1912 void GameAutomaton::explosionFinished()
1913 {
1914   qCDebug(KSIRK_LOG);
1915   if (isAdmin())
1916   {
1917     switch (gameStatus())
1918     {
1919       case KGame::Pause:
1920         m_game->setStateBeforeNewGame(FIGHT_BRINGBACK);
1921         break;
1922       case KGame::Run:;
1923       default:
1924         state(FIGHT_BRINGBACK);
1925     }
1926   }
1927 }
1928 
1929 void GameAutomaton::displayGoals()
1930 {
1931   qCDebug(KSIRK_LOG);
1932   PlayersArray::iterator it = playerList()->begin();
1933   PlayersArray::iterator it_end = playerList()->end();
1934   for (; it != it_end; it++)
1935   {
1936     if ( (dynamic_cast<Player*>(*it) != nullptr)
1937         && ( ! dynamic_cast<Player*>(*it)-> isVirtual() )
1938         && ( ! dynamic_cast<Player*>(*it)-> isAI() ) )
1939     {
1940       KMessageBox::information(
1941           game(),
1942           i18n("%1, your goal will be displayed. Please<br>"
1943                "make sure that no other player can see it!",(*it)->name()),
1944           i18n("KsirK - Displaying Goal"));
1945       dynamic_cast<Player*>(*it)->goal().show();
1946     }
1947   }
1948   m_aicannotrunhack = false;
1949 }
1950 
1951 void GameAutomaton::moveSlide()
1952 {
1953   qCDebug(KSIRK_LOG);
1954   if (!currentPlayer()->isVirtual())
1955     m_game->slideInvade(m_game->firstCountry(), m_game->secondCountry(),InvasionSlider::Moving);
1956 }
1957 
1958 /**
1959   * Change the automatic attack state.
1960   * @param activated new state
1961   */
1962 void GameAutomaton::setAttackAuto(bool activated)
1963 {
1964   QByteArray buffer;
1965   QDataStream stream(&buffer, QIODevice::WriteOnly);
1966   stream << (quint32)activated;
1967 
1968   sendMessage(buffer,AttackAuto);
1969 }
1970 
1971 void GameAutomaton::slotNetworkData(int msgid, const QByteArray &buffer, quint32 receiver, quint32 sender)
1972 {
1973   qCDebug(KSIRK_LOG) << "msg " << msgid << " ; rec="<<receiver << " snd=" << sender ;
1974   if (m_game == nullptr)
1975   {
1976     exit(0);
1977   }
1978 
1979   if (msgid < CountryOwner || msgid>= UnusedLastMessageId)
1980   {
1981     return;
1982   }
1983   qCDebug(KSIRK_LOG) << "("<<KsirkMessagesIdsNames[msgid-(KGameMessage::IdUser+1)]<<", " << receiver << ", " << sender << ")";
1984   QDataStream stream(const_cast<QByteArray*>(&buffer), QIODevice::ReadOnly);
1985   QString countryName, playerName, nationName;
1986   QPointF point;
1987   quint32 removable;
1988   quint32 theState;
1989   quint32 nbArmies;
1990   quint32 newState;
1991   quint32 statusBarId, messagePartsNb, messagePartsCounter, logStatus;
1992   quint32 propId, prop2Id;
1993   quint32 playerId;
1994   quint32 nbVotes = 0;
1995   quint32 explosing;
1996   KMessageParts messageParts;
1997   QString messagePart;
1998   Player* player;
1999   PlayerMatrix waitedPlayerDef(this);
2000   quint32 nbWaitedPlayers;
2001   quint32 waitedPlayerId;
2002   QString waitedPlayerPassword;
2003   quint32 nbCountries;
2004   Country* country;
2005   quint32 msgId;
2006   QString ack;
2007   QString msg;
2008   Goal goal(this);
2009   QString playersNames;
2010   QPixmap pm;
2011   quint32 A1, A2, A3, D1, D2, NKA, NKD;
2012   quint32 win;
2013   quint32 attackAutoValue;
2014   quint32 availArmies;
2015   quint32 elemType;
2016   quint32 nb;
2017   
2018   if (currentPlayer() != nullptr && currentPlayer()->getFlag() != nullptr)
2019   {
2020     pm = currentPlayer()->getFlag()->image(0);
2021   }
2022 
2023   QByteArray sendBuffer;
2024   QDataStream sendStream(&sendBuffer, QIODevice::WriteOnly);
2025   switch (msgid)
2026   {
2027   case CountryOwner:
2028     stream >> countryName >> playerName;
2029     qCDebug(KSIRK_LOG) << "CountryOwner for " << (void*)m_game->theWorld()->countryNamed(countryName) << " " << countryName << " and " << (void*)playerNamed(playerName) << playerName ;
2030     m_game->theWorld()->countryNamed(countryName)-> owner(playerNamed(playerName));
2031     break;
2032   case PlayerPutsInitialArmy:
2033     stream >> point;
2034     if (m_game->playerPutsInitialArmy(point))
2035     {
2036       if (isAdmin())
2037         gameEvent("playersLooped", point);
2038     }
2039     break;
2040   case PlayerPutsArmy:
2041     stream >> point >> removable;
2042     if (m_game->playerPutsArmy(point, removable) && isAdmin())
2043     {
2044       gameEvent("playersLooped", point);
2045     }
2046     break;
2047   case StateChange:
2048     stream >> theState;
2049     qCDebug(KSIRK_LOG) << "Got new state id: " << theState <<
2050         " ("<<GameStateNames[theState]<<")";
2051     m_state = GameState(theState);
2052     break;
2053   case PlayerChange:
2054     stream >> playerName;
2055     if (!isAdmin())
2056     {
2057       m_currentPlayer = playerName;
2058       m_currentPlayerPlayed = false;
2059     }
2060     break;
2061   case RegisterCountry:
2062     stream >> countryName >> propId >> prop2Id;
2063     m_nbArmiesIdsNamesCountriesMap.insert(int(propId),countryName);
2064     m_namesNbArmiesIdsCountriesMap.insert(countryName,int(propId));;
2065 //     m_nbAddedArmiesIdsNamesCountriesMap.insert(int(prop2Id),countryName);
2066 //     m_namesNbAddedArmiesIdsCountriesMap.insert(countryName,int(prop2Id));
2067     break;
2068   case PlayerAvailArmies:
2069     if (sender == gameId()) break;
2070     stream >> playerName >> nbArmies;
2071     if (playerNamed(playerName) != nullptr)
2072       playerNamed(playerName)->setNbAvailArmies((unsigned int)nbArmies, false);
2073     break;
2074 /*  case KGameWinAvailArmies:
2075     if (sender == gameId()) break;
2076     stream >> nbArmies;
2077     m_game->availArmies(nbArmies);*/
2078     break;
2079   case ChangeItem:
2080     if (sender == gameId()) break;
2081     stream >> statusBarId >> logStatus >> messagePartsNb;
2082     qCDebug(KSIRK_LOG) << "Got ChangeItem on " << statusBarId << " ; nb= " << messagePartsNb;
2083     for (messagePartsCounter = 0; messagePartsCounter < messagePartsNb; ++messagePartsCounter)
2084     {
2085       stream >> elemType;
2086       if (elemType == KMessageParts::Text)
2087       {
2088         stream >> messagePart;
2089         messageParts << messagePart;
2090         qCDebug(KSIRK_LOG) << " message part: " << messagePart;
2091       }
2092       else if (elemType == KMessageParts::StringId)
2093       {
2094         stream >> msgId;
2095         messageParts << msgForId(msgId);
2096         qCDebug(KSIRK_LOG) << " message part for id "<<msgId<<": " << msgForId(msgId);
2097       }
2098       else if (elemType == KMessageParts::Pixmap)
2099       {
2100         stream >> pm;
2101         messageParts << pm;
2102       }
2103     }
2104     m_game->changeItem(messageParts,statusBarId, logStatus);
2105     break;
2106   case DisplayRecyclingButtons:
2107     m_game->getRightDialog()->updateRecycleDetails(nullptr,true,0);
2108     m_game->displayRecyclingButtons();
2109     break;
2110   case ClearHighlighting:
2111     m_game->clearHighlighting();
2112     break;
2113   case ActionRecycling:
2114     if (isAdmin())
2115     {
2116       m_game->actionRecycling();
2117       state(NEWARMIES);
2118     }
2119     break;
2120   case ClearGameActionsToolbar:
2121     break;
2122   case DisplayDefenseButtons:
2123     stream >> playerName;
2124     if ( (!playerNamed(playerName)->isVirtual())
2125       && (!playerNamed(playerName)->isAI()) && (!isDefenseAuto()))
2126     {
2127       defCountry = this->game()->secondCountry();
2128       m_game->displayDefenseWindow();
2129     }
2130     messageParts << kli18n("%1 chooses its defense").untranslatedText() << playerName;
2131     m_game->broadcastChangeItem(messageParts, ID_STATUS_MSG2);
2132     break;
2133   case ActionDefense:
2134     stream >> nbArmies;
2135     if (isAdmin())
2136       m_game->defense((unsigned int)nbArmies);
2137     break;
2138   case FirstCountry:
2139     stream >> countryName;
2140     qCDebug(KSIRK_LOG) << "FirstCountry " << countryName ;
2141     m_game->firstCountry(m_game->theWorld()->countryNamed(countryName));
2142     break;
2143   case SecondCountry:
2144     stream >> countryName;
2145     qCDebug(KSIRK_LOG) << "SecondCountry " << countryName ;
2146     m_game->secondCountry(m_game->theWorld()->countryNamed(countryName));
2147     break;
2148   case InitCombatMovement:
2149     m_game->initCombatMovement();
2150     break;
2151   case AnimCombat:
2152     m_game->animCombat();
2153     break;
2154   case TerminateAttackSequence:
2155     {
2156       // update country display
2157       if (m_game->terminateAttackSequence())
2158       {
2159         // Re-display the world view
2160         m_game->showMap();
2161 
2162         setAttackAuto(false);
2163 //         setDefenseAuto(false);
2164         if(!currentPlayer()->isAI() && !currentPlayer()->isVirtual())
2165         {
2166           m_game->slideInvade(m_game->firstCountry(), m_game->secondCountry());
2167         }
2168         if (isAdmin())
2169         {
2170           state(INVADE);
2171         }
2172       }
2173       else if (isAdmin())
2174       {
2175         // if there is more than 1 army on my country and automatic
2176         // attack is activated
2177         if (m_game->firstCountry()->nbArmies() > 1 && m_attackAuto)
2178         {
2179           // continue automatically attacking by making the same attack
2180           state(WAIT1);
2181           if (m_game->firstCountry()->nbArmies() > 3)
2182           {
2183             gameEvent("actionAttack3", m_game->secondCountry()->centralPoint());
2184           }
2185           else if (m_game->firstCountry()->nbArmies() > 2)
2186           {
2187             gameEvent("actionAttack2", m_game->secondCountry()->centralPoint());
2188           }
2189           else
2190           {
2191             gameEvent("actionAttack1", m_game->secondCountry()->centralPoint());
2192           }
2193 
2194         // else wait user choice
2195         }
2196         else
2197         {
2198           // Re-display the world view
2199           m_game->showMap();
2200 
2201           setAttackAuto(false);
2202 //           setDefenseAuto(false);
2203           state(WAIT);
2204         }
2205       }
2206       m_game->firstCountry()-> createArmiesSprites();
2207       m_game->secondCountry()-> createArmiesSprites();
2208     }
2209     break;
2210   case DecrNbArmies:
2211     stream >> countryName >> nbArmies;
2212     m_game->theWorld()->countryNamed(countryName)->decrNbArmies(nbArmies);
2213     [[fallthrough]];
2214   case StartLocalCurrentAI:
2215     m_game->startLocalCurrentAI();
2216     break;
2217   case Invade:
2218     stream >> nbArmies;
2219     nb = nbArmies;
2220     while (nb >= 10)
2221     {
2222       if (m_game-> invade(10))
2223         m_game-> incrNbMovedArmies(10);
2224       nb -= 10;
2225     }
2226     while (nb >= 5)
2227     {
2228       if (m_game-> invade(5))
2229         m_game-> incrNbMovedArmies(5);
2230       nb -= 5;
2231     }
2232     while (nb > 0)
2233     {
2234       if (m_game-> invade(1))
2235         m_game-> incrNbMovedArmies(1);
2236       nb--;
2237     }
2238     
2239     break;
2240   case Retreat:
2241     stream >> nbArmies;
2242     if (m_game-> retreat(nbArmies))
2243       m_game-> decrNbMovedArmies(nbArmies);
2244     break;
2245   case  NextPlayerNormal:
2246     if (isAdmin())
2247     {
2248       stream >> playerName;
2249       stream >> newState;
2250       if (playerName == currentPlayer()->name() &&  m_game->nextPlayerNormal())
2251       {
2252         if (newState > 0)
2253         {
2254           qCDebug(KSIRK_LOG) << "at " <<  __FILE__ << ", line " << __LINE__ << ", setting state to " << newState ;
2255           state(GameState(newState));
2256         }
2257       }
2258     }
2259     break;
2260   case  NextPlayerRecycling:
2261     if (isAdmin())
2262     {
2263       stream >> newState;
2264       if (m_game->nextPlayerRecycling())
2265       {
2266         m_choosedToRecycleNumber = 0;
2267         if (newState > 0)
2268         {
2269           qCDebug(KSIRK_LOG) << "at " <<  __FILE__ << ", line " << __LINE__ << ", setting state to " << newState ;
2270           state(GameState(newState));
2271           m_game->slotContextualHelp();
2272         }
2273       }
2274     }
2275     break;
2276   case ShowArmiesToPlace:
2277     messageParts << pm << kli18n("%1: %2 armies to place").untranslatedText() << (currentPlayer()-> name())
2278       << QString::number(currentPlayer()-> getNbAvailArmies());
2279     m_game->broadcastChangeItem(messageParts, ID_STATUS_MSG2);
2280     m_game->showMessage(i18n("Now, place your armies in your countries<br>by clicking in the target countries."));
2281     break;
2282   case PlayerRemovesArmy:
2283     stream >> point;
2284     m_game->playerRemovesArmy(point);
2285     break;
2286   case VoteRecyclingFinished:
2287     if (isAdmin())
2288     {
2289 //       stream >> playerName;
2290       messageParts << kli18n("%1 choose to end recycling; there are now %2 players who want so").untranslatedText();
2291       stream >> nbVotes;
2292       stream >> playerId;
2293       playersNames = ((Player*)(findPlayer(playerId)))->name();
2294       if (!m_choosedToRecycle.contains(playerId))
2295       {
2296         m_choosedToRecycle.push_back(playerId);
2297       }
2298       else
2299       {
2300         nbVotes--;
2301       }
2302 
2303       for (quint32 i = 1 ; i < nbVotes; i++)
2304       {
2305         stream >> playerId;
2306         playersNames += QString(", ") + ((Player*)(findPlayer(playerId)))->name();
2307         if (!m_choosedToRecycle.contains(playerId))
2308         {
2309           m_choosedToRecycle.push_back(playerId);
2310         }
2311         else
2312         {
2313           nbVotes--;
2314         }
2315       }
2316       qCDebug(KSIRK_LOG) << "VoteRecyclingFinished nb before: " << m_choosedToRecycleNumber ;
2317       m_choosedToRecycleNumber+=nbVotes;
2318       qCDebug(KSIRK_LOG) << "VoteRecyclingFinished nb after : " << m_choosedToRecycleNumber ;
2319       messageParts << playersNames << QString::number(m_choosedToRecycleNumber);
2320       m_game->broadcastChangeItem(messageParts, ID_NO_STATUS_MSG);
2321       if (m_choosedToRecycleNumber == (unsigned int)(playerList()->count()))
2322       {
2323         m_game->actionRecyclingFinished();
2324         m_choosedToRecycle.clear();
2325       }
2326     }
2327     break;
2328   case CancelShiftSource:
2329     m_game-> cancelShiftSource();
2330     if (isAdmin())
2331     {
2332       state(SHIFT1);
2333     }
2334     break;
2335   case ChangePlayerNation:
2336     stream >> playerId;
2337 //     qCDebug(KSIRK_LOG) << "Got ChangePlayerNation for player id " << playerId ;
2338     player = (Player*)(findPlayer(playerId));
2339 //     qCDebug(KSIRK_LOG) << "Found player id " << player;
2340     if (player && !player->isVirtual())
2341     {
2342       changePlayerNation(player);
2343     }
2344     break;
2345   case ChangePlayerName:
2346     stream >> playerId;
2347     player = (Player*)(findPlayer(playerId));
2348     if (player && !player->isVirtual())
2349     {
2350       changePlayerName(player);
2351     }
2352     break;
2353   case StartGame:
2354     if (isAdmin())
2355       startGame();
2356     break;
2357   case SetNation:
2358     stream >> playerName >> nationName;
2359     playerNamed(playerName)->setNation(nationName);
2360     break;
2361   case SetBarFlagButton:
2362     stream >> playerName;
2363     qCDebug(KSIRK_LOG) << "Calling setBarFlagButton for player " << playerNamed(playerName) << " named " << playerName ;
2364     m_game->setBarFlagButton(playerNamed(playerName));
2365     break;
2366   case FinishMoves:
2367     m_game->finishMoves();
2368     break;
2369   case AnimExplosion:
2370     stream >> explosing;
2371     qCDebug(KSIRK_LOG) << "AnimExplosion" << explosing;
2372     if (m_game->backGnd()->bgIsArena())
2373     {
2374       m_game->animExplosionForArena();
2375     }
2376     else
2377     {
2378       if (explosing != 0 && explosing != 1 && explosing != 2)
2379       {
2380         KMessageBox::information(m_game, i18n("Problem : no one destroyed"), i18n("KsirK - Error!"));
2381       }
2382       else
2383       {
2384         m_game->animExplosion(explosing);
2385       }
2386     }
2387     break;
2388   case SetupOnePlayer:
2389     if (receiver == gameId())
2390     {
2391       m_game->setupOnePlayer();
2392     }
2393     break;
2394   case SetupWaitedPlayer:
2395     stream >> nbWaitedPlayers;
2396     for (quint32 i = 0; i < nbWaitedPlayers; i++)
2397     {
2398       stream >> waitedPlayerDef;
2399       m_game->waitedPlayers().push_back(waitedPlayerDef);
2400     }
2401     m_game->setupOneWaitedPlayer();
2402     break;
2403   case ValidateWaitedPlayerPassword:
2404     if (isAdmin())
2405     {
2406       stream >> waitedPlayerId >> waitedPlayerPassword;
2407 //       qCDebug(KSIRK_LOG) << "Validating password for waited player " << waitedPlayerId << " : " << m_game->waitedPlayers()[waitedPlayerId].password << " / " << waitedPlayerPassword ;
2408       if (m_game->waitedPlayers()[waitedPlayerId].password == waitedPlayerPassword)
2409       {
2410         sendStream << waitedPlayerId;
2411         sendMessage(sendBuffer,ValidPassword, sender);
2412       }
2413       else
2414       {
2415         sendMessage(sendBuffer,InvalidPassword, sender);
2416       }
2417     }
2418     break;
2419   case ValidPassword:
2420     if (receiver == gameId())
2421     {
2422       stream >> waitedPlayerId;
2423       m_game->createWaitedPlayer(waitedPlayerId);
2424     }
2425     break;
2426   case InvalidPassword:
2427     if (receiver == gameId())
2428     {
2429       KMessageBox::information(m_game, i18n("You entered an invalid password.\nPlease try again."), i18n("KsirK - Invalid password!"));
2430       m_game->setupOneWaitedPlayer();
2431     }
2432     break;
2433   case SetupCountries:
2434     stream >> nbCountries;
2435     for (unsigned int i = 0; i < nbCountries; i++)
2436     {
2437       stream >> countryName;
2438       country = m_game->theWorld()->countryNamed(countryName);
2439       qCDebug(KSIRK_LOG) << "Setting up country n°" << i << " on " << nbCountries << ", " << (void*)country << " named " << countryName ;
2440       if (country)
2441       {
2442         stream >> country;
2443       }
2444     }
2445     break;
2446   case AddMsgIdPair:
2447     stream >> msg >> msgId;
2448     m_msgs2ids.insert(msg,msgId);
2449     m_ids2msgs.insert(msgId,msg);
2450     break;
2451   case CheckGoal:
2452     if (isAdmin())
2453     {
2454       qCDebug(KSIRK_LOG) << "CheckGoal: ";
2455       stream >> playerId;
2456       player = dynamic_cast< Player* >(findPlayer(playerId));
2457       if (player)
2458       {
2459         if (player->checkGoal())
2460         {
2461           qCDebug(KSIRK_LOG) << "    goal reached for " << player->name();
2462           qCDebug(KSIRK_LOG) << "    setting state to " << GameStateNames[GAME_OVER];
2463 //           m_game->haltTimer();
2464           setGameStatus(KGame::End);
2465           state(GAME_OVER);
2466           sendStream << player->id();
2467           qCDebug(KSIRK_LOG) << "    sending Winner";
2468           sendMessage(sendBuffer,Winner);
2469         }
2470       }
2471     }
2472     break;
2473   case SetGoalFor:
2474     if (isAdmin())
2475     {
2476       stream >> playerId;
2477       setGoalFor(dynamic_cast<Player*>(findPlayer(playerId)));
2478     }
2479     break;
2480   case GoalForIs:
2481     qCDebug(KSIRK_LOG) << "GoalForIs: ";
2482     stream >> playerId;
2483     qCDebug(KSIRK_LOG) << "  player id: " << playerId ;
2484     stream >> goal;
2485     player = dynamic_cast<Player*>(findPlayer(playerId));
2486     if (player != nullptr)
2487     {
2488       player->goal(goal);
2489     }
2490     break;
2491   case FinalizePlayers:
2492       qCDebug(KSIRK_LOG) << "Got message FinalizePlayers";
2493       finalizePlayers();
2494     break;
2495   case Winner:
2496     QObject::disconnect(messageServer(),&KMessageServer::connectionLost,
2497                         this,&GameAutomaton::slotConnectionToClientBroken);
2498     stream >> playerId;
2499     m_game->winner(dynamic_cast<Player*>(findPlayer(playerId)));
2500     break;
2501   case NbPlayers:
2502     stream >> m_nbPlayers;
2503     break;
2504   case Acknowledge:
2505       stream >> playerId;
2506       stream >> ack;
2507       if (!isAdmin() && !dynamic_cast<Player*>(findPlayer(playerId))->isVirtual())
2508       {
2509         qCDebug(KSIRK_LOG) << "Got message Acknowledge" << playerId << ack;
2510         dynamic_cast<Player*>(findPlayer(playerId))->acknowledge(ack);
2511       }
2512     break;
2513   case DisplayGoals:
2514       qCDebug(KSIRK_LOG) << "Got message DisplayGoals";
2515       QTimer::singleShot(0,this,&GameAutomaton::displayGoals);
2516     break;
2517   case DisplayFightResult:
2518       qCDebug(KSIRK_LOG) << "Got message DisplayFightResult";
2519       stream >> A1 >> A2 >> A3 >> D1 >> D2 >> NKA >> NKD >> win;
2520       m_game->getRightDialog()->displayFightResult(A1,A2,A3,D1,D2,NKA,NKD,win);
2521     break;
2522   case MoveSlide:
2523       qCDebug(KSIRK_LOG) << "Got message MoveSlide";
2524       moveSlide();
2525     break;
2526   case InvasionFinished:
2527       qCDebug(KSIRK_LOG) << "Got message InvasionFinished";
2528       if (isAdmin())
2529       {
2530         gameEvent("actionInvasionFinished", point);
2531       }
2532     break;
2533   case AttackAuto:
2534       qCDebug(KSIRK_LOG) << "Got message AttackAuto";
2535       stream >> attackAutoValue;
2536       m_attackAuto = attackAutoValue;
2537     break;
2538   case DisplayRecycleDetails:
2539       stream >> playerName;
2540       stream >> availArmies;
2541       qCDebug(KSIRK_LOG) << "Got message DisplayRecycleDetails "
2542           << playerName << availArmies;
2543       m_game->getRightDialog()->displayRecycleDetails(playerNamed(playerName),availArmies);
2544 //       bool value;
2545 //       if (playerNamed(playerName)->isAI() || playerNamed(playerName)->isVirtual())
2546 //       {
2547 //         value = false;
2548 //       }
2549 //       else
2550 //       {
2551 //         value = true;
2552 //       }
2553       m_game->setNextPlayerActionEnabled(false);
2554     break;
2555   case CurrentPlayerPlayed:
2556     m_currentPlayerPlayed = true;
2557     break;
2558   case ResetPlayersDistributionData:
2559     resetPlayersDistributionData();
2560     break;
2561   case NewGameSetupMsg:
2562     qCDebug(KSIRK_LOG) << "Got message NewGameSetupMsg";
2563     stream >> *m_game->newGameSetup();
2564     break;
2565   default: ;
2566   }
2567 }
2568 
2569 #if HAVE_JABBER_SUPPORT
2570 void GameAutomaton::askForJabberGames()
2571 {
2572   m_game->askForJabberGames();
2573 }
2574 #endif
2575 
2576 QSvgRenderer& GameAutomaton::rendererFor(const QString& skinName)
2577 {
2578   if (!m_renderers.contains(skinName))
2579   {
2580     m_renderers.insert(skinName,new QSvgRenderer(this));
2581   }
2582   return *m_renderers[skinName];
2583 }
2584 
2585 KGameSvgDocument& GameAutomaton::svgDomFor(const QString& skinName)
2586 {
2587   if (!m_svgDoms.contains(skinName))
2588   {
2589     m_svgDoms.insert(skinName,KGameSvgDocument());
2590   }
2591   return m_svgDoms[skinName];
2592 }
2593 
2594 bool GameAutomaton::startingGame() const
2595 {
2596   qCDebug(KSIRK_LOG) << m_startingGame;
2597   return m_startingGame;
2598 }
2599 
2600 bool GameAutomaton::isDefenseAuto()
2601 {
2602   return m_defenseAuto.isDefenseAuto(m_game->firstCountry(),m_game->secondCountry());
2603 }
2604 
2605 void GameAutomaton::setDefenseAuto(bool activated)
2606 {
2607   m_defenseAuto.value = activated;
2608   if (activated)
2609   {
2610     m_defenseAuto.firstCountry = m_game->firstCountry();
2611     m_defenseAuto.secondCountry= m_game->secondCountry();
2612   }
2613   else
2614   {
2615     m_defenseAuto.firstCountry = nullptr;
2616     m_defenseAuto.secondCountry= nullptr;
2617   }
2618 }
2619 
2620 void GameAutomaton::resetPlayersDistributionData()
2621 {
2622   foreach (KPlayer* p, *playerList())
2623   {
2624     if ( !p->isVirtual() )
2625     {
2626       ((GameLogic::Player*)p)->reset();
2627     }
2628   }
2629 }
2630 
2631 void GameAutomaton::actionNextPlayer()
2632 {
2633   if ( currentPlayer()->isVirtual()
2634     || currentPlayer()->isAI()
2635     || m_currentPlayerPlayed
2636     || (KMessageBox::questionTwoActions (m_game,
2637                                     i18n("%1, you have not played anything this turn.\nDo you really want to lose your turn?",m_currentPlayer),
2638                                     i18n("Really Next Player?"),
2639                                     KGuiItem(i18nc("@action:button", "Next Player")),
2640                                     KStandardGuiItem::cancel())
2641        == KMessageBox::PrimaryAction) )
2642   {
2643     QByteArray buffer;
2644     QDataStream stream(&buffer, QIODevice::WriteOnly);
2645     stream << currentPlayer()->name();
2646     stream << (quint32)NEWARMIES;
2647     qCDebug(KSIRK_LOG) << "(state " << stateName() << ") sending NextPlayerNormal" << currentPlayer()->name() << NEWARMIES;
2648     sendMessage(buffer,NextPlayerNormal);
2649     m_game-> cancelAction();
2650   }
2651 }
2652 
2653 void GameAutomaton::removeAllPlayers()
2654 {
2655   qCDebug(KSIRK_LOG);
2656   m_currentPlayer = "";
2657   
2658   /* Bug 304362. KPlayer destructor removes
2659    * player from the list and makes iterators invalid.
2660    * qDeleteAll crashes in that case. */
2661   while (!playerList()->isEmpty()) 
2662   {
2663     delete playerList()->takeFirst();
2664   }
2665   // qDeleteAll(*playerList());
2666   // playerList()->clear();
2667 }
2668 
2669 // Bug 308527.
2670 void GameAutomaton::removeAllGoals()
2671 {
2672     qCDebug(KSIRK_LOG);
2673     while (!goals().isEmpty())
2674         delete goals().takeFirst();
2675 }
2676 
2677 void GameAutomaton::newGameNext()
2678 {
2679   qCDebug(KSIRK_LOG);
2680   m_startingGame = true;
2681   state(INIT);
2682   
2683   qCDebug(KSIRK_LOG) << "Changing skin";
2684   m_skin = m_game->newGameSetup()->skin();
2685   if (m_game->newGameSetup()->networkGameType() == Socket)
2686   {
2687     offerConnections(m_game->newGameSetup()->tcpPort());
2688   }
2689   m_game->finishSetupPlayers();
2690 }
2691 
2692 void GameAutomaton::checkGoal(Player* player) 
2693 {
2694   QByteArray buffer;
2695   QDataStream stream(&buffer, QIODevice::WriteOnly);
2696   if (player == nullptr)
2697     stream << currentPlayer()->id();
2698   else
2699     stream << player->id();
2700   qCDebug(KSIRK_LOG) << "sending CheckGoal";
2701   sendMessage(buffer,CheckGoal);
2702 }
2703 
2704 
2705 } // closing namespace GameLogic
2706 } // closing namespace Ksirk
2707 
2708 #include "moc_gameautomaton.cpp"