game_server.cpp 11.2 KB
Newer Older
louiz’'s avatar
louiz’ committed
1
#include <game/game_server.hpp>
louiz’'s avatar
louiz’ committed
2
#include <game/turn.hpp>
louiz’'s avatar
louiz’ committed
3
4
#include <algorithm>

louiz’'s avatar
louiz’ committed
5
6
7
8
#include <world/world_callbacks.hpp>
#include <world/entity.hpp>
#include <world/team.hpp>

louiz’'s avatar
louiz’ committed
9
10
11
12
#include "game.pb.h"
#include "orders.pb.h"
#include "requests.pb.h"

louiz’'s avatar
louiz’ committed
13
14
namespace ph = std::placeholders;

louiz’'s avatar
louiz’ committed
15
16
GameServer::GameServer(short port):
  Game(),
louiz’'s avatar
louiz’ committed
17
  Server<RemoteGameClient>(port),
louiz’'s avatar
louiz’ committed
18
  replay()
louiz’'s avatar
louiz’ committed
19
{
louiz’'s avatar
louiz’ committed
20
  this->turn_handler.set_next_turn_callback(std::bind(&GameServer::on_next_turn, this,
louiz’'s avatar
louiz’ committed
21
22
23
24
                                                      ph::_1));

  this->world.callbacks->entity_created = std::bind(&GameServer::on_entity_created, this, ph::_1);

louiz’'s avatar
louiz’ committed
25
  this->start_game();
louiz’'s avatar
louiz’ committed
26
27
28
29
30
31
}

GameServer::~GameServer()
{
}

louiz’'s avatar
louiz’ committed
32
33
34
35
36
37
38
39
40
41
42
43
void GameServer::on_entity_created(const Entity* entity)
{
  Team* team = entity->get<Team>();
  if (team && entity->get_type() == 0)
    {
      if (team->get() == 1)
        this->send_cast_order({entity->get_id()}, {3000, 1000}, 0, false);
      else
        this->send_cast_order({entity->get_id()}, {500, 1000}, 0, false);
    }
}

louiz’'s avatar
louiz’ committed
44
45
46
47
48
49
50
51
void GameServer::on_new_client(RemoteGameClient* new_client)
{
  // Give a pointer to ourself (the server) to this new client, so that it
  // can communicate with us later
  new_client->set_game_server(this);

  // First send the new player to all connected clients.
  // (including the just-new-connected one)
louiz’'s avatar
louiz’ committed
52
53
  Message* message = new Message();
  message->set_name("NEW_OCCUPANT");
louiz’'s avatar
louiz’ committed
54

louiz’'s avatar
louiz’ committed
55
  auto new_occupant = std::make_unique<Occupant>(new_client->get_id(), "coucou");
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

  // Get the first team not already taken by an other occupant
  uint16_t team;
  for (team = 1;; team++)
    {
      bool res = std::none_of(this->occupants_handler.begin(),
                              this->occupants_handler.end(),
                              [team](const auto& occupant)
                              {
                                return occupant->get_team() == team;
                              });
      if (res)
        break;
    }
  new_occupant->set_team(team);

louiz’'s avatar
louiz’ committed
72
73
  message->set_body(new_occupant->serialize());
  this->send_to_all_clients(message);
louiz’'s avatar
louiz’ committed
74

louiz’'s avatar
louiz’ committed
75
76
  this->occupants_handler.add(std::move(new_occupant));
  log_debug("There are now " << this->occupants_handler.size() << " occupants");
louiz’'s avatar
louiz’ committed
77
78
79

  // Then send the list of already-connected clients to the new
  // one.
louiz’'s avatar
louiz’ committed
80
  for (const auto& occupant: this->occupants_handler)
louiz’'s avatar
louiz’ committed
81
    {
louiz’'s avatar
louiz’ committed
82
      if (occupant->id != new_client->get_id())
louiz’'s avatar
louiz’ committed
83
84
     { // Do not send the information about itself, it
       // already just received that.
louiz’'s avatar
louiz’ committed
85
86
87
88
       message = new Message();
       message->set_name("NEW_OCCUPANT");
       message->set_body(occupant->serialize());
       new_client->send(message);
louiz’'s avatar
louiz’ committed
89
90
     }
    }
91
  this->send_seed_value(new_client);
louiz’'s avatar
louiz’ committed
92
93
94
95
  // Send the replay to the new client.
  this->send_replay(new_client);
  // Send an action to indicate at what turn the replay ends
  // and where the game currently is.
louiz’'s avatar
louiz’ committed
96
97
98
  this->send_start_message(new_client);
  // Send the futur actions to the new client
  this->send_future_actions(new_client);
louiz’'s avatar
louiz’ committed
99
100
101
102
}

void GameServer::send_replay(RemoteGameClient* new_client)
{
louiz’'s avatar
louiz’ committed
103
104
  for (const auto& order: this->replay.get_orders())
    new_client->send(new Message(order));
louiz’'s avatar
louiz’ committed
105
106
}

louiz’'s avatar
louiz’ committed
107
void GameServer::send_future_actions(RemoteGameClient* new_client)
louiz’'s avatar
louiz’ committed
108
{
louiz’'s avatar
louiz’ committed
109
110
111
112
113
  // Turn* turn;
  // Action* action;
  // Message* message;
  // ActionEvent* event;
  // std::size_t occupants_handler = this->occupants_handler.size();
louiz’'s avatar
louiz’ committed
114

louiz’'s avatar
louiz’ committed
115
116
117
118
119
120
121
122
123
124
125
  // for (const auto& turn: this->turn_handler.get_turns())
  //   {
  //     for (const auto& action: turn.get_actions())
  //       {
  //         event = action->get_event();
  //         message = new Message;
  //         message->set_name(event->name);
  //         message->set_body(event->to_string().c_str());
  //         new_client->send(message);
  //       }
  //   }
louiz’'s avatar
louiz’ committed
126
127
}

louiz’'s avatar
louiz’ committed
128
void GameServer::send_start_message(RemoteGameClient* client)
louiz’'s avatar
louiz’ committed
129
{
louiz’'s avatar
louiz’ committed
130
131
132
133
134
135
  Message* message = new Message;
  ser::order::Start start_msg;
  start_msg.set_turn(this->turn_handler.get_current_turn());
  message->set_name("START");
  message->set_body(start_msg);
  client->send(message);
louiz’'s avatar
louiz’ committed
136
137
138
139
}

void GameServer::on_client_left(RemoteGameClient* client)
{
louiz’'s avatar
louiz’ committed
140
  const auto it = std::remove_if(this->occupants_handler.begin(), this->occupants_handler.end(),
louiz’'s avatar
louiz’ committed
141
142
                           [client](const auto& occupant)
                                 {
louiz’'s avatar
louiz’ committed
143
                                   return occupant->id == client->get_id();
louiz’'s avatar
louiz’ committed
144
                                 });
louiz’'s avatar
louiz’ committed
145
  std::for_each(it, this->occupants_handler.end(),
louiz’'s avatar
louiz’ committed
146
147
               [this](const auto& occupant)
               {
louiz’'s avatar
louiz’ committed
148
149
150
151
                 Message* message = new Message;
                 message->set_name("OCCUPANT_LEFT");
                 message->set_body(occupant->serialize());
                 this->send_to_all_clients(message);
louiz’'s avatar
louiz’ committed
152
               });
louiz’'s avatar
louiz’ committed
153
  this->occupants_handler.erase(it, this->occupants_handler.end());
louiz’'s avatar
louiz’ committed
154
155
156
157
}

void GameServer::tick()
{
louiz’'s avatar
louiz’ committed
158
159
160
  this->turn_handler.tick();
  if (this->turn_handler.is_paused())
    return;
louiz’'s avatar
louiz’ committed
161
162
163
  this->world.tick();
}

louiz’'s avatar
louiz’ committed
164
165
166
167
168
169
170
171
172
// void GameServer::pause_game()
// {
//   this->started = false;
// }

// void GameServer::unpause_game()
// {
//   this->started = true;
// }
louiz’'s avatar
louiz’ committed
173

174
175
176
177
178
void GameServer::seed_world()
{
  this->world.seed();
}

louiz’'s avatar
louiz’ committed
179
void GameServer::start_game()
louiz’'s avatar
louiz’ committed
180
{
181
  this->seed_world();
louiz’'s avatar
louiz’ committed
182
183
184

  this->spawn_waves();

louiz’'s avatar
louiz’ committed
185
  this->turn_handler.mark_turn_as_ready();
louiz’'s avatar
louiz’ committed
186
187
}

louiz’'s avatar
louiz’ committed
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
void GameServer::spawn_waves()
{
  this->send_new_entity_order(0, {500, 1000}, 1);
  this->send_new_entity_order(0, {500, 900}, 1);
  this->send_new_entity_order(0, {500, 800}, 1);
  this->send_new_entity_order(0, {400, 850}, 1);
  this->send_new_entity_order(0, {400, 950}, 1);

  this->send_new_entity_order(0, {2800, 1000}, 2);
  this->send_new_entity_order(0, {2800, 900}, 2);
  this->send_new_entity_order(0, {2800, 800}, 2);
  this->send_new_entity_order(0, {2900, 850}, 2);
  this->send_new_entity_order(0, {2900, 950}, 2);
}

louiz’'s avatar
louiz’ committed
203
void GameServer::on_next_turn(const TurnNb n)
louiz’'s avatar
louiz’ committed
204
{
louiz’'s avatar
louiz’ committed
205
206
  this->turn_handler.mark_turn_as_ready();
  this->send_message_to_all("T", {});
louiz’'s avatar
louiz’ committed
207
208
  if (n % 400 == 0)
    this->spawn_waves();
louiz’'s avatar
louiz’ committed
209
210
}

louiz’'s avatar
louiz’ committed
211
void GameServer::send_order_to_all(const char* name, const google::protobuf::Message& srl)
louiz’'s avatar
louiz’ committed
212
{
louiz’'s avatar
louiz’ committed
213
214
215
216
217
  Message* message = new Message;
  message->set_name(name);
  message->set_body(srl);
  this->replay.insert_order(*message);
  this->send_to_all_clients(message);
louiz’'s avatar
louiz’ committed
218
219
}

louiz’'s avatar
louiz’ committed
220
void GameServer::send_message_to_all(const char* name, const std::string& data)
louiz’'s avatar
louiz’ committed
221
{
louiz’'s avatar
louiz’ committed
222
223
224
225
  Message* message = new Message;
  message->set_name(name);
  message->set_body(data.data(), data.size());
  this->send_to_all_clients(message);
louiz’'s avatar
louiz’ committed
226
227
}

louiz’'s avatar
louiz’ committed
228
void GameServer::send_turn()
louiz’'s avatar
louiz’ committed
229
{
louiz’'s avatar
louiz’ committed
230
231
232
  Message* message = new Message;
  message->set_name("T");
  this->send_to_all_clients(message);
louiz’'s avatar
louiz’ committed
233
234
235
236
237
238
}

void GameServer::init()
{
}

louiz’'s avatar
louiz’ committed
239
void GameServer::on_move_request(Message* message)
louiz’'s avatar
louiz’ committed
240
{
louiz’'s avatar
louiz’ committed
241
242
243
244
  auto srl = message->parse_body_to_protobuf_object<ser::request::Move>();
  std::vector<EntityId> ids;
  for (const auto& id: srl.entity_id())
    ids.push_back(id);
245
246
247
248
249
250
251
252
253
  if (srl.has_pos())
    {
      Position pos;
      pos.x.raw() = srl.pos().x();
      pos.y.raw() = srl.pos().y();
      this->send_move_order(ids, pos, srl.queue());
    }
  else
    this->send_follow_order(ids, srl.target(), srl.queue());
louiz’'s avatar
louiz’ committed
254
255
}

louiz’'s avatar
louiz’ committed
256
257
258
259
260
261
262
263
264
265
266
267
268
void GameServer::on_cast_request(Message* message)
{
  auto srl = message->parse_body_to_protobuf_object<ser::request::Cast>();
  std::vector<EntityId> ids;
  for (const auto& id: srl.entity_id())
    ids.push_back(id);
  if (srl.has_pos())
    {
      Position pos;
      pos.x.raw() = srl.pos().x();
      pos.y.raw() = srl.pos().y();
      this->send_cast_order(ids, pos, srl.type(), srl.queue());
    }
269
270
  else if (srl.has_target())
    this->send_cast_order(ids, srl.target(), srl.type(), srl.queue());
271
272
  else
    this->send_cast_order(ids, srl.type(), srl.queue());
louiz’'s avatar
louiz’ committed
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
}

void GameServer::send_cast_order(const std::vector<EntityId>& ids, const Position& pos,
                                 const uint32_t type, const bool queue)
{
  ser::order::Cast srl;
  srl.set_turn(this->turn_handler.get_current_turn() + 2);
  if (queue)
    srl.set_queue(queue);
  for (const EntityId id: ids)
    srl.add_entity_id(id);
  srl.set_type(type);
  srl.mutable_pos()->set_x(pos.x.raw());
  srl.mutable_pos()->set_y(pos.y.raw());
  this->send_order_to_all("CAST", srl);
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
  this->turn_handler.insert_action(std::bind(&World::do_cast_on_pos, &this->world, ids, pos,
                                             static_cast<AbilityType>(type), queue),
                                   srl.turn());
}

void GameServer::send_cast_order(const std::vector<EntityId>& ids, const EntityId target_id,
                                 const uint32_t type, const bool queue)
{
  ser::order::Cast srl;
  srl.set_turn(this->turn_handler.get_current_turn() + 2);
  if (queue)
    srl.set_queue(queue);
  srl.set_target(target_id);
  for (const EntityId id: ids)
    srl.add_entity_id(id);
  srl.set_type(type);
  this->send_order_to_all("CAST", srl);
  this->turn_handler.insert_action(std::bind(&World::do_cast_on_target, &this->world, ids, target_id,
louiz’'s avatar
louiz’ committed
306
307
308
309
                                             static_cast<AbilityType>(type), queue),
                                   srl.turn());
}

310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
void GameServer::send_cast_order(const std::vector<EntityId>& ids,
                                 const uint32_t type, const bool queue)
{
  ser::order::Cast srl;
  srl.set_turn(this->turn_handler.get_current_turn() + 2);
  if (queue)
    srl.set_queue(queue);
  for (const EntityId id: ids)
    srl.add_entity_id(id);
  srl.set_type(type);
  this->send_order_to_all("CAST", srl);
  this->turn_handler.insert_action(std::bind(&World::do_cast, &this->world, ids,
                                             static_cast<AbilityType>(type), queue),
                                   srl.turn());
}

louiz’'s avatar
louiz’ committed
326
327
void GameServer::send_new_entity_order(const EntityType type, const Position& pos,
                                       const uint16_t team)
louiz’'s avatar
louiz’ committed
328
{
louiz’'s avatar
louiz’ committed
329
  ser::order::NewEntity srl;
louiz’'s avatar
louiz’ committed
330
331
332
333
  srl.set_turn(this->turn_handler.get_current_turn() + 2);
  srl.set_type_id(type);
  srl.mutable_pos()->set_x(pos.x.raw());
  srl.mutable_pos()->set_y(pos.y.raw());
334
  srl.set_team(team);
louiz’'s avatar
louiz’ committed
335
336
  this->send_order_to_all("NEW_ENTITY", srl);
  this->turn_handler.insert_action(std::bind(&World::do_new_entity, &this->world, type, pos, team),
louiz’'s avatar
louiz’ committed
337
338
339
                                   srl.turn());
}

340
341
342
343
344
345
346
347
348
349
void GameServer::send_seed_value(RemoteGameClient* client)
{
  ser::order::Seed srl;
  srl.set_value(this->world.get_seed());
  Message* message = new Message;
  message->set_name("SEED");
  message->set_body(srl);
  client->send(message);
}

louiz’'s avatar
louiz’ committed
350
351
352
353
354
355
356
357
358
359
360
361
void GameServer::send_move_order(const std::vector<EntityId> ids, const Position& pos, const bool queue)
{
  ser::order::Move srl;
  srl.set_turn(this->turn_handler.get_current_turn() + 2);
  for (const EntityId id: ids)
    srl.add_entity_id(id);
  srl.set_queue(queue);
  srl.mutable_pos()->set_x(pos.x.raw());
  srl.mutable_pos()->set_y(pos.y.raw());
  this->send_order_to_all("MOVE", srl);
  this->turn_handler.insert_action(std::bind(&World::do_move, &this->world, ids, pos, queue),
                                   srl.turn());
louiz’'s avatar
louiz’ committed
362
}
363
364
365
366
367
368
369
370
371
372
373
374
375

void GameServer::send_follow_order(const std::vector<EntityId> ids, const EntityId target, const bool queue)
{
  ser::order::Move srl;
  srl.set_turn(this->turn_handler.get_current_turn() + 2);
  for (const EntityId id: ids)
    srl.add_entity_id(id);
  srl.set_queue(queue);
  srl.set_target(target);
  this->send_order_to_all("MOVE", srl);
  this->turn_handler.insert_action(std::bind(&World::do_follow, &this->world, ids, target, queue),
                                   srl.turn());
}