~ubuntu-branches/ubuntu/saucy/lordsawar/saucy

« back to all changes in this revision

Viewing changes to src/game-server.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Barry deFreese, Barry deFreese
  • Date: 2008-12-20 13:52:12 UTC
  • mfrom: (1.1.6 upstream) (5.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20081220135212-noeb2w3y98ebo7o9
Tags: 0.1.4-1
[ Barry deFreese ]
* New upstream release.
* Move 0.0.8-2.1 changelog entry to correct point in changelog.
* Make lordsawar-data suggest lordsawar.
* Update my e-mail address.
* Add build-depends on intltool, uuid-dev, and libboost-dev.
* Don't install locales since there are no translations currently.
* Add simple man page for new lordsawar-pbm binary.
* Drop gcc4.3 patches as they have been fixed upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
// Copyright (C) 2008 Ole Laursen
 
2
// Copyright (C) 2008 Ben Asselstine
2
3
//
3
4
//  This program is free software; you can redistribute it and/or modify
4
5
//  it under the terms of the GNU General Public License as published by
29
30
#include "player.h"
30
31
#include "network-action.h"
31
32
#include "network-history.h"
 
33
#include "Configuration.h"
 
34
#include "network_player.h"
 
35
#include "real_player.h"
 
36
#include "GameScenarioOptions.h"
32
37
 
33
38
 
34
39
class NetworkAction;
36
41
struct Participant
37
42
{
38
43
  void *conn;
39
 
  Player *player;
 
44
  std::list<Uint32> players;
40
45
  std::list<NetworkAction *> actions;
41
46
  std::list<NetworkHistory *> histories;
 
47
  std::string nickname;
 
48
  bool round_finished;
42
49
};
43
50
 
 
51
GameServer * GameServer::s_instance = 0;
 
52
 
 
53
 
 
54
GameServer* GameServer::getInstance()
 
55
{
 
56
    if (s_instance == 0)
 
57
        s_instance = new GameServer();
 
58
 
 
59
    return s_instance;
 
60
}
 
61
 
 
62
void GameServer::deleteInstance()
 
63
{
 
64
    if (s_instance)
 
65
        delete s_instance;
 
66
 
 
67
    s_instance = 0;
 
68
}
 
69
 
44
70
 
45
71
GameServer::GameServer()
46
72
{
48
74
 
49
75
GameServer::~GameServer()
50
76
{
 
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");
 
81
 
51
82
  for (std::list<Participant *>::iterator i = participants.begin(),
52
83
         end = participants.end(); i != end; ++i)
53
84
    delete *i;
54
 
}
55
 
 
56
 
void GameServer::start()
57
 
{
 
85
  players_seated_locally.clear();
 
86
}
 
87
 
 
88
bool GameServer::isListening()
 
89
{
 
90
  if (network_server.get() != NULL)
 
91
    return network_server->isListening();
 
92
  else
 
93
    return false;
 
94
}
 
95
 
 
96
void GameServer::start(GameScenario *game_scenario, int port, std::string nick)
 
97
{
 
98
  setGameScenario(game_scenario);
 
99
  setNickname(nick);
 
100
 
 
101
  if (network_server.get() != NULL && network_server->isListening())
 
102
    return;
58
103
  network_server.reset(new NetworkServer());
59
 
  network_server->got_message.connect(
60
 
    sigc::mem_fun(this, &GameServer::onGotMessage));
61
 
  network_server->connection_lost.connect(
62
 
    sigc::mem_fun(this, &GameServer::onConnectionLost));
 
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));
63
110
 
64
 
  int port = 12345;
65
111
  network_server->startListening(port);
66
112
 
67
 
  listenForActions();
68
 
  listenForHistories();
69
 
}
70
 
 
 
113
  listenForLocalEvents(Playerlist::getInstance()->getNeutral());
 
114
}
 
115
 
 
116
void GameServer::checkRoundOver()
 
117
{
 
118
  bool all_finished = true;
 
119
  for (std::list<Participant *>::iterator i = participants.begin(),
 
120
       end = participants.end(); i != end; ++i)
 
121
    {
 
122
      if ((*i)->round_finished == false)
 
123
        {
 
124
          all_finished = false;
 
125
          break;
 
126
        }
 
127
    }
 
128
 
 
129
  if (all_finished)
 
130
    {
 
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;
 
135
 
 
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, "");
 
140
 
 
141
      round_begins.emit();
 
142
    }
 
143
}
 
144
 
 
145
void GameServer::gotRoundOver(void *conn)
 
146
{
 
147
  Participant *part = findParticipantByConn(conn);
 
148
  if (part)
 
149
    {
 
150
      //mark the participant as finished for this round
 
151
      part->round_finished = true;
 
152
      //are all participants finished?
 
153
      checkRoundOver();
 
154
    }
 
155
  return;
 
156
}
 
157
 
 
158
void GameServer::gotChat(void *conn, std::string message)
 
159
{
 
160
  Participant *part = findParticipantByConn(conn);
 
161
  if (part)
 
162
    {
 
163
      gotChatMessage(part->nickname, message);
 
164
      for (std::list<Participant *>::iterator i = participants.begin(),
 
165
           end = participants.end(); i != end; ++i)
 
166
        {
 
167
          //if ((*i)->conn != part->conn)
 
168
          //network_server->send((*i)->conn, MESSAGE_TYPE_CHATTED, 
 
169
          //part->nickname + ":" + message);
 
170
          //else
 
171
          network_server->send((*i)->conn, MESSAGE_TYPE_CHATTED, 
 
172
                               message);
 
173
 
 
174
        }
 
175
    }
 
176
  return;
 
177
}
71
178
void GameServer::onGotMessage(void *conn, MessageType type, std::string payload)
72
179
{
73
180
  std::cerr << "got message of type " << type << std::endl;
81
188
    break;
82
189
 
83
190
  case MESSAGE_TYPE_SENDING_ACTIONS:
84
 
    gotActions(conn, payload);
 
191
    gotRemoteActions(conn, payload);
85
192
    break;
86
193
 
87
 
  case MESSAGE_TYPE_JOIN:
88
 
    join(conn);
89
 
    break;
90
 
    
91
194
  case MESSAGE_TYPE_SENDING_MAP:
92
195
    // should never occur
93
196
    break;
94
197
 
95
198
  case MESSAGE_TYPE_SENDING_HISTORY:
96
 
    gotHistory(conn, payload);
97
 
    break;
98
 
 
 
199
    gotRemoteHistory(conn, payload);
 
200
    break;
 
201
 
 
202
  case MESSAGE_TYPE_PARTICIPANT_CONNECT:
 
203
    join(conn, payload);
 
204
    break;
 
205
 
 
206
  case MESSAGE_TYPE_REQUEST_SEAT_MANIFEST:
 
207
    sendSeats(conn);
 
208
    sendChatRoster(conn);
 
209
    break;
 
210
 
 
211
  case MESSAGE_TYPE_P1_SIT:
 
212
    sit(conn, Playerlist::getInstance()->getPlayer(0), payload);
 
213
    break;
 
214
 
 
215
  case MESSAGE_TYPE_P2_SIT:
 
216
    sit(conn, Playerlist::getInstance()->getPlayer(1), payload);
 
217
    break;
 
218
 
 
219
  case MESSAGE_TYPE_P3_SIT:
 
220
    sit(conn, Playerlist::getInstance()->getPlayer(2), payload);
 
221
    break;
 
222
 
 
223
  case MESSAGE_TYPE_P4_SIT:
 
224
    sit(conn, Playerlist::getInstance()->getPlayer(3), payload);
 
225
    break;
 
226
 
 
227
  case MESSAGE_TYPE_P5_SIT:
 
228
    sit(conn, Playerlist::getInstance()->getPlayer(4), payload);
 
229
    break;
 
230
 
 
231
  case MESSAGE_TYPE_P6_SIT:
 
232
    sit(conn, Playerlist::getInstance()->getPlayer(5), payload);
 
233
    break;
 
234
 
 
235
  case MESSAGE_TYPE_P7_SIT:
 
236
    sit(conn, Playerlist::getInstance()->getPlayer(6), payload);
 
237
    break;
 
238
 
 
239
  case MESSAGE_TYPE_P8_SIT:
 
240
    sit(conn, Playerlist::getInstance()->getPlayer(7), payload);
 
241
    break;
 
242
 
 
243
  case MESSAGE_TYPE_P1_STAND:
 
244
    stand(conn, Playerlist::getInstance()->getPlayer(0), payload);
 
245
    break;
 
246
 
 
247
  case MESSAGE_TYPE_P2_STAND:
 
248
    stand(conn, Playerlist::getInstance()->getPlayer(1), payload);
 
249
    break;
 
250
 
 
251
  case MESSAGE_TYPE_P3_STAND:
 
252
    stand(conn, Playerlist::getInstance()->getPlayer(2), payload);
 
253
    break;
 
254
 
 
255
  case MESSAGE_TYPE_P4_STAND:
 
256
    stand(conn, Playerlist::getInstance()->getPlayer(3), payload);
 
257
    break;
 
258
 
 
259
  case MESSAGE_TYPE_P5_STAND:
 
260
    stand(conn, Playerlist::getInstance()->getPlayer(4), payload);
 
261
    break;
 
262
 
 
263
  case MESSAGE_TYPE_P6_STAND:
 
264
    stand(conn, Playerlist::getInstance()->getPlayer(5), payload);
 
265
    break;
 
266
 
 
267
  case MESSAGE_TYPE_P7_STAND:
 
268
    stand(conn, Playerlist::getInstance()->getPlayer(6), payload);
 
269
    break;
 
270
 
 
271
  case MESSAGE_TYPE_P8_STAND:
 
272
    stand(conn, Playerlist::getInstance()->getPlayer(7), payload);
 
273
    break;
 
274
 
 
275
  case MESSAGE_TYPE_PARTICIPANT_DISCONNECT:
 
276
    depart(conn);
 
277
    break;
 
278
 
 
279
  case MESSAGE_TYPE_PARTICIPANT_CONNECTED:
 
280
    break;
 
281
 
 
282
  case MESSAGE_TYPE_CHAT:
 
283
    gotChat(conn, payload);
 
284
    break;
 
285
 
 
286
  case MESSAGE_TYPE_ROUND_OVER:
 
287
    //what do we do now?
 
288
    gotRoundOver(conn);
 
289
    break;
 
290
 
 
291
  case MESSAGE_TYPE_PARTICIPANT_DISCONNECTED:
 
292
    break;
 
293
 
 
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:
 
315
    //faulty client
 
316
    break;
99
317
  }
100
318
}
101
319
 
 
320
void GameServer::onConnectionMade(void *conn)
 
321
{
 
322
  remote_participant_connected.emit();
 
323
}
 
324
 
102
325
void GameServer::onConnectionLost(void *conn)
103
326
{
104
327
  std::cerr << "connection lost" << std::endl;
105
 
  
 
328
 
106
329
  Participant *part = findParticipantByConn(conn);
107
330
  if (part)
108
 
    participants.remove(part);
 
331
    {
 
332
      std::list<Uint32> players_to_stand = part->players;
 
333
 
 
334
      depart(conn);
 
335
      participants.remove(part);
 
336
      for (std::list<Uint32>::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();
 
340
    }
109
341
  delete part;
110
342
}
111
343
 
112
344
Participant *GameServer::findParticipantByConn(void *conn)
113
345
{
114
346
  for (std::list<Participant *>::iterator i = participants.begin(),
115
 
         end = participants.end(); i != end; ++i)
 
347
       end = participants.end(); i != end; ++i)
116
348
    if ((*i)->conn == conn)
117
349
      return *i;
118
 
  
 
350
 
119
351
  return 0;
120
352
}
121
353
 
122
 
void GameServer::listenForActions()
123
 
{
124
 
  Playerlist *pl = Playerlist::getInstance();
125
 
  for (Playerlist::iterator i = pl->begin(); i != pl->end(); ++i)
126
 
    (*i)->acting.connect(sigc::mem_fun(this, &GameServer::onActionDone));
127
 
}
128
 
 
129
 
void GameServer::listenForHistories()
130
 
{
131
 
  Playerlist *pl = Playerlist::getInstance();
132
 
  for (Playerlist::iterator i = pl->begin(); i != pl->end(); ++i)
133
 
    (*i)->history_written.connect(sigc::mem_fun(this, &GameServer::onHistoryDone));
134
 
}
135
 
 
136
354
void GameServer::onActionDone(NetworkAction *action)
137
355
{
138
356
  std::string desc = action->toString();
139
357
  std::cerr << "Game Server got " << desc <<"\n";
140
358
 
 
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());
 
363
 
141
364
  for (std::list<Participant *>::iterator i = participants.begin(),
142
 
         end = participants.end(); i != end; ++i) {
143
 
    (*i)->actions.push_back(action);
144
 
    sendActions(*i);
145
 
    (*i)->actions.clear();
146
 
  }
 
365
       end = participants.end(); i != end; ++i) 
 
366
    {
 
367
      (*i)->actions.push_back(action);
 
368
      sendActions(*i);
 
369
      clearNetworkActionlist((*i)->actions);
 
370
    }
147
371
 
148
 
  delete action;
149
372
}
150
373
 
151
374
void GameServer::onHistoryDone(NetworkHistory *history)
153
376
  std::string desc = history->toString();
154
377
  std::cerr << "Game Server got " << desc <<"\n";
155
378
 
156
 
  for (std::list<Participant *>::iterator i = participants.begin(),
157
 
         end = participants.end(); i != end; ++i) {
158
 
    (*i)->histories.push_back(history);
159
 
    sendHistory(*i);
160
 
    (*i)->histories.clear();
161
 
  }
162
 
 
163
 
  delete history;
164
 
}
165
 
 
166
 
void GameServer::join(void *conn)
167
 
{
 
379
  if (history->getHistory()->getType() == History::PLAYER_VANQUISHED)
 
380
    local_player_died(history->getOwner());
 
381
 
 
382
  for (std::list<Participant *>::iterator i = participants.begin(),
 
383
       end = participants.end(); i != end; ++i) 
 
384
    {
 
385
      (*i)->histories.push_back(history);
 
386
      sendHistories(*i);
 
387
      clearNetworkHistorylist((*i)->histories);
 
388
    }
 
389
}
 
390
 
 
391
void GameServer::notifyJoin(std::string nickname)
 
392
{
 
393
  remote_participant_joins.emit(nickname);
 
394
  for (std::list<Participant *>::iterator i = participants.begin(),
 
395
       end = participants.end(); i != end; ++i) 
 
396
    {
 
397
      network_server->send((*i)->conn, MESSAGE_TYPE_PARTICIPANT_CONNECTED, 
 
398
                           nickname);
 
399
      //network_server->send((*i)->conn, MESSAGE_TYPE_CHATTED, 
 
400
      //nickname + " connected.");
 
401
    }
 
402
  gotChatMessage("[server]", nickname + " connected.");
 
403
}
 
404
 
 
405
void GameServer::notifyDepart(void *conn, std::string nickname)
 
406
{
 
407
  remote_participant_departs.emit(nickname);
 
408
  for (std::list<Participant *>::iterator i = participants.begin(),
 
409
       end = participants.end(); i != end; ++i) 
 
410
    {
 
411
      if ((*i)->conn == conn)
 
412
        continue;
 
413
      network_server->send((*i)->conn, MESSAGE_TYPE_PARTICIPANT_DISCONNECTED, 
 
414
                           nickname);
 
415
      network_server->send((*i)->conn, MESSAGE_TYPE_CHATTED, 
 
416
                           nickname + " disconnected.");
 
417
    }
 
418
  gotChatMessage("", nickname + " disconnected.");
 
419
}
 
420
 
 
421
void GameServer::notifySit(Player *player, std::string nickname)
 
422
{
 
423
  if (!player)
 
424
    return;
 
425
  player_sits.emit(player, nickname);
 
426
  MessageType type;
 
427
  switch (player->getId())
 
428
    {
 
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;
 
437
    default:
 
438
            return;
 
439
    }
 
440
 
 
441
  for (std::list<Participant *>::iterator i = participants.begin(),
 
442
       end = participants.end(); i != end; ++i) 
 
443
    {
 
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() +".");
 
448
    }
 
449
  gotChatMessage("", nickname + " assumes control of " + 
 
450
                 player->getName() +".");
 
451
}
 
452
 
 
453
void GameServer::join(void *conn, std::string nickname)
 
454
{
 
455
  bool new_participant = false;
168
456
  std::cout << "JOIN: " << conn << std::endl;
169
 
  
 
457
 
170
458
  Participant *part = findParticipantByConn(conn);
171
459
  if (!part) {
172
460
    part = new Participant;
173
461
    part->conn = conn;
174
 
    part->player = 0;
 
462
    part->nickname = nickname;
175
463
    participants.push_back(part);
 
464
    new_participant = true;
176
465
  }
177
 
 
178
 
  sendMap(part);
179
 
}
180
 
 
181
 
void GameServer::gotActions(void *conn, const std::string &payload)
182
 
{
183
 
}
184
 
 
185
 
void GameServer::gotHistory(void *conn, const std::string &payload)
186
 
{
 
466
  if (new_participant)
 
467
    {
 
468
      sendMap(part);
 
469
    }
 
470
 
 
471
  notifyJoin(nickname);
 
472
}
 
473
 
 
474
void GameServer::depart(void *conn)
 
475
{
 
476
  std::cout << "DEPART: " << conn << std::endl;
 
477
 
 
478
  Participant *part = findParticipantByConn(conn);
 
479
 
 
480
  notifyDepart(conn, part->nickname);
 
481
  //we don't delete the participant, it gets deleted when it disconnects.
 
482
  //see onConnectionLost
 
483
}
 
484
 
 
485
bool GameServer::player_already_sitting(Player *p)
 
486
{
 
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) 
 
490
    {
 
491
      for (std::list<Uint32>::iterator j = (*i)->players.begin(); 
 
492
           j != (*i)->players.end(); j++)
 
493
        {
 
494
          if (p->getId() == *j)
 
495
            return true;
 
496
        }
 
497
    }
 
498
  return false;
 
499
}
 
500
 
 
501
void GameServer::sit(void *conn, Player *player, std::string nickname)
 
502
{
 
503
  std::cout << "SIT: " << conn << " " << player << std::endl;
 
504
 
 
505
  if (!player || !conn)
 
506
    return;
 
507
  Participant *part = findParticipantByConn(conn);
 
508
  if (!part) 
 
509
    return;
 
510
 
 
511
  //fixme: is another player already sitting here?
 
512
  if (player_already_sitting(player) == true)
 
513
    return;
 
514
 
 
515
  add_to_player_list(part->players, player->getId());
 
516
 
 
517
  if (player)
 
518
    dynamic_cast<NetworkPlayer*>(player)->setConnected(true);
 
519
 
 
520
  notifySit(player, nickname);
 
521
}
 
522
 
 
523
void GameServer::notifyStand(Player *player, std::string nickname)
 
524
{
 
525
  if (!player)
 
526
    return;
 
527
  player_stands.emit(player, nickname);
 
528
  MessageType type;
 
529
  switch (player->getId())
 
530
    {
 
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;
 
539
    default:
 
540
            return;
 
541
    }
 
542
 
 
543
  for (std::list<Participant *>::iterator i = participants.begin(),
 
544
       end = participants.end(); i != end; ++i) 
 
545
    {
 
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() +".");
 
550
    }
 
551
  gotChatMessage("", nickname + " relinquishes control of " + 
 
552
                 player->getName() +".");
 
553
}
 
554
 
 
555
bool
 
556
GameServer::add_to_player_list(std::list<Uint32> &list, Uint32 id)
 
557
{
 
558
  bool found = false;
 
559
  for (std::list<Uint32>::iterator i = list.begin(); i != list.end(); i++)
 
560
    {
 
561
      if (*i == id)
 
562
        {
 
563
          found = true;
 
564
          break;
 
565
        }
 
566
    }
 
567
  if (found == false)
 
568
    list.push_back(id);
 
569
  return found;
 
570
}
 
571
 
 
572
bool
 
573
GameServer::remove_from_player_list(std::list<Uint32> &list, Uint32 id)
 
574
{
 
575
  //remove player id from part.
 
576
  for (std::list<Uint32>::iterator i = list.begin(); 
 
577
       i != list.end(); i++)
 
578
    {
 
579
      if (*i == id)
 
580
        {
 
581
          list.erase (i);
 
582
          return true;
 
583
        }
 
584
    }
 
585
  return false;
 
586
}
 
587
 
 
588
void GameServer::stand(void *conn, Player *player, std::string nickname)
 
589
{
 
590
  std::cout << "STAND: " << conn << " " << player << std::endl;
 
591
  if (!player || !conn)
 
592
    return;
 
593
 
 
594
  Participant *part = findParticipantByConn(conn);
 
595
  if (!part) 
 
596
    return;
 
597
 
 
598
  //remove player id from part.
 
599
  bool found = remove_from_player_list (part->players, player->getId());
 
600
 
 
601
  if (!found)
 
602
    //okay somebody's trying to boot another player.
 
603
    return;
 
604
 
 
605
  if (player && player->getType() == Player::NETWORKED)
 
606
    dynamic_cast<NetworkPlayer*>(player)->setConnected(false);
 
607
  notifyStand(player, nickname);
 
608
}
 
609
 
 
610
void GameServer::gotRemoteActions(void *conn, const std::string &payload)
 
611
{
 
612
  gotActions(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);
 
617
}
 
618
 
 
619
void GameServer::gotRemoteHistory(void *conn, const std::string &payload)
 
620
{
 
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);
187
626
}
188
627
 
189
628
void GameServer::sendMap(Participant *part)
190
629
{
191
630
  Playerlist *pl = Playerlist::getInstance();
192
 
  
 
631
 
193
632
  // first hack the players so the player type we serialize is right
194
 
  std::vector<Uint32> player_types;
195
 
  for (Playerlist::iterator i = pl->begin(); i != pl->end(); ++i) {
196
 
    player_types.push_back((*i)->getType());
197
 
    (*i)->setType(Player::NETWORKED);
198
 
  }
199
 
  
 
633
  std::vector<Player*> players;
 
634
  for (Playerlist::iterator i = pl->begin(); i != pl->end(); ++i) 
 
635
    {
 
636
      bool connected = false;
 
637
      players.push_back(*i);
 
638
      if ((*i)->getType() == Player::AI_FAST ||
 
639
          (*i)->getType() == Player::AI_SMART ||
 
640
          (*i)->getType() == Player::AI_DUMMY)
 
641
        connected = true;
 
642
      NetworkPlayer *new_p = new NetworkPlayer(**i);
 
643
      new_p->setConnected(connected);
 
644
      pl->swap(*i, new_p);
 
645
    }
 
646
 
200
647
 
201
648
  // send the map
202
649
  std::ostringstream os;
203
650
  XML_Helper helper(&os);
204
 
  Game::getScenario()->saveWithHelper(helper);
 
651
  d_game_scenario->saveWithHelper(helper);
205
652
  std::cerr << "sending map" << std::endl;
206
653
  network_server->send(part->conn, MESSAGE_TYPE_SENDING_MAP, os.str());
207
654
 
208
 
 
209
655
  // unhack the players
210
 
  std::vector<Uint32>::iterator j = player_types.begin();
211
 
  for (Playerlist::iterator i = pl->begin(); i != pl->end(); ++i, ++j) {
212
 
    (*i)->setType(Player::Type(*j));
213
 
  }
 
656
  std::vector<Player*>::iterator j = players.begin();
 
657
  for (Playerlist::iterator i = pl->begin(); i != pl->end(); ++i, ++j) 
 
658
    {
 
659
      pl->swap(*i, *j);
 
660
      //delete *i;
 
661
    }
214
662
}
215
663
 
216
664
void GameServer::sendActions(Participant *part)
220
668
 
221
669
  helper.begin("1");
222
670
  helper.openTag("actions");
223
 
  
 
671
 
224
672
  for (std::list<NetworkAction *>::iterator i = part->actions.begin(),
225
 
         end = part->actions.end(); i != end; ++i)
 
673
       end = part->actions.end(); i != end; ++i)
226
674
    (**i).save(&helper);
227
675
 
228
676
  helper.closeTag();
229
 
    
 
677
 
230
678
  std::cerr << "sending actions" << std::endl;
231
679
  network_server->send(part->conn, MESSAGE_TYPE_SENDING_ACTIONS, os.str());
232
680
}
233
681
 
234
 
void GameServer::sendHistory(Participant *part)
 
682
void GameServer::sendHistories(Participant *part)
235
683
{
236
684
  std::ostringstream os;
237
685
  XML_Helper helper(&os);
238
686
 
239
687
  helper.begin("1");
240
688
  helper.openTag("histories");
241
 
  
 
689
 
242
690
  for (std::list<NetworkHistory *>::iterator i = part->histories.begin(),
243
 
         end = part->histories.end(); i != end; ++i)
 
691
       end = part->histories.end(); i != end; ++i)
244
692
    (**i).save(&helper);
245
693
 
246
694
  helper.closeTag();
247
 
    
 
695
 
248
696
  std::cerr << "sending histories" << std::endl;
249
697
  network_server->send(part->conn, MESSAGE_TYPE_SENDING_HISTORY, os.str());
250
698
}
251
699
 
 
700
bool GameServer::dumpActionsAndHistories(XML_Helper *helper, Player *player)
 
701
{
 
702
  Participant *part = NULL;
 
703
  for (std::list<Participant *>::iterator i = participants.begin(),
 
704
       end = participants.end(); i != end; ++i)
 
705
    {
 
706
      bool found = false;
 
707
      for (std::list<Uint32>::iterator it = (*i)->players.begin();
 
708
           it != (*i)->players.end(); it++)
 
709
        {
 
710
          if (*it == player->getId())
 
711
            {
 
712
              found = true;
 
713
              break;
 
714
            }
 
715
        }
 
716
 
 
717
      if (found)
 
718
        {
 
719
          part = *i;
 
720
          break;
 
721
        }
 
722
    }
 
723
  if (part == NULL)
 
724
    return false;
 
725
  for (std::list<NetworkHistory *>::iterator i = part->histories.begin(),
 
726
       end = part->histories.end(); i != end; ++i)
 
727
    (**i).save(helper);
 
728
  for (std::list<NetworkAction *>::iterator i = part->actions.begin(),
 
729
       end = part->actions.end(); i != end; ++i)
 
730
    (**i).save(helper);
 
731
  return true;
 
732
}
 
733
 
 
734
bool GameServer::dumpActionsAndHistories(XML_Helper *helper)
 
735
{
 
736
  Player *player = Playerlist::getActiveplayer();
 
737
  return dumpActionsAndHistories(helper, player);
 
738
}
 
739
 
 
740
void GameServer::sit_down (Player *player)
 
741
{
 
742
  if (!player)
 
743
    return;
 
744
  if (player->getType() == Player::NETWORKED)
 
745
    {
 
746
      //alright, we want to sit down as this player
 
747
      //convert the network player to a human player
 
748
      dynamic_cast<NetworkPlayer*>(player)->setConnected(true);
 
749
      RealPlayer *new_p = new RealPlayer (*player);
 
750
      Playerlist::getInstance()->swap(player, new_p);
 
751
      stopListeningForLocalEvents(player);
 
752
      listenForLocalEvents(new_p);
 
753
      delete player;
 
754
      add_to_player_list (players_seated_locally, new_p->getId());
 
755
      notifySit(new_p, d_nickname);
 
756
    }
 
757
  else if (player->getType() == Player::HUMAN)
 
758
    {
 
759
      // do nothing
 
760
    }
 
761
  else // an ai player
 
762
    {
 
763
      stopListeningForLocalEvents(player);
 
764
      listenForLocalEvents(player);
 
765
      add_to_player_list (players_seated_locally, player->getId());
 
766
      notifySit(player, d_nickname);
 
767
    }
 
768
}
 
769
 
 
770
void GameServer::stand_up (Player *player)
 
771
{
 
772
  if (!player)
 
773
    return;
 
774
  if (player->getType() == Player::HUMAN)
 
775
    {
 
776
      //alright, we want to stand up as this player
 
777
      //convert the player from a human player back to a network player
 
778
 
 
779
      NetworkPlayer *new_p = new NetworkPlayer(*player);
 
780
      Playerlist::getInstance()->swap(player, new_p);
 
781
      stopListeningForLocalEvents(player);
 
782
      delete player;
 
783
      new_p->setConnected(false);
 
784
      notifyStand(new_p, d_nickname);
 
785
      remove_from_player_list (players_seated_locally, new_p->getId());
 
786
    }
 
787
  else if (player->getType() == Player::NETWORKED)
 
788
    {
 
789
      // do nothing
 
790
    }
 
791
  else // an ai player
 
792
    {
 
793
      stopListeningForLocalEvents(player);
 
794
      remove_from_player_list (players_seated_locally, player->getId());
 
795
      notifyStand(player, d_nickname);
 
796
    }
 
797
}
 
798
 
 
799
void GameServer::chat (std::string message)
 
800
{
 
801
  notifyChat(d_nickname + ":" + message);
 
802
}
 
803
 
 
804
void GameServer::notifyChat(std::string message)
 
805
{
 
806
  gotChatMessage(d_nickname, message);
 
807
  for (std::list<Participant *>::iterator i = participants.begin(),
 
808
       end = participants.end(); i != end; ++i) 
 
809
    network_server->send((*i)->conn, MESSAGE_TYPE_CHATTED, message);
 
810
}
 
811
 
 
812
void GameServer::sendSeats(void *conn)
 
813
{
 
814
  Participant *part = findParticipantByConn(conn);
 
815
  if (!part)
 
816
    return;
 
817
  //send seatedness info for remote participants
 
818
 
 
819
  for (std::list<Participant *>::iterator i = participants.begin(),
 
820
       end = participants.end(); i != end; ++i) 
 
821
    {
 
822
      if ((*i)->conn == part->conn)
 
823
        continue;
 
824
 
 
825
      for (std::list<Uint32>::iterator j = (*i)->players.begin(); 
 
826
           j != (*i)->players.end(); j++)
 
827
        {
 
828
          Player *player = Playerlist::getInstance()->getPlayer(*j);
 
829
          MessageType type;
 
830
          switch (player->getId())
 
831
            {
 
832
            case 0: type = MESSAGE_TYPE_P1_SAT_DOWN; break;
 
833
            case 1: type = MESSAGE_TYPE_P2_SAT_DOWN; break;
 
834
            case 2: type = MESSAGE_TYPE_P3_SAT_DOWN; break;
 
835
            case 3: type = MESSAGE_TYPE_P4_SAT_DOWN; break;
 
836
            case 4: type = MESSAGE_TYPE_P5_SAT_DOWN; break;
 
837
            case 5: type = MESSAGE_TYPE_P6_SAT_DOWN; break;
 
838
            case 6: type = MESSAGE_TYPE_P7_SAT_DOWN; break;
 
839
            case 7: type = MESSAGE_TYPE_P8_SAT_DOWN; break;
 
840
            default:
 
841
                    return;
 
842
            }
 
843
          network_server->send(part->conn, type, (*i)->nickname);
 
844
        }
 
845
    }
 
846
  //send out seatedness info for local server
 
847
  for (std::list<Uint32>::iterator j = players_seated_locally.begin(); 
 
848
       j != players_seated_locally.end(); j++)
 
849
    {
 
850
      Player *player = Playerlist::getInstance()->getPlayer(*j);
 
851
      MessageType type;
 
852
      switch (player->getId())
 
853
        {
 
854
        case 0: type = MESSAGE_TYPE_P1_SAT_DOWN; break;
 
855
        case 1: type = MESSAGE_TYPE_P2_SAT_DOWN; break;
 
856
        case 2: type = MESSAGE_TYPE_P3_SAT_DOWN; break;
 
857
        case 3: type = MESSAGE_TYPE_P4_SAT_DOWN; break;
 
858
        case 4: type = MESSAGE_TYPE_P5_SAT_DOWN; break;
 
859
        case 5: type = MESSAGE_TYPE_P6_SAT_DOWN; break;
 
860
        case 6: type = MESSAGE_TYPE_P7_SAT_DOWN; break;
 
861
        case 7: type = MESSAGE_TYPE_P8_SAT_DOWN; break;
 
862
        default:
 
863
                return;
 
864
        }
 
865
      network_server->send(part->conn, type, d_nickname);
 
866
    }
 
867
}
 
868
 
 
869
void GameServer::sendChatRoster(void *conn)
 
870
{
 
871
  Participant *part = findParticipantByConn(conn);
 
872
  if (!part)
 
873
    return;
 
874
  for (std::list<Participant *>::iterator i = participants.begin(),
 
875
       end = participants.end(); i != end; ++i) 
 
876
    {
 
877
      if ((*i)->conn == part->conn)
 
878
        continue;
 
879
      network_server->send(part->conn, MESSAGE_TYPE_PARTICIPANT_CONNECTED, 
 
880
                           (*i)->nickname);
 
881
    }
 
882
  network_server->send(part->conn, MESSAGE_TYPE_PARTICIPANT_CONNECTED, 
 
883
                       d_nickname);
 
884
}
 
885
 
 
886
void GameServer::sendKillPlayer(Player *p)
 
887
{
 
888
  std::stringstream player;
 
889
  player << p->getId();
 
890
  for (std::list<Participant *>::iterator i = participants.begin(),
 
891
       end = participants.end(); i != end; ++i) 
 
892
    network_server->send((*i)->conn, MESSAGE_TYPE_KILL_PLAYER, player.str());
 
893
 
 
894
  remote_player_died.emit(p);
 
895
}
 
896
 
 
897
void GameServer::sendTurnOrder()
 
898
{
 
899
  std::stringstream players;
 
900
  Playerlist *pl = Playerlist::getInstance();
 
901
  for (Playerlist::iterator it = pl->begin(); it != pl->end(); it++)
 
902
    players << (*it)->getId() << " ";
 
903
  for (std::list<Participant *>::iterator i = participants.begin(),
 
904
       end = participants.end(); i != end; ++i) 
 
905
    network_server->send((*i)->conn, MESSAGE_TYPE_TURN_ORDER, players.str());
 
906
  playerlist_reorder_received.emit();
 
907
}
252
908
 
253
909
// End of file