Program Listing for File API.cpp

Return to documentation for file (gui/API/API.cpp)

#include <functional>
#include <iostream>
#include <sstream>

#include <sys/poll.h>
#include <unistd.h>

#include "API.hpp"
#include "API/TileMap/Tilemap.hpp"
#include "API/Trantor/Trantor.hpp"
#include "Utils/Utils.hpp"

API::API()
{
  // Initialize the pipe for network communication
  if (pipe(_pipeFdNetwork.data()) == -1)
    throw std::runtime_error(
      "Error: pipe failed, Function: API constructor, File: API.cpp");

  // Create pipe for events
  if (pipe(_pipeFdEvents.data()) == -1)
    throw std::runtime_error(
      "Error: pipe failed. Function: API constructor, File: API.cpp");

  // Initialize the poll structures
  _pollOutFd[0].fd = _pipeFdNetwork[1];
  _pollOutFd[0].events = POLLOUT;
  _pollOutFd[0].revents = 0;

  _pollEventOutFd[0].fd = _pipeFdEvents[1];
  _pollEventOutFd[0].events = POLLOUT;
  _pollEventOutFd[0].revents = 0;

  // Initialize the tilemap
  _tilemap = Tilemap();
}

void API::WriteMessage(const std::string &msg)
{
  if (poll(_pollOutFd.data(), _pollOutFd.size(), -1) == -1)
    throw std::runtime_error(
      "Error: poll failed, Function: WriteMessage, File: API.cpp");
  // No need to check for POLLOUT here, there is only one fd in _pollOutFd
  if (write(_pipeFdNetwork[1], msg.c_str(), msg.size()) == -1)
    throw std::runtime_error(
      "Error: write failed, Function: WriteMessage, File: API.cpp");
}

Tilemap API::GetTilemap()
{
  std::lock_guard<std::mutex> lock(_tilemapLocker);
  return _tilemap;
}

std::vector<std::string> API::GetTeamsName()
{
  std::lock_guard<std::mutex> locker(_allTeamNameLocker);
  return _allTeamName;
}

void API::AddEgg(int id, int x, int y)
{
  std::lock_guard<std::mutex> locker(_eggListLocker);
  _eggList[id].first = x;
  _eggList[id].second = y;
}

void API::DeleteEgg(int id)
{
  std::lock_guard<std::mutex> locker(_eggListLocker);
  _eggList.erase(id);
}

void API::AskMapSize()
{
  std::string tmp_command = "msz\n";

  std::lock_guard<std::mutex> lock(_commandListLocker);
  WriteMessage(tmp_command);
}

void API::AskAllTileContent()
{
  std::string tmp_command = "mct\n";

  std::lock_guard<std::mutex> lock(_commandListLocker);
  WriteMessage(tmp_command);
}

void API::AskTileContent(int x, int y)
{
  std::string tmp_command = "bct " + std::to_string(x) + " "
    + std::to_string(y) + "\n";

  std::lock_guard<std::mutex> lock(_commandListLocker);
  WriteMessage(tmp_command);
}

void API::AskAllTeamName()
{
  std::string tmp_command = "tna\n";

  std::lock_guard<std::mutex> lock(_commandListLocker);
  WriteMessage(tmp_command);
}

void API::AskAllPlayerPos()
{
  std::string tmp_command;

  std::lock_guard<std::mutex> lockerName(_allTeamNameLocker);
  for (const auto &teamName: _allTeamName) {
    std::lock_guard<std::mutex> lockerTeam(_teamsLocker);
    const auto &teamPlayers = _teams[teamName];
    for (const Trantor &trantor: teamPlayers) {
      std::lock_guard<std::mutex> lock(_commandListLocker);
      tmp_command = "ppo " + std::to_string(trantor.GetId()) + "\n";
      WriteMessage(tmp_command);
    }
  }
}

void API::AskPlayerPos(int id)
{
  std::string tmp_command = "ppo " + std::to_string(id) + "\n";

  std::lock_guard<std::mutex> lock(_commandListLocker);
  WriteMessage(tmp_command);
}

void API::AskAllPlayerLevel()
{
  std::string tmp_command;

  std::lock_guard<std::mutex> lock(_commandListLocker);
  std::lock_guard<std::mutex> lockerName(_allTeamNameLocker);
  for (const auto &teamName: _allTeamName) {
    std::lock_guard<std::mutex> lockerTeam(_teamsLocker);
    const auto &teamPlayers = _teams[teamName];
    for (const Trantor &trantor: teamPlayers) {
      tmp_command = "plv " + std::to_string(trantor.GetId()) + "\n";
      WriteMessage(tmp_command);
    }
  }
}

void API::AskPlayerLevel(int id)
{
  std::string tmp_command = "plv " + std::to_string(id) + "\n";

  std::lock_guard<std::mutex> lock(_commandListLocker);
  WriteMessage(tmp_command);
}

void API::AskAllPlayerInventory()
{
  std::string tmp_command;

  std::lock_guard<std::mutex> lockerName(_allTeamNameLocker);
  for (const auto &teamName: _allTeamName) {
    std::lock_guard<std::mutex> lock(_commandListLocker);
    std::lock_guard<std::mutex> lockerTeam(_teamsLocker);
    const auto &teamPlayers = _teams[teamName];
    for (const Trantor &trantor: teamPlayers) {
      tmp_command = "pin " + std::to_string(trantor.GetId()) + "\n";
      WriteMessage(tmp_command);
    }
  }
}

void API::AskPlayerInventory(int id)
{
  std::string tmp_command = "pin " + std::to_string(id) + "\n";

  std::lock_guard<std::mutex> lock(_commandListLocker);
  WriteMessage(tmp_command);
}

void API::ParseManageCommand(std::string &command)
{
  if (command.empty())
    return;

  static const std::map<std::string, std::function<void(std::stringstream &)>>
    commandHandlers = {
      {"msz", [this](std::stringstream &ss) { HandleMSZ(ss); }},
      {"bct", [this](std::stringstream &ss) { HandleBCT(ss); }},
      {"mct",
       [](std::stringstream &ss) {
         (void)ss;
         API::HandleMCT();
       }},
      {"tna", [this](std::stringstream &ss) { HandleTNA(ss); }},
      {"pnw", [this](std::stringstream &ss) { HandlePNW(ss); }},
      {"ppo", [this](std::stringstream &ss) { HandlePPO(ss); }},
      {"plv", [this](std::stringstream &ss) { HandlePLV(ss); }},
      {"pin", [this](std::stringstream &ss) { HandlePIN(ss); }},
      {"pex", [this](std::stringstream &ss) { HandlePEX(ss); }},
      {"pbc", [this](std::stringstream &ss) { HandlePBC(ss); }},
      {"pic", [this](std::stringstream &ss) { HandlePIC(ss); }},
      {"pie", [this](std::stringstream &ss) { HandlePIE(ss); }},
      {"pfk", [this](std::stringstream &ss) { HandlePFK(ss); }},
      {"pdr", [this](std::stringstream &ss) { HandlePDR(ss); }},
      {"pgt", [this](std::stringstream &ss) { HandlePGT(ss); }},
      {"pdi", [this](std::stringstream &ss) { HandlePDI(ss); }},
      {"enw", [this](std::stringstream &ss) { HandleENW(ss); }},
      {"ebo", [this](std::stringstream &ss) { HandleEBO(ss); }},
      {"edi", [this](std::stringstream &ss) { HandleEDI(ss); }},
      {"sgt", [this](std::stringstream &ss) { HandleSGT(ss); }},
      {"sst", [this](std::stringstream &ss) { HandleSST(ss); }},
      {"seg", [this](std::stringstream &ss) { HandleSEG(ss); }},
      {"smg", [this](std::stringstream &ss) { HandleSMG(ss); }},
      {"suc",
       [](std::stringstream &ss) {
         (void)ss;
         API::HandleSUC();
       }},
      {"sbp", [](std::stringstream &ss) {
         (void)ss;
         API::HandleSBP();
       }}};

  std::istringstream stream(command);
  std::string line;

  while (std::getline(stream, line)) {
    line += "\n";
    if (poll(_pollEventOutFd.data(), _pollEventOutFd.size(), 0) == -1)
      throw std::runtime_error(
        "Error: poll failed, Function: ParseManageCommand, File: API.cpp");
    if (_pollEventOutFd[0].revents & POLLOUT)
      if (write(_pipeFdEvents[1], line.c_str(), line.size()) == -1)
        throw std::runtime_error(
          "Error: write failed, Function: ParseManageCommand, File: API.cpp");

    std::stringstream lineParsed(line);
    std::string word;
    lineParsed >> word;

    if (word == "WELCOME")
      continue;

    auto it = commandHandlers.find(word);
    if (it != commandHandlers.end()) {
      it->second(lineParsed);
    } else {
      throw std::runtime_error(
        "Error: unknown cmd, Function: ParseManageCommande, File: API.cpp");
    }
  }
}

void API::HandleMSZ(std::stringstream &ss)
{
  int x;
  int y;

  if (!(ss >> x >> y))
    throw std::runtime_error(
      "Error: invalid msz params, Function: HandleMSZ, File: API.cpp");
  // std::cout << "map size: x=" << x << " y=" << y << "\n";
  std::lock_guard<std::mutex> locker(_tilemapLocker);
  _tilemap.SetSize(x, y);
}

void API::HandleBCT(std::stringstream &ss)
{
  int x;
  int y;
  int q0;
  int q1;
  int q2;
  int q3;
  int q4;
  int q5;
  int q6;

  if (!(ss >> x >> y >> q0 >> q1 >> q2 >> q3 >> q4 >> q5 >> q6))
    throw std::runtime_error(
      "Error: invalid bct params, Function: HandleBCT, File: API.cpp");
  // //std::cout
  //   << "tile (" << x << "," << y << ") resources: " << q0 << "," << q1 <<
  //   ","
  //   << q2 << "," << q3 << "," << q4 << "," << q5 << "," << q6 << "\n";
  std::lock_guard<std::mutex> locker(_tilemapLocker);
  _tilemap.SetTileInventory(x, y, q0, q1, q2, q3, q4, q5, q6);
}

void API::HandleMCT()
{
  // std::cout << "map content (bct *): Handled line-by-line\n";
}

void API::HandleTNA(std::stringstream &ss)
{
  std::string N;
  std::vector<Trantor> teamTmp;

  if (!(ss >> N))
    throw std::runtime_error(
      "Error: invalid tna params, Function: HandleTNA, File: API.cpp");
  // std::cout << "team name: " << N << "\n";
  std::lock_guard<std::mutex> lockerTeam(_teamsLocker);
  if (_teams.contains(N))
    return;
  _teams[N] = teamTmp;
  std::lock_guard<std::mutex> lockerName(_allTeamNameLocker);
  for (std::string &teamName: _allTeamName)
    if (teamName == N)
      return;
  _allTeamName.push_back(N);
}

void API::HandlePNW(std::stringstream &ss)
{
  std::string nTmp;
  int X;
  int Y;
  int O;
  int L;
  std::string N;

  if (!(ss >> nTmp >> X >> Y >> O >> L >> N))
    throw std::runtime_error(
      "Error: invalid pnw params, Function: HandlePNW, File: API.cpp");

  if (nTmp[0] == '#')
    nTmp.erase(0, 1);
  std::cout
    << "new player: #" << std::stoi(nTmp) << " (" << X << "," << Y
    << ") facing " << O << " level " << L << " team " << N << "\n";
  Trantor trantorTmp(std::stoi(nTmp), X, Y, O, L);
  std::lock_guard<std::mutex> lockerName(_allTeamNameLocker);
  std::lock_guard<std::mutex> lockerTeam(_teamsLocker);
  _teams[N].push_back(trantorTmp);
}

void API::HandlePPO(std::stringstream &ss)
{
  std::string nTmp;
  int X;
  int Y;
  int O;

  if (!(ss >> nTmp >> X >> Y >> O))
    throw std::runtime_error(
      "Error: invalid ppo params, Function: HandlePPO, File: API.cpp");

  if (nTmp[0] == '#')
    nTmp.erase(0, 1);
  // std::cout
  //   << "player #" << std::stoi(nTmp) << " position: (" << X << "," << Y
  //   << ") facing " << O << "\n";
  std::lock_guard<std::mutex> lockerName(_allTeamNameLocker);
  std::lock_guard<std::mutex> lockerTeam(_teamsLocker);
  for (std::string &teamNameTmp: _allTeamName)
    for (Trantor &trantorTmp: _teams[teamNameTmp])
      if (trantorTmp.GetId() == std::stoi(nTmp))
        trantorTmp.SetPosition(X, Y, O);
}

void API::HandlePLV(std::stringstream &ss)
{
  std::string nTmp;
  int L;

  if (!(ss >> nTmp >> L))
    throw std::runtime_error(
      "Error: invalid plv params, Function: HandlePLV, File: API.cpp");

  if (nTmp[0] == '#')
    nTmp.erase(0, 1);
  // std::cout << "player #" << std::stoi(nTmp) << " level: " << L << "\n";
  std::lock_guard<std::mutex> lockerName(_allTeamNameLocker);
  std::lock_guard<std::mutex> lockerTeam(_teamsLocker);
  for (std::string &teamNameTmp: _allTeamName)
    for (Trantor &trantorTmp: _teams[teamNameTmp])
      if (trantorTmp.GetId() == std::stoi(nTmp))
        trantorTmp.SetLevel(L);
}

void API::HandlePIN(std::stringstream &ss)
{
  std::string nTmp;
  int x;
  int y;
  int q0;
  int q1;
  int q2;
  int q3;
  int q4;
  int q5;
  int q6;

  if (!(ss >> nTmp >> x >> y >> q0 >> q1 >> q2 >> q3 >> q4 >> q5 >> q6))
    throw std::runtime_error(
      "Error: invalid pin params, Function: HandlePIN, File: API.cpp");

  if (nTmp[0] == '#')
    nTmp.erase(0, 1);
  // std::cout
  //   << "player #" << std::stoi(nTmp) << " inventory at (" << x << "," << y
  //   << "): " << q0 << "," << q1 << "," << q2 << "," << q3 << "," << q4 <<
  //   ","
  //   << q5 << "," << q6 << "\n";
  std::lock_guard<std::mutex> lockerName(_allTeamNameLocker);
  std::lock_guard<std::mutex> lockerTeam(_teamsLocker);
  for (std::string &teamNameTmp: _allTeamName)
    for (Trantor &trantorTmp: _teams[teamNameTmp])
      if (trantorTmp.GetId() == std::stoi(nTmp)) {
        trantorTmp.SetPosition(x, y);
        trantorTmp.SetInventory(q0, q1, q2, q3, q4, q5, q6);
      }
}

void API::HandlePEX(std::stringstream &ss)
{
  std::string nTmp;
  int posX = -1;
  int posY = -1;
  int rotation = -1;
  int id = -1;

  if (!(ss >> nTmp))
    throw std::runtime_error(
      "Error: invalid pex params, Function: HandlePEX, File: API.cpp");

  if (nTmp[0] == '#')
    nTmp.erase(0, 1);
  // std::cout << "expulsion by player #" << std::stoi(nTmp) << "\n";
  std::lock_guard<std::mutex> lockerName(_allTeamNameLocker);
  std::lock_guard<std::mutex> lockerTeam(_teamsLocker);
  for (std::string &teamNameTmp: _allTeamName) {
    auto &team = _teams[teamNameTmp];
    for (auto it = team.begin(); it != team.end(); ++it)
      if (it->GetId() == std::stoi(nTmp)) {
        id = it->GetId();
        posX = it->GetPosition().first;
        posY = it->GetPosition().second;
        rotation = it->GetRotation();
        team.erase(it);
        break;
      }
  }
  for (std::string &teamNameTmp: _allTeamName) {
    auto &team = _teams[teamNameTmp];
    for (auto &it: team)
      if (it.GetPosition().first == posX && it.GetPosition().second == posY
          && it.GetId() != id)
        switch (rotation) {
          case 0:
            it.AddPosition(0, -1);
            break;
          case 1:
            it.AddPosition(1, -1);
            break;
          case 2:
            it.AddPosition(1, 0);
            break;
          case 3:
            it.AddPosition(1, 1);
            break;
          case 4:
            it.AddPosition(0, 1);
            break;
          case 5:
            it.AddPosition(-1, 1);
            break;
          case 6:
            it.AddPosition(-1, 0);
            break;
          case 7:
            it.AddPosition(-1, -1);
            break;
          default:
            return;
        }
  }
}

void API::HandlePBC(std::stringstream &ss)
{
  std::string nTmp;
  std::string msg;

  if (!(ss >> nTmp))
    throw std::runtime_error(
      "Error: invalid pbc params (missing id), Function: HandlePBC, File: "
      "API.cpp");

  std::getline(ss >> std::ws, msg);
  if (msg.empty())
    throw std::runtime_error(
      "Error: missing message in pbc, Function: HandlePBC, File: API.cpp");

  if (nTmp[0] == '#')
    nTmp.erase(0, 1);
  // std::cout << "broadcast from #" << std::stoi(nTmp) << ": " << msg << "\n";
  std::lock_guard<std::mutex> lockerName(_allTeamNameLocker);
  std::lock_guard<std::mutex> lockerTeam(_teamsLocker);
  for (std::string &teamNameTmp: _allTeamName)
    for (Trantor &trantorTmp: _teams[teamNameTmp])
      if (trantorTmp.GetId() == std::stoi(nTmp))
        trantorTmp.SetBroadcast(msg);
}

void API::HandlePIC(std::stringstream &ss)
{
  int X;
  int Y;
  int L;

  if (!(ss >> X >> Y >> L))
    throw std::runtime_error(
      "Error: invalid pic params, Function: HandlePIC, File: API.cpp");
  // std::cout
  //   << "start incantation at (" << X << "," << Y << ") level " << L
  //   << " by players:";

  Incantation tmp(L, X, Y);
  std::vector<std::string> nList;
  std::string tmpStr;
  while (ss >> tmpStr) {
    if (tmpStr[0] == '#')
      tmpStr.erase(0, 1);
    tmp.AddMember(std::stoi(tmpStr));
    nList.push_back(tmpStr);
  }
  {
    std::lock_guard<std::mutex> locker(_incantationListLocker);
    _incantationList.push_back(tmp);
  }
  // std::cout << "\n";
}

void API::HandlePIE(std::stringstream &ss)
{
  int X;
  int Y;
  std::string R;

  if (!(ss >> X >> Y >> R))
    throw std::runtime_error(
      "Error: invalid pie params, Function: HandlePIE, File: API.cpp");
  // std::cout
  //   << "end incantation at (" << X << "," << Y << "): result = " << R <<
  //   "\n";
  std::lock_guard<std::mutex> locker(_incantationListLocker);
  for (auto &incant: _incantationList)
    if (incant.GetPosition().first == X && incant.GetPosition().second == Y)
      incant.SetState(R);
}

void API::HandlePFK(std::stringstream &ss)
{
  std::string nTmp;

  if (!(ss >> nTmp))
    throw std::runtime_error(
      "Error: invalid pfk params, Function: HandlePFK, File: API.cpp");

  if (nTmp[0] == '#')
    nTmp.erase(0, 1);
  // std::cout << "egg laiying by player #" << std::stoi(nTmp) << "\n";
  std::lock_guard<std::mutex> lockerName(_allTeamNameLocker);
  std::lock_guard<std::mutex> lockerTeam(_teamsLocker);
  for (std::string &teamNameTmp: _allTeamName)
    for (Trantor &trantorTmp: _teams[teamNameTmp])
      if (trantorTmp.GetId() == std::stoi(nTmp))
        trantorTmp.IsTrantorLaying(true);
}

void API::HandlePDR(std::stringstream &ss)
{
  std::string nTmp;
  int i;

  if (!(ss >> nTmp >> i))
    throw std::runtime_error(
      "Error: invalid pdr params, Function: HandlePDR, File: API.cpp");

  if (nTmp[0] == '#')
    nTmp.erase(0, 1);
  // std::cout
  //   << "player #" << std::stoi(nTmp) << " dropped resource " << i << "\n";
  std::lock_guard<std::mutex> lockerName(_allTeamNameLocker);
  std::lock_guard<std::mutex> lockerTeam(_teamsLocker);
  for (std::string &teamNameTmp: _allTeamName)
    for (Trantor &trantorTmp: _teams[teamNameTmp])
      if (trantorTmp.GetId() == std::stoi(nTmp)) {
        trantorTmp.AddToInventory(static_cast<Item>(i), -1);
        std::lock_guard<std::mutex> locker(_tilemapLocker);
        _tilemap.AddToInventory(
          trantorTmp.GetPosition().first,
          trantorTmp.GetPosition().second,
          static_cast<Item>(i),
          1);
      }
}

void API::HandlePGT(std::stringstream &ss)
{
  std::string nTmp;
  int i;

  if (!(ss >> nTmp >> i))
    throw std::runtime_error(
      "Error: invalid pgt params, Function: HandlePGT, File: API.cpp");

  if (nTmp[0] == '#')
    nTmp.erase(0, 1);
  // std::cout
  //   << "player #" << std::stoi(nTmp) << " collected resource " << i << "\n";
  std::lock_guard<std::mutex> lockerName(_allTeamNameLocker);
  std::lock_guard<std::mutex> lockerTeam(_teamsLocker);
  for (std::string &teamNameTmp: _allTeamName)
    for (Trantor &trantorTmp: _teams[teamNameTmp])
      if (trantorTmp.GetId() == std::stoi(nTmp)) {
        trantorTmp.AddToInventory(static_cast<Item>(i), 1);
        std::lock_guard<std::mutex> locker(_tilemapLocker);
        _tilemap.AddToInventory(
          trantorTmp.GetPosition().first,
          trantorTmp.GetPosition().second,
          static_cast<Item>(i),
          -1);
      }
}

void API::HandlePDI(std::stringstream &ss)
{
  std::string nTmp;

  if (!(ss >> nTmp))
    throw std::runtime_error(
      "Error: invalid pdi params, Function: HandlePDI, File: API.cpp");

  if (nTmp[0] == '#')
    nTmp.erase(0, 1);
  // std::cout << "player #" << std::stoi(nTmp) << " died\n";
  std::lock_guard<std::mutex> lockerName(_allTeamNameLocker);
  std::lock_guard<std::mutex> lockerTeam(_teamsLocker);
  for (std::string &teamNameTmp: _allTeamName)
    for (size_t i = 0; i < _teams[teamNameTmp].size(); i++)
      if (_teams[teamNameTmp][i].GetId() == std::stoi(nTmp))
        _teams[teamNameTmp].erase(_teams[teamNameTmp].begin() + i);
}

void API::HandleENW(std::stringstream &ss)
{
  std::string eTmp;
  std::string nTmp;
  int X;
  int Y;

  if (!(ss >> eTmp >> nTmp >> X >> Y))
    throw std::runtime_error(
      "Error: invalid enw params, Function: HandleENW, File: API.cpp");

  if (eTmp[0] == '#')
    eTmp.erase(0, 1);
  if (nTmp[0] == '#')
    nTmp.erase(0, 1);
  // std::cout
  //   << "egg #" << std::stoi(eTmp) << " laid by player #" << std::stoi(nTmp)
  //   << " at (" << X << "," << Y << ")\n";
  std::lock_guard<std::mutex> lockerName(_allTeamNameLocker);
  std::lock_guard<std::mutex> lockerTeam(_teamsLocker);
  for (std::string &teamNameTmp: _allTeamName)
    for (Trantor &trantorTmp: _teams[teamNameTmp])
      if (trantorTmp.GetId() == std::stoi(nTmp))
        AddEgg(std::stoi(eTmp), X, Y);
}

void API::HandleEBO(std::stringstream &ss)
{
  std::string eTmp;

  if (!(ss >> eTmp))
    throw std::runtime_error(
      "Error: invalid ebo params, Function: HandleEBO, File: API.cpp");

  if (eTmp[0] == '#')
    eTmp.erase(0, 1);
  std::cout << "egg #" << eTmp << " connection\n";
  DeleteEgg(std::stoi(eTmp));
}

void API::HandleEDI(std::stringstream &ss)
{
  std::string eTmp;

  if (!(ss >> eTmp))
    throw std::runtime_error(
      "Error: invalid edi params, Function: HandleEDI, File: API.cpp");

  if (eTmp[0] == '#')
    eTmp.erase(0, 1);
  // std::cout << "egg #" << eTmp << " died\n";
  DeleteEgg(std::stoi(eTmp));
}

void API::HandleSGT(std::stringstream &ss)
{
  int T;

  if (!(ss >> T))
    throw std::runtime_error(
      "Error: invalid sgt params, Function: HandleSGT, File: API.cpp");
  // std::cout << "server time unit: " << T << "\n";
  std::lock_guard<std::mutex> locker(_timeUnitLocker);
  _timeUnit = T;
}

void API::HandleSST(std::stringstream &ss)
{
  short T;

  if (!(ss >> T))
    throw std::runtime_error(
      "Error: invalid sst params, Function: HandleSST, File: API.cpp");
  // std::cout << "server time unit changed to: " << T << "\n";
  std::lock_guard<std::mutex> locker(_timeUnitLocker);
  _timeUnit = T;
}

void API::HandleSEG(std::stringstream &ss)
{
  std::string N;

  if (!(ss >> N))
    throw std::runtime_error(
      "Error: invalid seg params, Function: HandleSEG, File: API.cpp");
  // std::cout << "end of game, winning team: " << N << "\n";
  std::lock_guard<std::mutex> locker(_winnerLocker);
  _winner = N;
}

void API::HandleSMG(std::stringstream &ss)
{
  std::string msg;

  std::getline(ss >> std::ws, msg);
  if (msg.empty())
    throw std::runtime_error(
      "Error: missing message in smg, Function: HandleSMG, File: API.cpp");
  // std::cout << "server message: " << msg << "\n";
  std::lock_guard<std::mutex> locker(_serverMessageLocker);
  _serverMessage.push_back(msg);
}

void API::HandleSUC()
{
  // std::cout << "unknown command\n";
}

void API::HandleSBP()
{
  // std::cout << "bad command parameter\n";
}