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());
}