1 // Copyright (C) 2008 Ole Laursen
2 // Copyright (C) 2008 Ben Asselstine
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Library General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 #include "game-server.h"
25 #include "network-server.h"
27 #include "xmlhelper.h"
28 #include "GameScenario.h"
29 #include "playerlist.h"
31 #include "network-action.h"
32 #include "network-history.h"
33 #include "Configuration.h"
34 #include "network_player.h"
35 #include "real_player.h"
36 #include "GameScenarioOptions.h"
44 std::list<guint32> players;
45 std::list<NetworkAction *> actions;
46 std::list<NetworkHistory *> histories;
51 GameServer * GameServer::s_instance = 0;
54 GameServer* GameServer::getInstance()
57 s_instance = new GameServer();
62 void GameServer::deleteInstance()
71 GameServer::GameServer()
75 GameServer::~GameServer()
77 //say goodbye to all participants
78 for (std::list<Participant *>::iterator i = participants.begin(),
79 end = participants.end(); i != end; ++i)
80 network_server->send((*i)->conn, MESSAGE_TYPE_SERVER_DISCONNECT, "bye");
82 for (std::list<Participant *>::iterator i = participants.begin(),
83 end = participants.end(); i != end; ++i)
85 players_seated_locally.clear();
88 bool GameServer::isListening()
90 if (network_server.get() != NULL)
91 return network_server->isListening();
96 void GameServer::start(GameScenario *game_scenario, int port, std::string nick)
98 setGameScenario(game_scenario);
101 if (network_server.get() != NULL && network_server->isListening())
103 network_server.reset(new NetworkServer());
104 network_server->got_message.connect
105 (sigc::mem_fun(this, &GameServer::onGotMessage));
106 network_server->connection_lost.connect
107 (sigc::mem_fun(this, &GameServer::onConnectionLost));
108 network_server->connection_made.connect
109 (sigc::mem_fun(this, &GameServer::onConnectionMade));
111 network_server->startListening(port);
113 listenForLocalEvents(Playerlist::getInstance()->getNeutral());
116 void GameServer::checkRoundOver()
118 bool all_finished = true;
119 for (std::list<Participant *>::iterator i = participants.begin(),
120 end = participants.end(); i != end; ++i)
122 if ((*i)->round_finished == false)
124 all_finished = false;
131 printf ("hooray! we're all done the round.\n");
132 for (std::list<Participant *>::iterator i = participants.begin(),
133 end = participants.end(); i != end; ++i)
134 (*i)->round_finished = false;
136 //now we can send the start round message, and begin the round ourselves.
137 for (std::list<Participant *>::iterator i = participants.begin(),
138 end = participants.end(); i != end; ++i)
139 network_server->send((*i)->conn, MESSAGE_TYPE_ROUND_START, "");
145 void GameServer::gotRoundOver(void *conn)
147 Participant *part = findParticipantByConn(conn);
150 //mark the participant as finished for this round
151 part->round_finished = true;
152 //are all participants finished?
158 void GameServer::gotChat(void *conn, std::string message)
160 Participant *part = findParticipantByConn(conn);
163 gotChatMessage(part->nickname, message);
164 for (std::list<Participant *>::iterator i = participants.begin(),
165 end = participants.end(); i != end; ++i)
167 //if ((*i)->conn != part->conn)
168 //network_server->send((*i)->conn, MESSAGE_TYPE_CHATTED,
169 //part->nickname + ":" + message);
171 network_server->send((*i)->conn, MESSAGE_TYPE_CHATTED,
178 void GameServer::onGotMessage(void *conn, MessageType type, std::string payload)
180 std::cerr << "got message of type " << type << std::endl;
182 case MESSAGE_TYPE_PING:
183 std::cerr << "sending pong" << std::endl;
184 network_server->send(conn, MESSAGE_TYPE_PONG, "");
187 case MESSAGE_TYPE_PONG:
190 case MESSAGE_TYPE_SENDING_ACTIONS:
191 gotRemoteActions(conn, payload);
194 case MESSAGE_TYPE_SENDING_MAP:
195 // should never occur
198 case MESSAGE_TYPE_SENDING_HISTORY:
199 gotRemoteHistory(conn, payload);
202 case MESSAGE_TYPE_PARTICIPANT_CONNECT:
206 case MESSAGE_TYPE_REQUEST_SEAT_MANIFEST:
208 sendChatRoster(conn);
211 case MESSAGE_TYPE_P1_SIT:
212 sit(conn, Playerlist::getInstance()->getPlayer(0), payload);
215 case MESSAGE_TYPE_P2_SIT:
216 sit(conn, Playerlist::getInstance()->getPlayer(1), payload);
219 case MESSAGE_TYPE_P3_SIT:
220 sit(conn, Playerlist::getInstance()->getPlayer(2), payload);
223 case MESSAGE_TYPE_P4_SIT:
224 sit(conn, Playerlist::getInstance()->getPlayer(3), payload);
227 case MESSAGE_TYPE_P5_SIT:
228 sit(conn, Playerlist::getInstance()->getPlayer(4), payload);
231 case MESSAGE_TYPE_P6_SIT:
232 sit(conn, Playerlist::getInstance()->getPlayer(5), payload);
235 case MESSAGE_TYPE_P7_SIT:
236 sit(conn, Playerlist::getInstance()->getPlayer(6), payload);
239 case MESSAGE_TYPE_P8_SIT:
240 sit(conn, Playerlist::getInstance()->getPlayer(7), payload);
243 case MESSAGE_TYPE_P1_STAND:
244 stand(conn, Playerlist::getInstance()->getPlayer(0), payload);
247 case MESSAGE_TYPE_P2_STAND:
248 stand(conn, Playerlist::getInstance()->getPlayer(1), payload);
251 case MESSAGE_TYPE_P3_STAND:
252 stand(conn, Playerlist::getInstance()->getPlayer(2), payload);
255 case MESSAGE_TYPE_P4_STAND:
256 stand(conn, Playerlist::getInstance()->getPlayer(3), payload);
259 case MESSAGE_TYPE_P5_STAND:
260 stand(conn, Playerlist::getInstance()->getPlayer(4), payload);
263 case MESSAGE_TYPE_P6_STAND:
264 stand(conn, Playerlist::getInstance()->getPlayer(5), payload);
267 case MESSAGE_TYPE_P7_STAND:
268 stand(conn, Playerlist::getInstance()->getPlayer(6), payload);
271 case MESSAGE_TYPE_P8_STAND:
272 stand(conn, Playerlist::getInstance()->getPlayer(7), payload);
275 case MESSAGE_TYPE_PARTICIPANT_DISCONNECT:
279 case MESSAGE_TYPE_PARTICIPANT_CONNECTED:
282 case MESSAGE_TYPE_CHAT:
283 gotChat(conn, payload);
286 case MESSAGE_TYPE_ROUND_OVER:
291 case MESSAGE_TYPE_PARTICIPANT_DISCONNECTED:
294 case MESSAGE_TYPE_P1_SAT_DOWN:
295 case MESSAGE_TYPE_P2_SAT_DOWN:
296 case MESSAGE_TYPE_P3_SAT_DOWN:
297 case MESSAGE_TYPE_P4_SAT_DOWN:
298 case MESSAGE_TYPE_P5_SAT_DOWN:
299 case MESSAGE_TYPE_P6_SAT_DOWN:
300 case MESSAGE_TYPE_P7_SAT_DOWN:
301 case MESSAGE_TYPE_P8_SAT_DOWN:
302 case MESSAGE_TYPE_P1_STOOD_UP:
303 case MESSAGE_TYPE_P2_STOOD_UP:
304 case MESSAGE_TYPE_P3_STOOD_UP:
305 case MESSAGE_TYPE_P4_STOOD_UP:
306 case MESSAGE_TYPE_P5_STOOD_UP:
307 case MESSAGE_TYPE_P6_STOOD_UP:
308 case MESSAGE_TYPE_P7_STOOD_UP:
309 case MESSAGE_TYPE_P8_STOOD_UP:
310 case MESSAGE_TYPE_SERVER_DISCONNECT:
311 case MESSAGE_TYPE_CHATTED:
312 case MESSAGE_TYPE_TURN_ORDER:
313 case MESSAGE_TYPE_KILL_PLAYER:
314 case MESSAGE_TYPE_ROUND_START:
320 void GameServer::onConnectionMade(void *conn)
322 remote_participant_connected.emit();
325 void GameServer::onConnectionLost(void *conn)
327 std::cerr << "connection lost" << std::endl;
329 Participant *part = findParticipantByConn(conn);
332 std::list<guint32> players_to_stand = part->players;
335 participants.remove(part);
336 for (std::list<guint32>::iterator it = players_to_stand.begin();
337 it != players_to_stand.end(); it++)
338 notifyStand(Playerlist::getInstance()->getPlayer(*it), d_nickname);
339 remote_participant_disconnected.emit();
344 Participant *GameServer::findParticipantByConn(void *conn)
346 for (std::list<Participant *>::iterator i = participants.begin(),
347 end = participants.end(); i != end; ++i)
348 if ((*i)->conn == conn)
354 void GameServer::onActionDone(NetworkAction *action)
356 std::string desc = action->toString();
357 std::cerr << "Game Server got " << desc <<"\n";
359 if (action->getAction()->getType() == Action::END_TURN)
360 local_player_moved(action->getOwner());
361 if (action->getAction()->getType() == Action::INIT_TURN)
362 local_player_starts_move(action->getOwner());
364 for (std::list<Participant *>::iterator i = participants.begin(),
365 end = participants.end(); i != end; ++i)
367 (*i)->actions.push_back(action);
369 clearNetworkActionlist((*i)->actions);
374 void GameServer::onHistoryDone(NetworkHistory *history)
376 std::string desc = history->toString();
377 std::cerr << "Game Server got " << desc <<"\n";
379 if (history->getHistory()->getType() == History::PLAYER_VANQUISHED)
380 local_player_died(history->getOwner());
382 for (std::list<Participant *>::iterator i = participants.begin(),
383 end = participants.end(); i != end; ++i)
385 (*i)->histories.push_back(history);
387 clearNetworkHistorylist((*i)->histories);
391 void GameServer::notifyJoin(std::string nickname)
393 remote_participant_joins.emit(nickname);
394 for (std::list<Participant *>::iterator i = participants.begin(),
395 end = participants.end(); i != end; ++i)
397 network_server->send((*i)->conn, MESSAGE_TYPE_PARTICIPANT_CONNECTED,
399 //network_server->send((*i)->conn, MESSAGE_TYPE_CHATTED,
400 //nickname + " connected.");
402 gotChatMessage("[server]", nickname + " connected.");
405 void GameServer::notifyDepart(void *conn, std::string nickname)
407 remote_participant_departs.emit(nickname);
408 for (std::list<Participant *>::iterator i = participants.begin(),
409 end = participants.end(); i != end; ++i)
411 if ((*i)->conn == conn)
413 network_server->send((*i)->conn, MESSAGE_TYPE_PARTICIPANT_DISCONNECTED,
415 network_server->send((*i)->conn, MESSAGE_TYPE_CHATTED,
416 nickname + " disconnected.");
418 gotChatMessage("", nickname + " disconnected.");
421 void GameServer::notifySit(Player *player, std::string nickname)
425 player_sits.emit(player, nickname);
427 switch (player->getId())
429 case 0: type = MESSAGE_TYPE_P1_SAT_DOWN; break;
430 case 1: type = MESSAGE_TYPE_P2_SAT_DOWN; break;
431 case 2: type = MESSAGE_TYPE_P3_SAT_DOWN; break;
432 case 3: type = MESSAGE_TYPE_P4_SAT_DOWN; break;
433 case 4: type = MESSAGE_TYPE_P5_SAT_DOWN; break;
434 case 5: type = MESSAGE_TYPE_P6_SAT_DOWN; break;
435 case 6: type = MESSAGE_TYPE_P7_SAT_DOWN; break;
436 case 7: type = MESSAGE_TYPE_P8_SAT_DOWN; break;
441 for (std::list<Participant *>::iterator i = participants.begin(),
442 end = participants.end(); i != end; ++i)
444 network_server->send((*i)->conn, type, nickname);
445 network_server->send((*i)->conn, MESSAGE_TYPE_CHATTED,
446 nickname + " assumes control of " +
447 player->getName() +".");
449 gotChatMessage("", nickname + " assumes control of " +
450 player->getName() +".");
453 void GameServer::join(void *conn, std::string nickname)
455 bool new_participant = false;
456 std::cout << "JOIN: " << conn << std::endl;
458 Participant *part = findParticipantByConn(conn);
460 part = new Participant;
462 part->nickname = nickname;
463 participants.push_back(part);
464 new_participant = true;
471 notifyJoin(nickname);
474 void GameServer::depart(void *conn)
476 std::cout << "DEPART: " << conn << std::endl;
478 Participant *part = findParticipantByConn(conn);
480 notifyDepart(conn, part->nickname);
481 //we don't delete the participant, it gets deleted when it disconnects.
482 //see onConnectionLost
485 bool GameServer::player_already_sitting(Player *p)
487 //check if the player p is already sitting down as a participant.
488 for (std::list<Participant *>::iterator i = participants.begin(),
489 end = participants.end(); i != end; ++i)
491 for (std::list<guint32>::iterator j = (*i)->players.begin();
492 j != (*i)->players.end(); j++)
494 if (p->getId() == *j)
501 void GameServer::sit(void *conn, Player *player, std::string nickname)
503 std::cout << "SIT: " << conn << " " << player << std::endl;
505 if (!player || !conn)
507 Participant *part = findParticipantByConn(conn);
511 //fixme: is another player already sitting here?
512 if (player_already_sitting(player) == true)
515 add_to_player_list(part->players, player->getId());
518 dynamic_cast<NetworkPlayer*>(player)->setConnected(true);
520 notifySit(player, nickname);
523 void GameServer::notifyStand(Player *player, std::string nickname)
527 player_stands.emit(player, nickname);
529 switch (player->getId())
531 case 0: type = MESSAGE_TYPE_P1_STOOD_UP; break;
532 case 1: type = MESSAGE_TYPE_P2_STOOD_UP; break;
533 case 2: type = MESSAGE_TYPE_P3_STOOD_UP; break;
534 case 3: type = MESSAGE_TYPE_P4_STOOD_UP; break;
535 case 4: type = MESSAGE_TYPE_P5_STOOD_UP; break;
536 case 5: type = MESSAGE_TYPE_P6_STOOD_UP; break;
537 case 6: type = MESSAGE_TYPE_P7_STOOD_UP; break;
538 case 7: type = MESSAGE_TYPE_P8_STOOD_UP; break;
543 for (std::list<Participant *>::iterator i = participants.begin(),
544 end = participants.end(); i != end; ++i)
546 network_server->send((*i)->conn, type, nickname);
547 network_server->send((*i)->conn, MESSAGE_TYPE_CHATTED,
548 nickname + " relinquishes control of " +
549 player->getName() +".");
551 gotChatMessage("", nickname + " relinquishes control of " +
552 player->getName() +".");
556 GameServer::add_to_player_list(std::list<guint32> &list, guint32 id)
559 for (std::list<guint32>::iterator i = list.begin(); i != list.end(); i++)
573 GameServer::remove_from_player_list(std::list<guint32> &list, guint32 id)
575 //remove player id from part.
576 for (std::list<guint32>::iterator i = list.begin();
577 i != list.end(); i++)
588 void GameServer::stand(void *conn, Player *player, std::string nickname)
590 std::cout << "STAND: " << conn << " " << player << std::endl;
591 if (!player || !conn)
594 Participant *part = findParticipantByConn(conn);
598 //remove player id from part.
599 bool found = remove_from_player_list (part->players, player->getId());
602 //okay somebody's trying to boot another player.
605 if (player && player->getType() == Player::NETWORKED)
606 dynamic_cast<NetworkPlayer*>(player)->setConnected(false);
607 notifyStand(player, nickname);
610 void GameServer::gotRemoteActions(void *conn, const std::string &payload)
613 for (std::list<Participant *>::iterator i = participants.begin(),
614 end = participants.end(); i != end; ++i)
615 if ((*i)->conn != conn)
616 network_server->send((*i)->conn, MESSAGE_TYPE_SENDING_ACTIONS, payload);
619 void GameServer::gotRemoteHistory(void *conn, const std::string &payload)
621 gotHistories(payload);
622 for (std::list<Participant *>::iterator i = participants.begin(),
623 end = participants.end(); i != end; ++i)
624 if ((*i)->conn != conn)
625 network_server->send((*i)->conn, MESSAGE_TYPE_SENDING_HISTORY, payload);
628 void GameServer::sendMap(Participant *part)
630 Playerlist *pl = Playerlist::getInstance();
632 // first hack the players so the player type we serialize is right
633 std::vector<Player*> players;
634 for (Playerlist::iterator i = pl->begin(); i != pl->end(); ++i)
636 bool connected = false;
637 players.push_back(*i);
638 if ((*i)->isComputer() == true)
640 NetworkPlayer *new_p = new NetworkPlayer(**i);
641 new_p->setConnected(connected);
646 // send the map, and save it to a file somewhere temporarily
647 std::string tmpfile = "lw.XXXX";
648 int fd = Glib::file_open_tmp(tmpfile, "lw.XXXX");
650 File::erase(tmpfile);
653 d_game_scenario->saveGame(tmpfile, "sav");
655 std::cerr << "sending map" << std::endl;
656 network_server->send(part->conn, MESSAGE_TYPE_SENDING_MAP, tmpfile);
657 File::erase (tmpfile);
659 // unhack the players
660 std::vector<Player*>::iterator j = players.begin();
661 for (Playerlist::iterator i = pl->begin(); i != pl->end(); ++i, ++j)
668 void GameServer::sendActions(Participant *part)
670 std::ostringstream os;
671 XML_Helper helper(&os);
674 helper.openTag("actions");
676 for (std::list<NetworkAction *>::iterator i = part->actions.begin(),
677 end = part->actions.end(); i != end; ++i)
682 std::cerr << "sending actions" << std::endl;
683 network_server->send(part->conn, MESSAGE_TYPE_SENDING_ACTIONS, os.str());
686 void GameServer::sendHistories(Participant *part)
688 std::ostringstream os;
689 XML_Helper helper(&os);
692 helper.openTag("histories");
694 for (std::list<NetworkHistory *>::iterator i = part->histories.begin(),
695 end = part->histories.end(); i != end; ++i)
700 std::cerr << "sending histories" << std::endl;
701 network_server->send(part->conn, MESSAGE_TYPE_SENDING_HISTORY, os.str());
704 bool GameServer::dumpActionsAndHistories(XML_Helper *helper, Player *player)
706 Participant *part = NULL;
707 for (std::list<Participant *>::iterator i = participants.begin(),
708 end = participants.end(); i != end; ++i)
711 for (std::list<guint32>::iterator it = (*i)->players.begin();
712 it != (*i)->players.end(); it++)
714 if (*it == player->getId())
729 for (std::list<NetworkHistory *>::iterator i = part->histories.begin(),
730 end = part->histories.end(); i != end; ++i)
732 for (std::list<NetworkAction *>::iterator i = part->actions.begin(),
733 end = part->actions.end(); i != end; ++i)
738 bool GameServer::dumpActionsAndHistories(XML_Helper *helper)
740 Player *player = Playerlist::getActiveplayer();
741 return dumpActionsAndHistories(helper, player);
744 void GameServer::sit_down (Player *player)
748 if (player->getType() == Player::NETWORKED)
750 //alright, we want to sit down as this player
751 //convert the network player to a human player
752 dynamic_cast<NetworkPlayer*>(player)->setConnected(true);
753 RealPlayer *new_p = new RealPlayer (*player);
754 Playerlist::getInstance()->swap(player, new_p);
755 stopListeningForLocalEvents(player);
756 listenForLocalEvents(new_p);
758 add_to_player_list (players_seated_locally, new_p->getId());
759 notifySit(new_p, d_nickname);
761 else if (player->getType() == Player::HUMAN)
767 stopListeningForLocalEvents(player);
768 listenForLocalEvents(player);
769 add_to_player_list (players_seated_locally, player->getId());
770 notifySit(player, d_nickname);
774 void GameServer::stand_up (Player *player)
778 if (player->getType() == Player::HUMAN)
780 //alright, we want to stand up as this player
781 //convert the player from a human player back to a network player
783 NetworkPlayer *new_p = new NetworkPlayer(*player);
784 Playerlist::getInstance()->swap(player, new_p);
785 stopListeningForLocalEvents(player);
787 new_p->setConnected(false);
788 notifyStand(new_p, d_nickname);
789 remove_from_player_list (players_seated_locally, new_p->getId());
791 else if (player->getType() == Player::NETWORKED)
797 stopListeningForLocalEvents(player);
798 remove_from_player_list (players_seated_locally, player->getId());
799 notifyStand(player, d_nickname);
803 void GameServer::chat (std::string message)
805 notifyChat(d_nickname + ":" + message);
808 void GameServer::notifyChat(std::string message)
810 gotChatMessage(d_nickname, message);
811 for (std::list<Participant *>::iterator i = participants.begin(),
812 end = participants.end(); i != end; ++i)
813 network_server->send((*i)->conn, MESSAGE_TYPE_CHATTED, message);
816 void GameServer::sendSeats(void *conn)
818 Participant *part = findParticipantByConn(conn);
821 //send seatedness info for remote participants
823 for (std::list<Participant *>::iterator i = participants.begin(),
824 end = participants.end(); i != end; ++i)
826 if ((*i)->conn == part->conn)
829 for (std::list<guint32>::iterator j = (*i)->players.begin();
830 j != (*i)->players.end(); j++)
832 Player *player = Playerlist::getInstance()->getPlayer(*j);
834 switch (player->getId())
836 case 0: type = MESSAGE_TYPE_P1_SAT_DOWN; break;
837 case 1: type = MESSAGE_TYPE_P2_SAT_DOWN; break;
838 case 2: type = MESSAGE_TYPE_P3_SAT_DOWN; break;
839 case 3: type = MESSAGE_TYPE_P4_SAT_DOWN; break;
840 case 4: type = MESSAGE_TYPE_P5_SAT_DOWN; break;
841 case 5: type = MESSAGE_TYPE_P6_SAT_DOWN; break;
842 case 6: type = MESSAGE_TYPE_P7_SAT_DOWN; break;
843 case 7: type = MESSAGE_TYPE_P8_SAT_DOWN; break;
847 network_server->send(part->conn, type, (*i)->nickname);
850 //send out seatedness info for local server
851 for (std::list<guint32>::iterator j = players_seated_locally.begin();
852 j != players_seated_locally.end(); j++)
854 Player *player = Playerlist::getInstance()->getPlayer(*j);
856 switch (player->getId())
858 case 0: type = MESSAGE_TYPE_P1_SAT_DOWN; break;
859 case 1: type = MESSAGE_TYPE_P2_SAT_DOWN; break;
860 case 2: type = MESSAGE_TYPE_P3_SAT_DOWN; break;
861 case 3: type = MESSAGE_TYPE_P4_SAT_DOWN; break;
862 case 4: type = MESSAGE_TYPE_P5_SAT_DOWN; break;
863 case 5: type = MESSAGE_TYPE_P6_SAT_DOWN; break;
864 case 6: type = MESSAGE_TYPE_P7_SAT_DOWN; break;
865 case 7: type = MESSAGE_TYPE_P8_SAT_DOWN; break;
869 network_server->send(part->conn, type, d_nickname);
873 void GameServer::sendChatRoster(void *conn)
875 Participant *part = findParticipantByConn(conn);
878 for (std::list<Participant *>::iterator i = participants.begin(),
879 end = participants.end(); i != end; ++i)
881 if ((*i)->conn == part->conn)
883 network_server->send(part->conn, MESSAGE_TYPE_PARTICIPANT_CONNECTED,
886 network_server->send(part->conn, MESSAGE_TYPE_PARTICIPANT_CONNECTED,
890 void GameServer::sendKillPlayer(Player *p)
892 std::stringstream player;
893 player << p->getId();
894 for (std::list<Participant *>::iterator i = participants.begin(),
895 end = participants.end(); i != end; ++i)
896 network_server->send((*i)->conn, MESSAGE_TYPE_KILL_PLAYER, player.str());
898 remote_player_died.emit(p);
901 void GameServer::sendTurnOrder()
903 std::stringstream players;
904 Playerlist *pl = Playerlist::getInstance();
905 for (Playerlist::iterator it = pl->begin(); it != pl->end(); it++)
906 players << (*it)->getId() << " ";
907 for (std::list<Participant *>::iterator i = participants.begin(),
908 end = participants.end(); i != end; ++i)
909 network_server->send((*i)->conn, MESSAGE_TYPE_TURN_ORDER, players.str());
910 playerlist_reorder_received.emit();