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