X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fserver.cpp;h=b257448a1c4e2de8b1b7091ffd74e103352e4c2a;hb=676f34a02be17d898ea45b1b05be72bfcfcd588e;hp=1fea8afe5ac9bc5fe9ce65cf777ffc7825065673;hpb=61f240946a794423b0a50916c96dbb51054a77d0;p=dragonfireclient.git diff --git a/src/server.cpp b/src/server.cpp index 1fea8afe5..b257448a1 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -22,19 +22,23 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include "clientserver.h" +#include "ban.h" +#include "environment.h" #include "map.h" -#include "jmutexautolock.h" +#include "jthread/jmutexautolock.h" #include "main.h" #include "constants.h" #include "voxel.h" #include "config.h" +#include "version.h" #include "filesys.h" #include "mapblock.h" #include "serverobject.h" +#include "genericobject.h" #include "settings.h" #include "profiler.h" #include "log.h" -#include "script/cpp_api/scriptapi.h" +#include "scripting_game.h" #include "nodedef.h" #include "itemdef.h" #include "craftdef.h" @@ -58,6 +62,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/mathconstants.h" #include "rollback.h" #include "util/serialize.h" +#include "util/thread.h" #include "defaultsettings.h" class ClientNotFoundException : public BaseException @@ -68,17 +73,33 @@ class ClientNotFoundException : public BaseException {} }; -void * ServerThread::Thread() +class ServerThread : public JThread { - ThreadStarted(); + Server *m_server; + +public: + + ServerThread(Server *server): + JThread(), + m_server(server) + { + } + void * Thread(); +}; + +void * ServerThread::Thread() +{ log_register_thread("ServerThread"); DSTACK(__FUNCTION_NAME); - BEGIN_DEBUG_EXCEPTION_HANDLER - while(getRun()) + m_server->AsyncRunStep(true); + + ThreadStarted(); + + while(!StopRequested()) { try{ //TimeTaker timer("AsyncRunStep() + Receive()"); @@ -613,46 +634,23 @@ void RemoteClient::SetBlocksNotSent(std::map &blocks) } } -/* - PlayerInfo -*/ - -PlayerInfo::PlayerInfo() -{ - name[0] = 0; - avg_rtt = 0; -} - -void PlayerInfo::PrintLine(std::ostream *s) -{ - (*s)<getBool("enable_ipv6") && g_settings->getBool("ipv6_server"), this), - m_banmanager(path_world+DIR_DELIM+"ipban.txt"), + m_banmanager(NULL), m_rollback(NULL), m_rollback_sink_enabled(true), m_enable_rollback_recording(false), @@ -662,7 +660,7 @@ Server::Server( m_nodedef(createNodeDefManager()), m_craftdef(createCraftDefManager()), m_event(new EventManager()), - m_thread(this), + m_thread(NULL), m_time_of_day_send_timer(0), m_uptime(0), m_shutdown_requested(false), @@ -676,12 +674,9 @@ Server::Server( m_objectdata_timer = 0.0; m_emergethread_trigger_timer = 0.0; m_savemap_timer = 0.0; - m_clients_number = 0; - m_env_mutex.Init(); - m_con_mutex.Init(); - m_step_dtime_mutex.Init(); m_step_dtime = 0.0; + m_lag = g_settings->getFloat("dedicated_server_step"); if(path_world == "") throw ServerError("Supplied empty world path"); @@ -695,7 +690,6 @@ Server::Server( else infostream< unsatisfied_mods = modconf.getUnsatisfiedMods(); // complain about mods with unsatisfied dependencies - if(!modconf.isConsistent()) + if(!modconf.isConsistent()) { for(std::vector::iterator it = unsatisfied_mods.begin(); it != unsatisfied_mods.end(); ++it) @@ -739,10 +740,10 @@ Server::Server( worldmt_settings.readConfigFile(worldmt.c_str()); std::vector names = worldmt_settings.getNames(); std::set load_mod_names; - for(std::vector::iterator it = names.begin(); + for(std::vector::iterator it = names.begin(); it != names.end(); ++it) - { - std::string name = *it; + { + std::string name = *it; if(name.compare(0,9,"load_mod_")==0 && worldmt_settings.getBool(name)) load_mod_names.insert(name.substr(9)); } @@ -754,7 +755,7 @@ Server::Server( it != unsatisfied_mods.end(); ++it) load_mod_names.erase((*it).name); if(!load_mod_names.empty()) - { + { errorstream << "The following mods could not be found:"; for(std::set::iterator it = load_mod_names.begin(); it != load_mod_names.end(); ++it) @@ -773,7 +774,7 @@ Server::Server( infostream<<"Server: Initializing Lua"<getMapgenParams(); @@ -824,6 +825,7 @@ Server::Server( // Initialize mapgens m_emerge->initMapgens(mgparams); + servermap->setMapgenParams(m_emerge->params); // Give environment reference to scripting api m_script->initializeEnvironment(m_env); @@ -913,6 +915,7 @@ Server::~Server() Stop threads */ stop(); + delete m_thread; //shutdown all emerge threads first! delete m_emerge; @@ -936,6 +939,7 @@ Server::~Server() // Delete things in the reverse order of creation delete m_env; delete m_rollback; + delete m_banmanager; delete m_event; delete m_itemdef; delete m_nodedef; @@ -961,15 +965,14 @@ void Server::start(unsigned short port) infostream<<"Starting server on port "<Stop(); // Initialize connection m_con.SetTimeoutMs(30); m_con.Serve(port); // Start thread - m_thread.setRun(true); - m_thread.Start(); + m_thread->Start(); // ASCII art for the win! actionstream @@ -991,9 +994,9 @@ void Server::stop() infostream<<"Server: Stopping and waiting threads"<Stop(); //m_emergethread.setRun(false); - m_thread.stop(); + m_thread->Wait(); //m_emergethread.stop(); infostream<<"Server: Threads stopped"<add("Server::AsyncRunStep with dtime (num)", 1); @@ -1086,15 +1089,15 @@ void Server::AsyncRunStep() //JMutexAutoLock envlock(m_env_mutex); JMutexAutoLock conlock(m_con_mutex); + u16 time = m_env->getTimeOfDay(); + float time_speed = g_settings->getFloat("time_speed"); + for(std::map::iterator i = m_clients.begin(); i != m_clients.end(); ++i) { RemoteClient *client = i->second; - SharedBuffer data = makePacket_TOCLIENT_TIME_OF_DAY( - m_env->getTimeOfDay(), g_settings->getFloat("time_speed")); - // Send as reliable - m_con.Send(client->peer_id, 0, data, true); + SendTimeOfDay(client->peer_id, time, time_speed); } } } @@ -1239,7 +1242,7 @@ void Server::AsyncRunStep() counter = 0.0; JMutexAutoLock lock2(m_con_mutex); - m_clients_number = 0; + m_clients_names.clear(); if(m_clients.size() != 0) infostream<<"Players:"<::iterator @@ -1253,19 +1256,20 @@ void Server::AsyncRunStep() continue; infostream<<"* "<getName()<<"\t"; client->PrintInfo(infostream); - ++m_clients_number; + m_clients_names.push_back(player->getName()); } } } + m_lag += (m_lag > dtime ? -1 : 1) * dtime/100; #if USE_CURL // send masterserver announce { float &counter = m_masterserver_timer; if(!isSingleplayer() && (!counter || counter >= 300.0) && g_settings->getBool("server_announce") == true) { - ServerList::sendAnnounce(!counter ? "start" : "update", m_clients_number, m_uptime.get(), m_gamespec.id, m_mods); + ServerList::sendAnnounce(!counter ? "start" : "update", m_clients_names, m_uptime.get(), m_env->getGameTime(), m_lag, m_gamespec.id, m_mods); counter = 0.01; } counter += dtime; @@ -1525,7 +1529,7 @@ void Server::AsyncRunStep() memcpy((char*)&reply[2], unreliable_data.c_str(), unreliable_data.size()); // Send as unreliable - m_con.Send(client->peer_id, 0, reply, false); + m_con.Send(client->peer_id, 1, reply, false); } /*if(reliable_data.size() > 0 || unreliable_data.size() > 0) @@ -1578,16 +1582,16 @@ void Server::AsyncRunStep() // for them. std::list far_players; - if(event->type == MEET_ADDNODE) + if(event->type == MEET_ADDNODE || event->type == MEET_SWAPNODE) { //infostream<<"Server: MEET_ADDNODE"<p, event->n, event->already_known_by_peer, - &far_players, 5); + &far_players, 5, event->type == MEET_ADDNODE); else sendAddNode(event->p, event->n, event->already_known_by_peer, - &far_players, 30); + &far_players, 30, event->type == MEET_ADDNODE); } else if(event->type == MEET_REMOVENODE) { @@ -1680,8 +1684,7 @@ void Server::AsyncRunStep() { counter = 0.0; - for (unsigned int i = 0; i != m_emerge->emergethread.size(); i++) - m_emerge->emergethread[i]->trigger(); + m_emerge->startAllThreads(); // Update m_enable_rollback_recording here too m_enable_rollback_recording = @@ -1701,8 +1704,8 @@ void Server::AsyncRunStep() ScopeProfiler sp(g_profiler, "Server: saving stuff"); //Ban stuff - if(m_banmanager.isModified()) - m_banmanager.save(); + if(m_banmanager->isModified()) + m_banmanager->save(); // Save changed parts of map m_env->getMap().save(MOD_STATE_WRITE_NEEDED); @@ -1772,13 +1775,14 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) addr_s = address.serializeString(); // drop player if is ip is banned - if(m_banmanager.isIpBanned(addr_s)){ + if(m_banmanager->isIpBanned(addr_s)){ + std::string ban_name = m_banmanager->getBanName(addr_s); infostream<<"Server: A banned client tried to connect from " <net_proto_version != 0){ + verbosestream<<"Server: Ignoring multiple TOSERVER_INITs from " + <on_prejoinplayer(playername, addr_s, reason)) + { + actionstream<<"Server: Player with the name \""< data = makePacket_TOCLIENT_TIME_OF_DAY( - m_env->getTimeOfDay(), g_settings->getFloat("time_speed")); - m_con.Send(peer_id, 0, data, true); + u16 time = m_env->getTimeOfDay(); + float time_speed = g_settings->getFloat("time_speed"); + SendTimeOfDay(peer_id, time, time_speed); } // Note things in chat if not in simple singleplayer mode @@ -2722,7 +2747,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); - std::list tosend; + std::list tosend; u16 numfiles = readU16(is); infostream<<"Sending "<setTimeOfDay(time); + m_time_of_day_send_timer = 0; +} + void Server::onMapEditEvent(MapEditEvent *event) { //infostream<<"Server::onMapEditEvent()"< Server::getPlayerInfo() -//{ -// DSTACK(__FUNCTION_NAME); -// JMutexAutoLock envlock(m_env_mutex); -// JMutexAutoLock conlock(m_con_mutex); -// -// std::list list; -// -// std::list players = m_env->getPlayers(); -// -// std::list::iterator i; -// for(i = players.begin(); -// i != players.end(); ++i) -// { -// PlayerInfo info; -// -// Player *player = *i; -// -// try{ -// // Copy info from connection to info struct -// info.id = player->peer_id; -// info.address = m_con.GetPeerAddress(player->peer_id); -// info.avg_rtt = m_con.GetPeerAvgRTT(player->peer_id); -// } -// catch(con::PeerNotFoundException &e) -// { -// // Set dummy peer info -// info.id = 0; -// info.address = Address(0,0,0,0,0); -// info.avg_rtt = 0.0; -// } -// -// snprintf(info.name, PLAYERNAME_SIZE, "%s", player->getName()); -// info.position = player->getPosition(); -// -// list.push_back(info); -// } -// -// return list; -//} - - void Server::peerAdded(con::Peer *peer) { DSTACK(__FUNCTION_NAME); @@ -3733,7 +3722,7 @@ void Server::SendHUDAdd(u16 peer_id, u32 id, HudElement *form) std::string s = os.str(); SharedBuffer data((u8*)s.c_str(), s.size()); // Send as reliable - m_con.Send(peer_id, 0, data, true); + m_con.Send(peer_id, 1, data, true); } void Server::SendHUDRemove(u16 peer_id, u32 id) @@ -3748,7 +3737,8 @@ void Server::SendHUDRemove(u16 peer_id, u32 id) std::string s = os.str(); SharedBuffer data((u8*)s.c_str(), s.size()); // Send as reliable - m_con.Send(peer_id, 0, data, true); + + m_con.Send(peer_id, 1, data, true); } void Server::SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value) @@ -3833,6 +3823,20 @@ void Server::BroadcastChatMessage(const std::wstring &message) } } +void Server::SendTimeOfDay(u16 peer_id, u16 time, f32 time_speed) +{ + DSTACK(__FUNCTION_NAME); + + // Make packet + SharedBuffer data(2+2+4); + writeU16(&data[0], TOCLIENT_TIME_OF_DAY); + writeU16(&data[2], time); + writeF1000(&data[4], time_speed); + + // Send as reliable + m_con.Send(peer_id, 0, data, true); +} + void Server::SendPlayerHP(u16 peer_id) { DSTACK(__FUNCTION_NAME); @@ -3840,6 +3844,11 @@ void Server::SendPlayerHP(u16 peer_id) assert(playersao); playersao->m_hp_not_sent = false; SendHP(m_con, peer_id, playersao->getHP()); + + // Send to other clients + std::string str = gob_cmd_punched(playersao->readDamage(), playersao->getHP()); + ActiveObjectMessage aom(playersao->getId(), true, str); + playersao->m_messages_out.push_back(aom); } void Server::SendPlayerBreath(u16 peer_id) @@ -4075,7 +4084,8 @@ void Server::sendRemoveNode(v3s16 p, u16 ignore_id, } void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id, - std::list *far_players, float far_d_nodes) + std::list *far_players, float far_d_nodes, + bool remove_metadata) { float maxd = far_d_nodes*BS; v3f p_f = intToFloat(p, BS); @@ -4111,13 +4121,23 @@ void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id, } // Create packet - u32 replysize = 8 + MapNode::serializedLength(client->serialization_version); + u32 replysize = 9 + MapNode::serializedLength(client->serialization_version); SharedBuffer reply(replysize); writeU16(&reply[0], TOCLIENT_ADDNODE); writeS16(&reply[2], p.X); writeS16(&reply[4], p.Y); writeS16(&reply[6], p.Z); n.serialize(&reply[8], client->serialization_version); + u32 index = 8 + MapNode::serializedLength(client->serialization_version); + writeU8(&reply[index], remove_metadata ? 0 : 1); + + if (!remove_metadata) { + if (client->net_proto_version <= 21) { + // Old clients always clear metadata; fix it + // by sending the full block again. + client->SetBlockNotSent(p); + } + } // Send as reliable m_con.Send(client->peer_id, 0, reply, true); @@ -4186,7 +4206,7 @@ void Server::SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver, u16 net_proto /* Send packet */ - m_con.Send(peer_id, 1, reply, true); + m_con.Send(peer_id, 2, reply, true); } void Server::SendBlocks(float dtime) @@ -4436,7 +4456,7 @@ struct SendableMedia }; void Server::sendRequestedMedia(u16 peer_id, - const std::list &tosend) + const std::list &tosend) { DSTACK(__FUNCTION_NAME); @@ -4453,17 +4473,19 @@ void Server::sendRequestedMedia(u16 peer_id, u32 file_size_bunch_total = 0; - for(std::list::const_iterator i = tosend.begin(); + for(std::list::const_iterator i = tosend.begin(); i != tosend.end(); ++i) { - if(m_media.find(i->name) == m_media.end()){ + const std::string &name = *i; + + if(m_media.find(name) == m_media.end()){ errorstream<<"Server::sendRequestedMedia(): Client asked for " - <<"unknown file \""<<(i->name)<<"\""<= bytes_per_bunch){ @@ -4546,7 +4568,7 @@ void Server::sendRequestedMedia(u16 peer_id, <<" size=" < data((u8*)s.c_str(), s.size()); // Send as reliable - m_con.Send(peer_id, 0, data, true); + m_con.Send(peer_id, 2, data, true); } } @@ -4650,7 +4672,9 @@ void Server::DenyAccess(u16 peer_id, const std::wstring &reason) client->denied = true; // If there are way too many clients, get rid of denied new ones immediately - if(m_clients.size() > 2 * g_settings->getU16("max_users")){ + if((int)m_clients.size() > 2 * g_settings->getU16("max_users")){ + verbosestream<<"Server: DenyAccess: Too many clients; getting rid of " + <<"peer_id="<getName()); getCraftingResult(&player->inventory, preview, false, this); + m_env->getScriptIface()->item_CraftPredict(preview, player->getPlayerSAO(), (&player->inventory)->getList("craft"), loc); // Put the new preview in InventoryList *plist = player->inventory.getList("craftpreview"); @@ -4808,12 +4832,28 @@ RemoteClient* Server::getClientNoEx(u16 peer_id) return n->second; } +std::string Server::getPlayerName(u16 peer_id) +{ + Player *player = m_env->getPlayer(peer_id); + if(player == NULL) + return "[id="+itos(peer_id)+"]"; + return player->getName(); +} + +PlayerSAO* Server::getPlayerSAO(u16 peer_id) +{ + Player *player = m_env->getPlayer(peer_id); + if(player == NULL) + return NULL; + return player->getPlayerSAO(); +} + std::wstring Server::getStatusString() { std::wostringstream os(std::ios_base::binary); os<updateConfigFile(m_path_config.c_str()); + return m_banmanager->getBanDescription(ip_or_name); } void Server::notifyPlayer(const char *name, const std::wstring msg, const bool prepend = true) @@ -4932,7 +4980,7 @@ u32 Server::hudAdd(Player *player, HudElement *form) { if (!player) return -1; - u32 id = hud_get_free_id(player); + u32 id = player->getFreeHudID(); if (id < player->hud.size()) player->hud[id] = form; else @@ -4981,6 +5029,20 @@ bool Server::hudSetHotbarItemcount(Player *player, s32 hotbar_itemcount) { return true; } +void Server::hudSetHotbarImage(Player *player, std::string name) { + if (!player) + return; + + SendHUDSetParam(player->peer_id, HUD_PARAM_HOTBAR_IMAGE, name); +} + +void Server::hudSetHotbarSelectedImage(Player *player, std::string name) { + if (!player) + return; + + SendHUDSetParam(player->peer_id, HUD_PARAM_HOTBAR_SELECTED_IMAGE, name); +} + void Server::notifyPlayers(const std::wstring msg) { BroadcastChatMessage(msg); @@ -5091,11 +5153,6 @@ void Server::deleteParticleSpawnerAll(u32 id) SendDeleteParticleSpawnerAll(id); } -void Server::queueBlockEmerge(v3s16 blockpos, bool allow_generate) -{ - m_emerge->enqueueBlockEmerge(PEER_ID_INEXISTENT, blockpos, allow_generate); -} - Inventory* Server::createDetachedInventory(const std::string &name) { if(m_detached_inventories.count(name) > 0){