1 // Copyright (C) 2008 Ole Laursen
3 // This program is free software; you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation; either version 3 of the License, or
6 // (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU Library General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #include "game-client.h"
23 #include "network-connection.h"
26 #include "network-action.h"
27 #include "network-history.h"
28 #include "playerlist.h"
29 #include "network_player.h"
30 #include "xmlhelper.h"
32 #include "real_player.h"
33 #include "network_player.h"
36 GameClient * GameClient::s_instance = 0;
39 GameClient* GameClient::getInstance()
42 s_instance = new GameClient();
47 void GameClient::deleteInstance()
55 GameClient::GameClient()
61 GameClient::~GameClient()
63 if (network_connection.get() != NULL)
64 network_connection->send(MESSAGE_TYPE_PARTICIPANT_DISCONNECT, d_nickname);
67 void GameClient::start(std::string host, guint32 port, std::string nick)
73 network_connection.reset(new NetworkConnection());
74 network_connection->connected.connect(
75 sigc::mem_fun(this, &GameClient::onConnected));
76 network_connection->connection_lost.connect(
77 sigc::mem_fun(this, &GameClient::onConnectionLost));
78 network_connection->got_message.connect(
79 sigc::mem_fun(this, &GameClient::onGotMessage));
80 network_connection->connectToHost(host, port);
83 void GameClient::onConnected()
85 std::cerr << "connected" << std::endl;
88 network_connection->send(MESSAGE_TYPE_PING, "");
90 client_connected.emit();
93 void GameClient::onConnectionLost()
95 std::cerr << "connection lost" << std::endl;
97 client_disconnected.emit();
99 client_could_not_connect.emit();
102 void GameClient::sat_down(Player *player, std::string nickname)
106 if (player->getType() == Player::NETWORKED)
107 dynamic_cast<NetworkPlayer*>(player)->setConnected(true);
108 player_sits.emit(player, nickname);
111 void GameClient::stood_up(Player *player, std::string nickname)
115 if (player->getType() == Player::HUMAN)
117 //this covers the "boot", or forcibly-stand case.
118 NetworkPlayer *new_p = new NetworkPlayer(*player);
119 Playerlist::getInstance()->swap(player, new_p);
121 new_p->setConnected(false);
123 else if (player->getType() == Player::NETWORKED)
124 dynamic_cast<NetworkPlayer*>(player)->setConnected(false);
125 player_stands.emit(player, nickname);
128 void GameClient::onGotMessage(MessageType type, std::string payload)
130 std::cerr << "got message of type " << type << std::endl;
132 case MESSAGE_TYPE_PING:
133 network_connection->send(MESSAGE_TYPE_PONG, "PONGOGOGO");
136 case MESSAGE_TYPE_PONG:
137 network_connection->send(MESSAGE_TYPE_PARTICIPANT_CONNECT, d_nickname);
140 case MESSAGE_TYPE_SENDING_ACTIONS:
144 case MESSAGE_TYPE_SENDING_MAP:
145 gotScenario(payload);
148 case MESSAGE_TYPE_PARTICIPANT_CONNECTED:
149 remote_participant_joins.emit(payload);
151 case MESSAGE_TYPE_PARTICIPANT_DISCONNECTED:
152 remote_participant_departs.emit(payload);
155 case MESSAGE_TYPE_REQUEST_SEAT_MANIFEST:
156 case MESSAGE_TYPE_P1_SIT:
157 case MESSAGE_TYPE_P2_SIT:
158 case MESSAGE_TYPE_P3_SIT:
159 case MESSAGE_TYPE_P4_SIT:
160 case MESSAGE_TYPE_P5_SIT:
161 case MESSAGE_TYPE_P6_SIT:
162 case MESSAGE_TYPE_P7_SIT:
163 case MESSAGE_TYPE_P8_SIT:
164 case MESSAGE_TYPE_P1_STAND:
165 case MESSAGE_TYPE_P2_STAND:
166 case MESSAGE_TYPE_P3_STAND:
167 case MESSAGE_TYPE_P4_STAND:
168 case MESSAGE_TYPE_P5_STAND:
169 case MESSAGE_TYPE_P6_STAND:
170 case MESSAGE_TYPE_P7_STAND:
171 case MESSAGE_TYPE_P8_STAND:
172 case MESSAGE_TYPE_PARTICIPANT_CONNECT:
173 case MESSAGE_TYPE_PARTICIPANT_DISCONNECT:
174 case MESSAGE_TYPE_CHAT:
175 case MESSAGE_TYPE_ROUND_OVER:
176 //FIXME: faulty server.
179 case MESSAGE_TYPE_CHATTED:
180 gotChatMessage("", payload);
182 //this is the client realizing that some other player joined the server
183 case MESSAGE_TYPE_P1_SAT_DOWN:
184 sat_down(Playerlist::getInstance()->getPlayer(0), payload);
186 case MESSAGE_TYPE_P2_SAT_DOWN:
187 sat_down(Playerlist::getInstance()->getPlayer(1), payload);
189 case MESSAGE_TYPE_P3_SAT_DOWN:
190 sat_down(Playerlist::getInstance()->getPlayer(2), payload);
192 case MESSAGE_TYPE_P4_SAT_DOWN:
193 sat_down(Playerlist::getInstance()->getPlayer(3), payload);
195 case MESSAGE_TYPE_P5_SAT_DOWN:
196 sat_down(Playerlist::getInstance()->getPlayer(4), payload);
198 case MESSAGE_TYPE_P6_SAT_DOWN:
199 sat_down(Playerlist::getInstance()->getPlayer(5), payload);
201 case MESSAGE_TYPE_P7_SAT_DOWN:
202 sat_down(Playerlist::getInstance()->getPlayer(6), payload);
204 case MESSAGE_TYPE_P8_SAT_DOWN:
205 sat_down(Playerlist::getInstance()->getPlayer(7), payload);
207 case MESSAGE_TYPE_P1_STOOD_UP:
208 stood_up(Playerlist::getInstance()->getPlayer(0), payload);
210 case MESSAGE_TYPE_P2_STOOD_UP:
211 stood_up(Playerlist::getInstance()->getPlayer(1), payload);
213 case MESSAGE_TYPE_P3_STOOD_UP:
214 stood_up(Playerlist::getInstance()->getPlayer(2), payload);
216 case MESSAGE_TYPE_P4_STOOD_UP:
217 stood_up(Playerlist::getInstance()->getPlayer(3), payload);
219 case MESSAGE_TYPE_P5_STOOD_UP:
220 stood_up(Playerlist::getInstance()->getPlayer(4), payload);
222 case MESSAGE_TYPE_P6_STOOD_UP:
223 stood_up(Playerlist::getInstance()->getPlayer(5), payload);
225 case MESSAGE_TYPE_P7_STOOD_UP:
226 stood_up(Playerlist::getInstance()->getPlayer(6), payload);
228 case MESSAGE_TYPE_P8_STOOD_UP:
229 stood_up(Playerlist::getInstance()->getPlayer(7), payload);
232 case MESSAGE_TYPE_SENDING_HISTORY:
233 gotHistories(payload);
236 case MESSAGE_TYPE_SERVER_DISCONNECT:
237 client_disconnected.emit();
240 case MESSAGE_TYPE_TURN_ORDER:
241 gotTurnOrder (payload);
244 case MESSAGE_TYPE_KILL_PLAYER:
245 gotKillPlayer(Playerlist::getInstance()->getPlayer(atoi(payload.c_str())));
248 case MESSAGE_TYPE_ROUND_START:
254 void GameClient::gotKillPlayer(Player *player)
259 void GameClient::onHistoryDone(NetworkHistory *history)
261 std::string desc = history->toString();
262 std::cerr << "Game Client got " << desc <<"\n";
264 if (history->getHistory()->getType() == History::PLAYER_VANQUISHED)
265 local_player_died(history->getOwner());
267 histories.push_back(history);
269 clearNetworkHistorylist(histories);
272 void GameClient::onActionDone(NetworkAction *action)
274 std::string desc = action->toString();
275 std::cerr << "Game Client got " << desc <<"\n";
277 if (action->getAction()->getType() == Action::END_TURN)
278 local_player_moved(action->getOwner());
279 if (action->getAction()->getType() == Action::INIT_TURN)
280 local_player_starts_move(action->getOwner());
282 actions.push_back(action);
284 clearNetworkActionlist(actions);
287 void GameClient::sendActions()
289 std::ostringstream os;
290 XML_Helper helper(&os);
293 helper.openTag("actions");
295 for (std::list<NetworkAction *>::iterator i = actions.begin(),
296 end = actions.end(); i != end; ++i)
303 std::cerr << "sending actions" << std::endl;
304 network_connection->send(MESSAGE_TYPE_SENDING_ACTIONS, os.str());
307 void GameClient::sendHistories()
309 std::ostringstream os;
310 XML_Helper helper(&os);
313 helper.openTag("histories");
315 for (std::list<NetworkHistory *>::iterator i = histories.begin(),
316 end = histories.end(); i != end; ++i)
321 network_connection->send(MESSAGE_TYPE_SENDING_HISTORY, os.str());
324 void GameClient::sit_down (Player *player)
329 switch (player->getId())
331 case 0: type = MESSAGE_TYPE_P1_SIT; break;
332 case 1: type = MESSAGE_TYPE_P2_SIT; break;
333 case 2: type = MESSAGE_TYPE_P3_SIT; break;
334 case 3: type = MESSAGE_TYPE_P4_SIT; break;
335 case 4: type = MESSAGE_TYPE_P5_SIT; break;
336 case 5: type = MESSAGE_TYPE_P6_SIT; break;
337 case 6: type = MESSAGE_TYPE_P7_SIT; break;
338 case 7: type = MESSAGE_TYPE_P8_SIT; break;
342 RealPlayer *new_p = new RealPlayer (*player);
343 Playerlist::getInstance()->swap(player, new_p);
344 stopListeningForLocalEvents(player);
345 listenForLocalEvents(new_p);
347 network_connection->send(type, d_nickname);
350 void GameClient::stand_up (Player *player)
355 switch (player->getId())
357 case 0: type = MESSAGE_TYPE_P1_STAND; break;
358 case 1: type = MESSAGE_TYPE_P2_STAND; break;
359 case 2: type = MESSAGE_TYPE_P3_STAND; break;
360 case 3: type = MESSAGE_TYPE_P4_STAND; break;
361 case 4: type = MESSAGE_TYPE_P5_STAND; break;
362 case 5: type = MESSAGE_TYPE_P6_STAND; break;
363 case 6: type = MESSAGE_TYPE_P7_STAND; break;
364 case 7: type = MESSAGE_TYPE_P8_STAND; break;
368 //now turning a human player into a network player
369 NetworkPlayer *new_p = new NetworkPlayer(*player);
370 Playerlist::getInstance()->swap(player, new_p);
371 stopListeningForLocalEvents(new_p);
373 new_p->setConnected(false);
374 network_connection->send(type, d_nickname);
377 void GameClient::chat(std::string message)
379 network_connection->send(MESSAGE_TYPE_CHAT, d_nickname + ":" + message);
382 void GameClient::request_seat_manifest()
384 network_connection->send(MESSAGE_TYPE_REQUEST_SEAT_MANIFEST, "");
387 void GameClient::gotTurnOrder (std::string payload)
389 std::list<guint32> player_ids;
390 std::stringstream players;
391 players.str(payload);
394 while (players.eof() == false)
399 player_ids.push_back(ival);
401 Playerlist::getInstance()->reorder(player_ids);
402 playerlist_reorder_received.emit();
405 void GameClient::sendRoundOver()
407 network_connection->send(MESSAGE_TYPE_ROUND_OVER, "");