Exemple #1
0
// TODO: On signal event: close active connections, save world (when implemented), etc.
void SignalHandler(int sig)
{
  switch(sig)
  {
    case SIGHUP:
      signal(sig, SIG_IGN);
      /* TODO: Rehash a config? hmmnn */
      std::cout << "SIGHUP caught, ignoring.." << std::endl;
      break;
#ifdef HAVE_BACKTRACE
    case SIGSEGV: // Justasic: You can stop SIGSEGV's but i HIGHLY recommend against it unless you have good reason to.
      HandleSegfault();
      break;
#endif
    case SIGINT:
    case SIGKILL:
    case SIGTERM:
      signal(sig, SIG_IGN);
      signal(SIGHUP, SIG_IGN);
      /* TODO: Put code here for a slow kill shutdown, for now we (should) kick all clients :) */
      std::cout << "Received SIGTERM, Exiting.." << std::endl;
      siggame->disconnectAllClients("Server Shutdown");
      exit(0); // For now, exit.
      break;
    default:
      static_cast<void>(0); // TODO: fix this to do something useful
  }
}
Exemple #2
0
void Mineserver::Watcher_Chat::operator()(Mineserver::Game::pointer_t game, Mineserver::Network_Client::pointer_t client, Mineserver::Network_Message::pointer_t message) const
{
  std::cout << "Chat watcher called!" << std::endl;
  const Mineserver::Network_Message_Chat* msg = reinterpret_cast<Mineserver::Network_Message_Chat*>(&(*message));

	game->chat(client, msg->message);
}
Exemple #3
0
void HandleSegfault()
{
  // Justasic: We only use this statment if we have the capibility of outputting a backtrace >.<
  // Justasic: import some crap from another project i did this to.
  #ifdef HAVE_BACKTRACE
  void *array[10];
  char **strings;
  char tbuf[256];
  size_t size;
  time_t now = time(NULL);
  
  size = backtrace(array, 10);
  #ifdef HAVE_SYS_UTSNAME_H
  struct utsname uts;
  if(uname(&uts) < 0)
    std::cerr << "uname() error: " << strerror(errno) << std::endl;
  #endif
    
  strftime(tbuf, sizeof(tbuf), "[%b %d %H:%M:%S %Y]", localtime(&now));
  std::stringstream slog;
  slog << "====================== Segmentation Fault ======================" << std::endl;
  slog << "Please note that the Mineserver developers may ask you to re-run this under gdb!" << std::endl;
  slog << "Time of crash: " << tbuf << std::endl;
  slog << "Mineserver version: " << VERSION_COMPLETE << std::endl;
  #ifdef HAVE_SYS_UTSNAME_H
  slog << "System info: " << uts.sysname << " " << uts.nodename << " " <<  uts.release << " " << uts.machine << std::endl;
  slog << "System version: " << uts.version << std::endl;
  #endif
  slog << "C++ Version: " << __VERSION__ << std::endl;
  //slog << "Socket Buffer: " << LastBuf << std::endl;
  //slog << "Location: " << segv_location << std::endl;
  strings = backtrace_symbols(array, size);
  for(unsigned i=1; i < size; i++)
    slog << "BackTrace(" << (i - 1) << "): " << strings[i] << std::endl;
  free(strings);
  slog << "======================== END OF REPORT ==========================" << std::endl;
  std::cout << slog.str(); //Write to terminal.
  std::cout.flush(); //Clear output
  #endif // HAVE_BACKTRACE
  // Try and inform the clients of a server crash so we don't freeze/crash clients
  siggame->disconnectAllClients("Server Crash");
  exit(SIGSEGV); // Exit so we're not still running
}
Exemple #4
0
int main()
{
  std::cout << "Mineserver 2.0" << std::endl;

  boost::asio::io_service service;

  Mineserver::Game::pointer_t game = boost::make_shared<Mineserver::Game>();
	
  Mineserver::BlockType::Game_Object_BlockType_SignalHandler::pointer_t blockType_SignalHandler = boost::make_shared<Mineserver::BlockType::Game_Object_BlockType_SignalHandler>();
	
  game->setWorld(0, boost::make_shared<Mineserver::World>());
  game->getWorld(0)->addGenerator(boost::make_shared<Mineserver::World_Generator_Flatlands>());

  game->addMessageWatcher(0x00, boost::bind(&Mineserver::Game::messageWatcherKeepAlive, game, _1, _2, _3));
  game->addMessageWatcher(0x01, boost::bind(&Mineserver::Game::messageWatcherLogin, game, _1, _2, _3));
  game->addMessageWatcher(0x02, boost::bind(&Mineserver::Game::messageWatcherHandshake, game, _1, _2, _3));
  game->addMessageWatcher(0x03, boost::bind(&Mineserver::Game::messageWatcherChat, game, _1, _2, _3));
  game->addMessageWatcher(0x0B, boost::bind(&Mineserver::Game::messageWatcherPosition, game, _1, _2, _3));
  game->addMessageWatcher(0x0C, boost::bind(&Mineserver::Game::messageWatcherOrientation, game, _1, _2, _3));
  game->addMessageWatcher(0x0D, boost::bind(&Mineserver::Game::messageWatcherPositionAndOrientation, game, _1, _2, _3));
  game->addMessageWatcher(0x0E, boost::bind(&Mineserver::Game::messageWatcherDigging, game, _1, _2, _3));
  game->addMessageWatcher(0x0F, boost::bind(&Mineserver::Game::messageWatcherBlockPlacement, game, _1, _2, _3));
  game->addMessageWatcher(0x35, boost::bind(&Mineserver::Game::messageWatcherBlockChange, game, _1, _2, _3));
  game->addMessageWatcher(0xFE, boost::bind(&Mineserver::Game::messageWatcherServerListPing, game, _1, _2, _3));
  game->addMovementPostWatcher(boost::bind(&Mineserver::Game::movementPostWatcher, game, _1, _2, _3));
  game->addBlockBreakPreWatcher(boost::bind(&Mineserver::BlockType::Game_Object_BlockType_SignalHandler::blockBreakPreWatcher, blockType_SignalHandler, _1, _2, _3, _4, _5, _6));
  game->addBlockBreakPostWatcher(boost::bind(&Mineserver::Game::blockBreakPostWatcher, game, _1, _2, _3, _4, _5, _6));
  game->addBlockBreakPostWatcher(boost::bind(&Mineserver::BlockType::Game_Object_BlockType_SignalHandler::blockBreakPostWatcher, blockType_SignalHandler, _1, _2, _3, _4, _5, _6));
  game->addBlockPlacePostWatcher(boost::bind(&Mineserver::Game::blockPlacePostWatcher, game, _1, _2, _3, _4, _5, _6, _7, _8));

  Mineserver::Network_Protocol::pointer_t protocol = boost::make_shared<Mineserver::Network_Protocol_Notch_Protocol>();
  Mineserver::Network_Server::pointer_t server = boost::make_shared<Mineserver::Network_Server>(game, protocol, &service);

  std::cout << "Server is now waiting for connections." << std::endl << "--" << std::endl;

  // TODO: Listen for SIGTERM, on event: close active connections, save world (when implemented), etc.

  while (true) {
    try {
      service.poll();
    } catch (std::exception& e) {
      std::cerr << e.what() << std::endl;
    }

    try {
      game->run();
    } catch (std::exception& e) {
      std::cerr << e.what() << std::endl;
    }

    boost::this_thread::sleep(boost::posix_time::milliseconds(50));
  }

  return 0;
}
Exemple #5
0
void Mineserver::Command::execute(Mineserver::Game::pointer_t game, Mineserver::Game::clientList_t m_clients, Mineserver::Network_Client::pointer_t client)
{
  boost::shared_ptr<Mineserver::Game_Player> player = game->getPlayerForClient(client);
  typedef Mineserver::Game::clientList_t clientList_t;
  if (args[0] == "/say")
    
    {
      boost::shared_ptr<Mineserver::Network_Message_Chat> chatMessage = boost::make_shared<Mineserver::Network_Message_Chat>();
      chatMessage->mid = 0x03;
      chatMessage->message += "§5";
      chatMessage->message += "[Server]";
      for (std::vector<std::string>::iterator sayIt = args.begin() + 1; sayIt != args.end(); ++sayIt)
      {
        chatMessage->message += " " ;
        chatMessage->message += *sayIt;
      }
      
      for ( Mineserver::Game::clientList_t::iterator it = m_clients.begin(); it != m_clients.end(); ++it)
      {
        (*it)->outgoing().push_back(chatMessage);
      }

    } //end of /say server command

    //sends a 0xFF packet to all clients. Usage: /kickall [reason]
    else if (args[0] == "/kickall")
    {
      boost::shared_ptr<Network_Message_Kick> KickMessage = boost::make_shared<Mineserver::Network_Message_Kick>();
      KickMessage->mid = 0xFF;
      KickMessage->reason = "Everyone was kicked from the server!";
      //send the kick packet to all clients.
      for (clientList_t::iterator it = m_clients.begin(); it != m_clients.end(); ++it)
      {
        (*it)->outgoing().push_back(KickMessage);
      }

    } //end of /kickall [reason]

    //FIXME works except player spawns at original height.
    else if (args[0] == "/spawn")
    {
      // I should be using world->spawnX.y.z.
      std::cout << "Sending player: " << player->getName() << " from " << player->getPosition().x <<", " << player->getPosition().y <<", " << player->getPosition().z << " to 0,65,0 EntityId: " << player->getEid() << std::endl;
      Mineserver::World::pointer_t world = game->getWorld(0);
      boost::shared_ptr<Mineserver::Network_Message_PositionAndOrientation> TeleportToSpawnMessage = boost::make_shared<Mineserver::Network_Message_PositionAndOrientation>();
      TeleportToSpawnMessage->mid = 0x0D;
      player->getPosition().x = world->getSpawnPosition().x; //0 --defaults
      player->getPosition().y = world->getSpawnPosition().y; //61
      player->getPosition().z = world->getSpawnPosition().z; //0
      player->getPosition().stance = world->getSpawnPosition().y + 1.62;
      player->getPosition().yaw = 180.0;
      player->getPosition().pitch = 0;
      player->getPosition().onGround = false;
      TeleportToSpawnMessage->x = player->getPosition().x;
      TeleportToSpawnMessage->y = player->getPosition().y;
      TeleportToSpawnMessage->z = player->getPosition().z;
      TeleportToSpawnMessage->stance = player->getPosition().stance; //world->getSpawnPosition().y + 1.62;
      TeleportToSpawnMessage->yaw = player->getPosition().yaw;
      TeleportToSpawnMessage->pitch = player->getPosition().pitch;
      TeleportToSpawnMessage->onGround = player->getPosition().onGround;
      client->outgoing().push_back(TeleportToSpawnMessage);
      std::cout << "Sending Player is now at: " << player->getPosition().x <<", " << player->getPosition().y <<", " << player->getPosition().z << std::endl;

    }

    else if (args[0] == "/t" || args[0] == "/tell" || args[0] == "/msg")
    {
      std::string playername = args[1];
      std::string sender = player->getName();
      std::string message;
      for (std::vector<std::string>::iterator pmsgIt = args.begin() + 2; pmsgIt != args.end(); ++pmsgIt)
      {
        message += *pmsgIt;
        message += " ";
      }
      bool sentMessage = false;
      for (clientList_t::iterator playerIt = m_clients.begin(); playerIt != m_clients.end(); ++playerIt)
      {
        if (player->getName() == playername)
        {
          boost::shared_ptr<Mineserver::Network_Message_Chat> privateChatMessage = boost::make_shared<Mineserver::Network_Message_Chat>();
          privateChatMessage->mid = 0x03;
          privateChatMessage->message += sender;
          privateChatMessage->message += " -> ";
          privateChatMessage->message += message;
          (*playerIt)->outgoing().push_back(privateChatMessage);
          sentMessage = true;
          break;
        }

      }
      if (!sentMessage) {
        boost::shared_ptr<Mineserver::Network_Message_Chat> privateChatMessageFail = boost::make_shared<Mineserver::Network_Message_Chat>();
        privateChatMessageFail->mid = 0x03;
        privateChatMessageFail->message = "§cCould not find player: " + playername;
        client->outgoing().push_back(privateChatMessageFail);      }

    }// end of private message commands

    else if (args[0] == "/tpc" || args[0] == "/pos")
    {
      if (argc == 4) {

        int32_t tpX = atoi(args[1].c_str());
        int32_t tpY = atoi(args[2].c_str());
        int32_t tpZ = atoi(args[3].c_str());
        player->getPosition().x = tpX;
        player->getPosition().y = tpY;
        player->getPosition().z = tpZ;
        player->getPosition().stance = tpY + 1.62;
        player->getPosition().yaw = 180.0;
        player->getPosition().pitch = 0.0;
        player->getPosition().onGround = false;
        std::cout << "PositionP " << tpX << ", " << tpY << ", " << tpZ <<std::endl;
        boost::shared_ptr<Mineserver::Network_Message_PositionAndOrientation> tposTeleportMessage = boost::make_shared<Mineserver::Network_Message_PositionAndOrientation>();
        tposTeleportMessage->mid = 0x0D;
        tposTeleportMessage->x = player->getPosition().x;
        tposTeleportMessage->y = player->getPosition().y;
        tposTeleportMessage->z = player->getPosition().z;
        tposTeleportMessage->stance = player->getPosition().stance;
        tposTeleportMessage->yaw = player->getPosition().yaw;
        tposTeleportMessage->pitch = player->getPosition().pitch;
        tposTeleportMessage->onGround = player->getPosition().onGround;
        client->outgoing().push_back(tposTeleportMessage);
      }
      else
      {
        boost::shared_ptr<Mineserver::Network_Message_Chat> tposMessageFail = boost::make_shared<Mineserver::Network_Message_Chat>();
        tposMessageFail->mid = 0x03;
        tposMessageFail->message = "§cCorrect Usage: /tpc or /pos <x> <y> <z>";
        client->outgoing().push_back(tposMessageFail);
      }
    }

    else if (args[0] == "/s" || args[0] == "/tphere")
    {
      if (argc == 2)
      {
        std::string tpherePlayerName = args[1];
        bool foundPlayer;
        for (clientList_t::iterator tphereIt = m_clients.begin(); tphereIt != m_clients.end(); ++tphereIt)
        {
          if(game->getPlayerForClient(*tphereIt)->getName() == tpherePlayerName)
          {
            bool foundPlayer = true;
            boost::shared_ptr<Mineserver::Network_Message_PositionAndOrientation> tphereTeleportMessage = boost::make_shared<Mineserver::Network_Message_PositionAndOrientation>();
            tphereTeleportMessage->mid = 0x0D;
            //we have to convert the values to Big endian before transmitting.
            std::cout << "Tphere player: " << game->getPlayerForClient(*tphereIt)->getName() << " from: ("
              << game->getPlayerForClient(*tphereIt)->getPosition().x << ", " 
              << game->getPlayerForClient(*tphereIt)->getPosition().y << ", " 
              << game->getPlayerForClient(*tphereIt)->getPosition().z << ") To: (" 
              << game->getPlayerForClient(client)->getPosition().x << ", " 
              << game->getPlayerForClient(client)->getPosition().y << ", " 
              << game->getPlayerForClient(client)->getPosition().z << ") End" << std::endl;
            int32_t sX = game->getPlayerForClient(client)->getPosition().x;
            int32_t sY = game->getPlayerForClient(client)->getPosition().y;
            int32_t sZ = game->getPlayerForClient(client)->getPosition().z;
            tphereTeleportMessage->x = sX;
            tphereTeleportMessage->y = sY;
            tphereTeleportMessage->z = sZ;
            tphereTeleportMessage->stance = game->getPlayerForClient(client)->getPosition().y + 1.62;
            tphereTeleportMessage->yaw = game->getPlayerForClient(*tphereIt)->getPosition().yaw;
            tphereTeleportMessage->pitch = game->getPlayerForClient(*tphereIt)->getPosition().pitch;
            tphereTeleportMessage->onGround = game->getPlayerForClient(*tphereIt)->getPosition().onGround;
            (*tphereIt)->outgoing().push_back(tphereTeleportMessage);
          }
        }
        if (foundPlayer == false)
        {
          boost::shared_ptr<Mineserver::Network_Message_Chat> tphereTeleportMessageFail = boost::make_shared<Mineserver::Network_Message_Chat>();
          tphereTeleportMessageFail->mid = 0x03;
          tphereTeleportMessageFail->message = "§cTphere: Could not find player: " + tpherePlayerName;
          client->outgoing().push_back(tphereTeleportMessageFail);
        }
      }
      else
      {
        boost::shared_ptr<Mineserver::Network_Message_Chat> tphereTeleportMessageFail = boost::make_shared<Mineserver::Network_Message_Chat>();
        tphereTeleportMessageFail->mid = 0x03;
        tphereTeleportMessageFail->message = "§cCorrect Usage: /s or /tphere <playername>";
        client->outgoing().push_back(tphereTeleportMessageFail);
      }
    }

    else if (args[0] == "/help")
    {
      std::vector<std::string> helpOptions;
      helpOptions.push_back("/spawn - Go to 0, 61 ,0");
      helpOptions.push_back("/kickall - Kick all players from the server");
      helpOptions.push_back("/t or /msg <playername> <message> - send a private message");
      helpOptions.push_back("/tp <player> - Teleport to a player");
      helpOptions.push_back("/say <message> - Broadcast a [Server] message");
      helpOptions.push_back("/time <day/night> - Change the world time. Affects all players");
      helpOptions.push_back("/tpc or /pos <x> <y> <z> - Teleport to exact coordinates");
      helpOptions.push_back("/list - list players online. You can also use TAB");
      helpOptions.push_back("/s or /tphere <player> - Teleport a player to you");
      helpOptions.push_back("/gamemode <0 or 1> - Change to Survival(0) or Creative(1)");
      for (std::vector<std::string>::iterator helpIt = helpOptions.begin(); helpIt != helpOptions.end(); ++helpIt) {
        boost::shared_ptr<Mineserver::Network_Message_Chat> chatMessageHelp = boost::make_shared<Mineserver::Network_Message_Chat>();
        chatMessageHelp->mid = 0x03;
        chatMessageHelp->message += "§c";
        chatMessageHelp->message += *helpIt;
        client->outgoing().push_back(chatMessageHelp);
      }
    }
    //teleporting works :)
    else if (args[0] == "/tp")
    {
      if(argc != 2)
      {
        boost::shared_ptr<Mineserver::Network_Message_Chat> tpMessageFail = boost::make_shared<Mineserver::Network_Message_Chat>();
        tpMessageFail->mid = 0x03;
        tpMessageFail->message = "§cCorrect Usage: /tp <player>";
        client->outgoing().push_back(tpMessageFail);
      }
      else
      {
        std::string teleportToPlayer = args[1];
        bool playerExists = false;
        //search for the player...
        for (clientList_t::iterator teleportPlayerToIt = m_clients.begin(); teleportPlayerToIt != m_clients.end(); ++teleportPlayerToIt)
        {
          Mineserver::Game_Player::pointer_t destplayer = game->getPlayerForClient((*teleportPlayerToIt));
          if (destplayer->getName() == teleportToPlayer)
          {
            playerExists = true;
            boost::shared_ptr<Mineserver::Network_Message_PositionAndOrientation> teleportToPlayerMessage = boost::make_shared<Mineserver::Network_Message_PositionAndOrientation>();
            teleportToPlayerMessage->mid = 0x0D;
            teleportToPlayerMessage->x = destplayer->getPosition().x;
            teleportToPlayerMessage->y = destplayer->getPosition().y;
            teleportToPlayerMessage->z = destplayer->getPosition().z;
            teleportToPlayerMessage->stance = destplayer->getPosition().stance;
            teleportToPlayerMessage->yaw = destplayer->getPosition().yaw;
            teleportToPlayerMessage->pitch = destplayer->getPosition().pitch;
            teleportToPlayerMessage->onGround = destplayer->getPosition().onGround;
            client->outgoing().push_back(teleportToPlayerMessage);
            break;
          }
        }
        if (!playerExists)
        {
          boost::shared_ptr<Mineserver::Network_Message_Chat> teleportChatMessageFail = boost::make_shared<Mineserver::Network_Message_Chat>();
          teleportChatMessageFail->mid = 0x03;
          teleportChatMessageFail->message = "Could not find player: " + teleportToPlayer;
          client->outgoing().push_back(teleportChatMessageFail);
        }
      }

    }

    else if (args[0] == "/time" && argc == 2)
    {
      int64_t tickTime;
      if (args[1] == "day") {
        tickTime = 6000; // noon
      }
      else if (args[1] == "night") {
        tickTime = 18000; //night.
      }
      else {
        boost::shared_ptr<Mineserver::Network_Message_Chat> timeChangeMessageFail = boost::make_shared<Mineserver::Network_Message_Chat>();
        timeChangeMessageFail->mid = 0x03;
        timeChangeMessageFail->message = "§cCorrect Usage: /time <day/night>";
        client->outgoing().push_back(timeChangeMessageFail);
      }

      boost::shared_ptr<Mineserver::Network_Message_TimeUpdate> timeUpdateMessage = boost::make_shared<Mineserver::Network_Message_TimeUpdate>();
      timeUpdateMessage->mid = 0x04;
      timeUpdateMessage->time = tickTime;
      for (clientList_t::iterator timeIt = m_clients.begin(); timeIt != m_clients.end(); ++timeIt)
      {
        (*timeIt)->outgoing().push_back(timeUpdateMessage);
      }

    }

    else if (args[0] == "/list")
    {
      for (clientList_t::iterator listIt = m_clients.begin(); listIt != m_clients.end(); ++listIt)
      {
        boost::shared_ptr<Mineserver::Network_Message_Chat> listChatMessage = boost::make_shared<Mineserver::Network_Message_Chat>();
        listChatMessage->mid = 0x03;
        listChatMessage->message = game->getPlayerForClient(*listIt)->getName();
        for (clientList_t::iterator it = m_clients.begin(); it != m_clients.end(); ++it)
        {
          (*it)->outgoing().push_back(listChatMessage);
        }
      }
    }

    else if (args[0] == "/gamemode")
    {
      if (argc == 2)
      {
        uint8_t gameMode;
        if (args[1] == "0") {
          gameMode = 0;
        }
        else {
          gameMode = 1;
        }

        boost::shared_ptr<Mineserver::Network_Message_NewState> gamemodeChangeMessage = boost::make_shared<Mineserver::Network_Message_NewState>();
        gamemodeChangeMessage->mid = 0x46;
        gamemodeChangeMessage->reason = 3;
        gamemodeChangeMessage->mode = gameMode;
        client->outgoing().push_back(gamemodeChangeMessage);
      }

      else
      {
        boost::shared_ptr<Mineserver::Network_Message_Chat> gamemodeChangeFail = boost::make_shared<Mineserver::Network_Message_Chat>();
        gamemodeChangeFail->mid = 0x03;
        gamemodeChangeFail->message = "§cCorrect Usage: /gamemode <0/1>";
        client->outgoing().push_back(gamemodeChangeFail);
      }

    } // end of if /gamemode <mode>

    else if (args[0] == "/chunkprepare")
    {
      if (argc == 4)
      {
        int32_t cX = atoi(args[1].c_str());
        int32_t cZ = atoi(args[2].c_str());
        bool mode;
        if (args[3] == "true")
        {
          mode = true;
        }
        else
        {
          mode = false;
        }
        boost::shared_ptr<Mineserver::Network_Message_ChunkPrepare> chunkPrepareMessage = boost::make_shared<Mineserver::Network_Message_ChunkPrepare>();
        chunkPrepareMessage->mid = 0x32;
        chunkPrepareMessage->x = cX;
        chunkPrepareMessage->z = cZ;
        chunkPrepareMessage->mode = mode;
        for (clientList_t::iterator chunkIt = m_clients.begin(); chunkIt != m_clients.end(); ++chunkIt)
        {
          (*chunkIt)->outgoing().push_back(chunkPrepareMessage);
        }
      }
      else
      {
        boost::shared_ptr<Mineserver::Network_Message_Chat> chunkPrepareFail = boost::make_shared<Mineserver::Network_Message_Chat>();
        chunkPrepareFail->mid = 0x03;
        chunkPrepareFail->message = "§cCorrect Usage: /chunkprepare <x> <z> <true/false>";
        client->outgoing().push_back(chunkPrepareFail);
      }
    }
    else if (args[0] == "/chunkdata")
    {
      if (argc == 3)
      {
        int32_t cX = atoi(args[1].c_str());
        int32_t cZ = atoi(args[2].c_str());
        boost::shared_ptr<Mineserver::Network_Message_Chunk> chunkDataMessage = boost::make_shared<Mineserver::Network_Message_Chunk>();
        Mineserver::World::pointer_t world = game->getWorld(0);

        chunkDataMessage->mid = 0x33;
        chunkDataMessage->posX = cX * 16;
        chunkDataMessage->posY = 0;
        chunkDataMessage->posZ = cZ * 16;
        chunkDataMessage->sizeX = 15;
        chunkDataMessage->sizeY = 127;
        chunkDataMessage->sizeZ = 15;
        chunkDataMessage->chunk = world->generateChunk(cX, cZ);
        for (clientList_t::iterator chunkIt = m_clients.begin(); chunkIt != m_clients.end(); ++chunkIt)
        {
          (*chunkIt)->outgoing().push_back(chunkDataMessage);
        }
      }
      else {
        {
          boost::shared_ptr<Mineserver::Network_Message_Chat> chunkDataFail = boost::make_shared<Mineserver::Network_Message_Chat>();
          chunkDataFail->mid = 0x03;
          chunkDataFail->message = "§cCorrect Usage: /chunkdata <x> <z>";
          client->outgoing().push_back(chunkDataFail);
        }
      }

    }

    else if (args[0] == "/chunk")
    {
      Mineserver::Game_Player::pointer_t chunkplayer = player;
      boost::shared_ptr<Mineserver::Network_Message_Chat> chunkMessage = boost::make_shared<Mineserver::Network_Message_Chat>();
      chunkMessage->mid = 0x03;
      std::string chunkx;
      std::stringstream outx;
      outx << std::floor(chunkplayer->getPosition().x / 16);
      chunkx = outx.str();
      std::string chunkz;
      std::stringstream outz;
      outz << std::floor(chunkplayer->getPosition().z / 16);
      chunkz = outz.str();
      chunkMessage->message = "§5You are in chunk: " + chunkx + ", " + chunkz;

      client->outgoing().push_back(chunkMessage);
    }
    
    else if (args[0] == "/save")
    {
      //save a chunk
      Mineserver::Game_Player::pointer_t saverplayer = game->getPlayerForClient((client));
      Mineserver::World::pointer_t world = game->getWorld(0);
      int tX = std::floor(player->getPosition().x / 16);
      int tZ = std::floor(player->getPosition().z / 16);
      Mineserver::World_Chunk::pointer_t chunk = world->getChunk(tX,tZ);
      std::cout << "\nsizeof" << sizeof *chunk << std::endl;
      std::string fileName = "c.";
      std::stringstream ssX;
      std::stringstream ssZ;
      ssX << tX;
      ssZ << tZ;
      fileName.append(ssX.str());
      fileName.append(".");
      fileName.append(ssZ.str());
      fileName.append(".cho");
      char *fileName_c = (char*)fileName.c_str();
      std::ofstream file(fileName_c, std::ios::binary);
      file.write((char*)&chunk, sizeof *chunk);
      file.close();

    }
    
    else if (args[0] == "/load")
    {
      Mineserver::Game_Player::pointer_t saverplayer = game->getPlayerForClient((client));
      Mineserver::World::pointer_t world = game->getWorld(0);
      int tX = std::floor(player->getPosition().x / 16);
      int tZ = std::floor(player->getPosition().z / 16);
      Mineserver::World_Chunk::pointer_t chunk = world->getChunk(tX,tZ);
      std::cout << "\nsizeof" << sizeof *chunk << std::endl;
      std::string fileName = "c.";
      std::stringstream ssX;
      std::stringstream ssZ;
      ssX << tX;
      ssZ << tZ;
      fileName.append(ssX.str());
      fileName.append(".");
      fileName.append(ssZ.str());
      fileName.append(".cho");
      char *fileName_c = (char*)fileName.c_str();
      std::ifstream file(fileName_c, std::ios::binary);
      std::cout << "\nAttempting to read: " << fileName_c << std::endl; 
      file.read((char*)&chunk, sizeof &chunk);
      //chunk prepare message -false - unload old
      boost::shared_ptr<Mineserver::Network_Message_ChunkPrepare> chunkPrepareUnloadMessage = boost::make_shared<Mineserver::Network_Message_ChunkPrepare>();
      chunkPrepareUnloadMessage->mid = 0x32;
      chunkPrepareUnloadMessage->x = tX;
      chunkPrepareUnloadMessage->z = tZ;
      chunkPrepareUnloadMessage->mode = 0;
      for (clientList_t::iterator chunkIt = m_clients.begin(); chunkIt != m_clients.end(); ++chunkIt)
      {
        (*chunkIt)->outgoing().push_back(chunkPrepareUnloadMessage);
      }
      //chunk prepare message -true - prepare new...
      boost::shared_ptr<Mineserver::Network_Message_ChunkPrepare> chunkPrepareReloadMessage = boost::make_shared<Mineserver::Network_Message_ChunkPrepare>();
      chunkPrepareReloadMessage->mid = 0x32;
      chunkPrepareReloadMessage->x = tX;
      chunkPrepareReloadMessage->z = tZ;
      chunkPrepareReloadMessage->mode = 1;
      for (clientList_t::iterator chunkIt = m_clients.begin(); chunkIt != m_clients.end(); ++chunkIt)
      {
        (*chunkIt)->outgoing().push_back(chunkPrepareReloadMessage);
      }
      //send the data...
      boost::shared_ptr<Mineserver::Network_Message_Chunk> chunkDataMessage = boost::make_shared<Mineserver::Network_Message_Chunk>();
      chunkDataMessage->mid = 0x33;
      chunkDataMessage->posX = tX * 16;
      chunkDataMessage->posY = 0;
      chunkDataMessage->posZ = tZ * 16;
      chunkDataMessage->sizeX = 15;
      chunkDataMessage->sizeY = 127;
      chunkDataMessage->sizeZ = 15;
      chunkDataMessage->chunk = chunk;
      for (clientList_t::iterator chunkIt = m_clients.begin(); chunkIt != m_clients.end(); ++chunkIt)
      {
        (*chunkIt)->outgoing().push_back(chunkDataMessage);
      }
    }
    
    else
    {
      boost::shared_ptr<Mineserver::Network_Message_Chat> chatMessageError = boost::make_shared<Mineserver::Network_Message_Chat>();
      chatMessageError->mid = 0x03;
      chatMessageError->message = "§cUnknown command. Try /help for a list.";
      client->outgoing().push_back(chatMessageError);
    }

}
Exemple #6
0
void Mineserver::Watcher_Login::operator()(Mineserver::Game::pointer_t game, Mineserver::Network_Client::pointer_t client, Mineserver::Network_Message::pointer_t message) const
{
  std::cout << "Login watcher called!" << std::endl;
  const Mineserver::Network_Message_Login* msg = reinterpret_cast<Mineserver::Network_Message_Login*>(&(*message));

  Mineserver::Game_Player::pointer_t player(new Mineserver::Game_Player);
  player->setName(msg->username);

  std::cout << "Player login v." << msg->version << ": " << msg->username << std::endl;

  game->addPlayer(player);
  game->associateClient(client, player);

  boost::shared_ptr<Mineserver::Network_Message_Login> loginMessage = boost::make_shared<Mineserver::Network_Message_Login>();
  loginMessage->mid = 0x01;
  loginMessage->version = 1;
  loginMessage->seed = 1;
  loginMessage->mode = 0;
  loginMessage->dimension = 0;
  loginMessage->difficulty = 2;
  loginMessage->worldHeight = 128;
  loginMessage->maxPlayers = 128;
  client->outgoing().push_back(loginMessage);

  for (int x = -5; x <= 5; ++x) {
    for (int z = -5; z <= 5; ++z) {
      boost::shared_ptr<Mineserver::Network_Message_ChunkPrepare> chunkPrepareMessage = boost::make_shared<Mineserver::Network_Message_ChunkPrepare>();
      chunkPrepareMessage->mid = 0x32;
      chunkPrepareMessage->x = x;
      chunkPrepareMessage->z = z;
      chunkPrepareMessage->mode = 1;
      client->outgoing().push_back(chunkPrepareMessage);
    }
  }

  Mineserver::World::pointer_t world = game->getWorld(0);

  for (int x = -5; x <= 5; ++x) {
    for (int z = -5; z <= 5; ++z) {
      boost::shared_ptr<Mineserver::Network_Message_Chunk> chunkMessage = boost::make_shared<Mineserver::Network_Message_Chunk>();
      chunkMessage->mid = 0x33;
      chunkMessage->posX = x;
      chunkMessage->posY = 0;
      chunkMessage->posZ = z;
      chunkMessage->sizeX = 15;
      chunkMessage->sizeY = 127;
      chunkMessage->sizeZ = 15;
      chunkMessage->chunk = world->generateChunk(x, z);
      client->outgoing().push_back(chunkMessage);
    }
  }

  boost::shared_ptr<Mineserver::Network_Message_SpawnPosition> spawnPositionMessage = boost::make_shared<Mineserver::Network_Message_SpawnPosition>();
  spawnPositionMessage->mid = 0x06;
  spawnPositionMessage->x = 0;
  spawnPositionMessage->y = 100;
  spawnPositionMessage->z = 0;
  client->outgoing().push_back(spawnPositionMessage);

  boost::shared_ptr<Mineserver::Network_Message_PositionLook> positionLookMessage = boost::make_shared<Mineserver::Network_Message_PositionLook>();
  positionLookMessage->mid = 0x0D;
  positionLookMessage->x = 0;
  positionLookMessage->y = 100;
  positionLookMessage->z = 0;
  positionLookMessage->stance = 100;
  positionLookMessage->yaw = 0;
  positionLookMessage->pitch = 0;
  positionLookMessage->onGround = 0;
  client->outgoing().push_back(positionLookMessage);
}