minetest/src/server.cpp

3741 lines
98 KiB
C++
Raw Normal View History

/*
2013-02-24 18:40:43 +01:00
Minetest
2013-02-24 19:38:45 +01:00
Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
2010-11-27 00:02:21 +01:00
#include "server.h"
#include <iostream>
#include <queue>
#include <algorithm>
#include "network/connection.h"
#include "network/networkprotocol.h"
#include "network/serveropcodes.h"
#include "ban.h"
#include "environment.h"
2010-11-27 00:02:21 +01:00
#include "map.h"
#include "threading/mutex_auto_lock.h"
2010-11-27 00:02:21 +01:00
#include "constants.h"
#include "voxel.h"
2011-04-24 23:31:22 +02:00
#include "config.h"
#include "version.h"
#include "filesys.h"
2011-06-26 01:34:36 +02:00
#include "mapblock.h"
#include "serverobject.h"
#include "genericobject.h"
2011-10-12 12:53:38 +02:00
#include "settings.h"
#include "profiler.h"
#include "log.h"
#include "scripting_server.h"
2011-11-14 20:41:30 +01:00
#include "nodedef.h"
#include "itemdef.h"
2011-11-17 01:28:46 +01:00
#include "craftdef.h"
#include "emerge.h"
#include "mapgen/mapgen.h"
#include "mapgen/mg_biome.h"
#include "content_mapnode.h"
#include "content_nodemeta.h"
#include "content_sao.h"
#include "content/mods.h"
#include "modchannels.h"
2013-02-21 23:00:44 +01:00
#include "serverlist.h"
#include "util/string.h"
#include "rollback.h"
#include "util/serialize.h"
#include "util/thread.h"
2013-03-21 20:42:23 +01:00
#include "defaultsettings.h"
#include "server/mods.h"
2015-02-21 14:17:36 +01:00
#include "util/base64.h"
#include "util/sha1.h"
#include "util/hex.h"
#include "database/database.h"
#include "chatmessage.h"
#include "chat_interface.h"
#include "remoteplayer.h"
class ClientNotFoundException : public BaseException
{
public:
ClientNotFoundException(const char *s):
BaseException(s)
{}
};
class ServerThread : public Thread
{
public:
ServerThread(Server *server):
Thread("Server"),
m_server(server)
{}
void *run();
private:
Server *m_server;
};
void *ServerThread::run()
2010-11-27 00:02:21 +01:00
{
BEGIN_DEBUG_EXCEPTION_HANDLER
m_server->AsyncRunStep(true);
while (!stopRequested()) {
try {
m_server->AsyncRunStep();
2010-11-27 00:02:21 +01:00
m_server->Receive();
} catch (con::NoIncomingDataException &e) {
} catch (con::PeerNotFoundException &e) {
infostream<<"Server: PeerNotFoundException"<<std::endl;
} catch (ClientNotFoundException &e) {
} catch (con::ConnectionBindFailed &e) {
m_server->setAsyncFatalError(e.what());
} catch (LuaError &e) {
m_server->setAsyncFatalError(
"ServerThread::run Lua: " + std::string(e.what()));
}
2010-11-27 00:02:21 +01:00
}
END_DEBUG_EXCEPTION_HANDLER
2010-11-27 00:02:21 +01:00
return nullptr;
2010-11-27 00:02:21 +01:00
}
v3f ServerSoundParams::getPos(ServerEnvironment *env, bool *pos_exists) const
{
if(pos_exists) *pos_exists = false;
switch(type){
case SSP_LOCAL:
return v3f(0,0,0);
case SSP_POSITIONAL:
if(pos_exists) *pos_exists = true;
return pos;
case SSP_OBJECT: {
if(object == 0)
return v3f(0,0,0);
ServerActiveObject *sao = env->getActiveObject(object);
if(!sao)
return v3f(0,0,0);
if(pos_exists) *pos_exists = true;
return sao->getBasePosition(); }
}
return v3f(0,0,0);
}
void Server::ShutdownState::reset()
{
m_timer = 0.0f;
message.clear();
should_reconnect = false;
is_requested = false;
}
void Server::ShutdownState::trigger(float delay, const std::string &msg, bool reconnect)
{
m_timer = delay;
message = msg;
should_reconnect = reconnect;
}
void Server::ShutdownState::tick(float dtime, Server *server)
{
if (m_timer <= 0.0f)
return;
// Timed shutdown
static const float shutdown_msg_times[] =
{
1, 2, 3, 4, 5, 10, 20, 40, 60, 120, 180, 300, 600, 1200, 1800, 3600
};
// Automated messages
if (m_timer < shutdown_msg_times[ARRLEN(shutdown_msg_times) - 1]) {
for (float t : shutdown_msg_times) {
// If shutdown timer matches an automessage, shot it
if (m_timer > t && m_timer - dtime < t) {
std::wstring periodicMsg = getShutdownTimerMessage();
infostream << wide_to_utf8(periodicMsg).c_str() << std::endl;
server->SendChatMessage(PEER_ID_INEXISTENT, periodicMsg);
break;
}
}
}
m_timer -= dtime;
if (m_timer < 0.0f) {
m_timer = 0.0f;
is_requested = true;
}
}
std::wstring Server::ShutdownState::getShutdownTimerMessage() const
{
std::wstringstream ws;
ws << L"*** Server shutting down in "
<< duration_to_string(myround(m_timer)).c_str() << ".";
return ws.str();
}
2010-11-27 00:02:21 +01:00
/*
Server
*/
Server::Server(
2012-03-11 13:54:23 +01:00
const std::string &path_world,
const SubgameSpec &gamespec,
bool simple_singleplayer_mode,
Address bind_addr,
bool dedicated,
ChatInterface *iface
2010-11-27 00:02:21 +01:00
):
m_bind_addr(bind_addr),
2012-03-10 14:56:24 +01:00
m_path_world(path_world),
2012-03-11 13:54:23 +01:00
m_gamespec(gamespec),
m_simple_singleplayer_mode(simple_singleplayer_mode),
m_dedicated(dedicated),
m_async_fatal_error(""),
m_con(std::make_shared<con::Connection>(PROTOCOL_ID,
512,
CONNECTION_TIMEOUT,
m_bind_addr.isIPv6(),
this)),
m_itemdef(createItemDefManager()),
m_nodedef(createNodeDefManager()),
2011-11-17 01:28:46 +01:00
m_craftdef(createCraftDefManager()),
m_uptime(0),
m_clients(m_con),
m_admin_chat(iface),
m_modchannel_mgr(new ModChannelMgr())
2010-11-27 00:02:21 +01:00
{
m_lag = g_settings->getFloat("dedicated_server_step");
2011-11-11 18:33:17 +01:00
if (m_path_world.empty())
throw ServerError("Supplied empty world path");
if (!gamespec.isValid())
2012-03-11 13:54:23 +01:00
throw ServerError("Supplied invalid gamespec");
}
Server::~Server()
{
// Send shutdown message
SendChatMessage(PEER_ID_INEXISTENT, ChatMessage(CHATMESSAGE_TYPE_ANNOUNCE,
L"*** Server shutting down"));
if (m_env) {
MutexAutoLock envlock(m_env_mutex);
infostream << "Server: Saving players" << std::endl;
m_env->saveLoadedPlayers();
infostream << "Server: Kicking players" << std::endl;
std::string kick_msg;
bool reconnect = false;
if (isShutdownRequested()) {
reconnect = m_shutdown_state.should_reconnect;
kick_msg = m_shutdown_state.message;
}
if (kick_msg.empty()) {
kick_msg = g_settings->get("kick_msg_shutdown");
}
m_env->kickAllPlayers(SERVER_ACCESSDENIED_SHUTDOWN,
kick_msg, reconnect);
}
actionstream << "Server: Shutting down" << std::endl;
// Do this before stopping the server in case mapgen callbacks need to access
// server-controlled resources (like ModStorages). Also do them before
// shutdown callbacks since they may modify state that is finalized in a
// callback.
if (m_emerge)
m_emerge->stopThreads();
if (m_env) {
MutexAutoLock envlock(m_env_mutex);
// Execute script shutdown hooks
infostream << "Executing shutdown hooks" << std::endl;
m_script->on_shutdown();
infostream << "Server: Saving environment metadata" << std::endl;
m_env->saveMeta();
}
// Stop threads
if (m_thread) {
stop();
delete m_thread;
}
// Delete things in the reverse order of creation
delete m_emerge;
delete m_env;
delete m_rollback;
delete m_banmanager;
delete m_itemdef;
delete m_nodedef;
delete m_craftdef;
// Deinitialize scripting
infostream << "Server: Deinitializing scripting" << std::endl;
delete m_script;
// Delete detached inventories
for (auto &detached_inventory : m_detached_inventories) {
delete detached_inventory.second;
}
}
void Server::init()
{
infostream << "Server created for gameid \"" << m_gamespec.id << "\"";
if (m_simple_singleplayer_mode)
infostream << " in simple singleplayer mode" << std::endl;
else
infostream << std::endl;
infostream << "- world: " << m_path_world << std::endl;
infostream << "- game: " << m_gamespec.path << std::endl;
2012-03-11 03:15:45 +01:00
// Create world if it doesn't exist
if (!loadGameConfAndInitWorld(m_path_world, m_gamespec))
throw ServerError("Failed to initialize world");
// Create server thread
m_thread = new ServerThread(this);
// Create emerge manager
2013-04-06 17:19:59 +02:00
m_emerge = new EmergeManager(this);
// Create ban manager
2014-06-26 02:28:41 +02:00
std::string ban_path = m_path_world + DIR_DELIM "ipban.txt";
m_banmanager = new BanManager(ban_path);
m_modmgr = std::unique_ptr<ServerModManager>(new ServerModManager(m_path_world));
std::vector<ModSpec> unsatisfied_mods = m_modmgr->getUnsatisfiedMods();
Basic support for configuring which mods to load for each world settings.h: added function to return all keys used in settings, and a function to remove a setting mods.{h,cpp}: added class ModConfiguration that represents a subset of the installed mods. server.{h,cpp}: server does not load add-on mods that are disabled in the world.mt file. mods are disabled by a setting of the form "load_mod_<modname> = false". if no load_mod_<modname> = ... setting is found, the mod is loaded anyways for backwards compatibilty. server also complains to errorstream about mods with unstatisfied dependencies and about mods that are not installed. guiConfigureWorld.{h,cpp}: shows a treeview of installed add-on mods and modpacks with little icons in front of their name indicating their status: a checkmark for enabled mods, a cross for disabled mods, a question mark for "new" mods Mods can be enabled/disabled by a checkbox. Mods also show a list of dependencies and reverse dependencies. double-click on a mod in dependency or reverse dependency listbox selects the corresponding mod. Enabling a mod also enables all its dependencies. Disabling a mod also disables all its reverse dependencies. For modpacks, show buttons to enable/disable all mods (recursively, including their dependencies) in it. Button "Save" saves the current settings to the world.mt file and returns to the main menu. Button "Cancel" returns to main menu without saving. basic keyboard controls (if the proper widget has keyboard focus): up/down: scroll through tree of mods left/right: collaps/expand a modpack space: enable/disable the selected mod
2012-12-08 18:10:54 +01:00
// complain about mods with unsatisfied dependencies
if (!m_modmgr->isConsistent()) {
m_modmgr->printUnsatisfiedModsError();
Basic support for configuring which mods to load for each world settings.h: added function to return all keys used in settings, and a function to remove a setting mods.{h,cpp}: added class ModConfiguration that represents a subset of the installed mods. server.{h,cpp}: server does not load add-on mods that are disabled in the world.mt file. mods are disabled by a setting of the form "load_mod_<modname> = false". if no load_mod_<modname> = ... setting is found, the mod is loaded anyways for backwards compatibilty. server also complains to errorstream about mods with unstatisfied dependencies and about mods that are not installed. guiConfigureWorld.{h,cpp}: shows a treeview of installed add-on mods and modpacks with little icons in front of their name indicating their status: a checkmark for enabled mods, a cross for disabled mods, a question mark for "new" mods Mods can be enabled/disabled by a checkbox. Mods also show a list of dependencies and reverse dependencies. double-click on a mod in dependency or reverse dependency listbox selects the corresponding mod. Enabling a mod also enables all its dependencies. Disabling a mod also disables all its reverse dependencies. For modpacks, show buttons to enable/disable all mods (recursively, including their dependencies) in it. Button "Save" saves the current settings to the world.mt file and returns to the main menu. Button "Cancel" returns to main menu without saving. basic keyboard controls (if the proper widget has keyboard focus): up/down: scroll through tree of mods left/right: collaps/expand a modpack space: enable/disable the selected mod
2012-12-08 18:10:54 +01:00
}
//lock environment
MutexAutoLock envlock(m_env_mutex);
2012-03-10 14:56:24 +01:00
2014-12-30 18:30:14 +01:00
// Create the Map (loads map_meta.txt, overriding configured mapgen params)
ServerMap *servermap = new ServerMap(m_path_world, this, m_emerge);
2014-12-30 18:30:14 +01:00
2011-11-11 18:33:17 +01:00
// Initialize scripting
infostream << "Server: Initializing Lua" << std::endl;
m_script = new ServerScripting(this);
m_script->loadMod(getBuiltinLuaPath() + DIR_DELIM "init.lua", BUILTIN_MOD_NAME);
2014-04-27 23:55:49 +02:00
m_modmgr->loadMods(m_script);
// Read Textures and calculate sha1 sums
2012-03-25 10:50:29 +02:00
fillMediaCache();
// Apply item aliases in the node definition manager
m_nodedef->updateAliases(m_itemdef);
2015-03-30 12:55:29 +02:00
// Apply texture overrides from texturepack/override.txt
std::vector<std::string> paths;
fs::GetRecursiveDirs(paths, g_settings->get("texture_path"));
fs::GetRecursiveDirs(paths, m_gamespec.path + DIR_DELIM + "textures");
for (const std::string &path : paths)
m_nodedef->applyTextureOverrides(path + DIR_DELIM + "override.txt");
2015-03-30 12:55:29 +02:00
m_nodedef->setNodeRegistrationStatus(true);
// Perform pending node name resolutions
m_nodedef->runNodeResolveCallbacks();
Nodebox: Allow nodeboxes to "connect" We introduce a new nodebox type "connected", and allow these nodes to have optional nodeboxes that connect it to other connecting nodeboxes. This is all done at scenedraw time in the client. The client will inspect the surrounding nodes and if they are to be connected to, it will draw the appropriate connecting nodeboxes to make those connections. In the node_box definition, we have to specify separate nodeboxes for each valid connection. This allows us to make nodes that connect only horizontally (the common case) by providing optional nodeboxes for +x, -x, +z, -z directions. Or this allows us to make wires that can connect up and down, by providing nodeboxes that connect it up and down (+y, -y) as well. The optional nodeboxes can be arrays. They are named "connect_top, "connect_bottom", "connect_front", "connect_left", "connect_back" and "connect_right". Here, "front" means the south facing side of the node that has facedir = 0. Additionally, a "fixed" nodebox list present will always be drawn, so one can make a central post, for instance. This "fixed" nodebox can be omitted, or it can be an array of nodeboxes. Collision boxes are also updated in exactly the same fashion, which allows you to walk over the upper extremities of the individual node boxes, or stand really close to them. You can also walk up node noxes that are small in height, all as expected, and unlike the NDT_FENCELIKE nodes. I've posted a screenshot demonstrating the flexibility at http://i.imgur.com/zaJq8jo.png In the screenshot, all connecting nodes are of this new subtype. Transparent textures render incorrectly, Which I don't think is related to this text, as other nodeboxes also have issues with this. A protocol bump is performed in order to be able to send older clients a nodeblock that is usable for them. In order to avoid abuse of users we send older clients a "full-size" node, so that it's impossible for them to try and walk through a fence or wall that's created in this fashion. This was tested with a pre-bump client connected against a server running the new protocol. These nodes connect to other nodes, and you can select which ones those are by specifying node names (or group names) in the connects_to string array: connects_to = { "group:fence", "default:wood" } By default, nodes do not connect to anything, allowing you to create nodes that always have to be paired in order to connect. lua_api.txt is updated to reflect the extension to the node_box API. Example lua code needed to generate these nodes can be found here: https://gist.github.com/sofar/b381c8c192c8e53e6062
2016-02-25 09:16:31 +01:00
// unmap node names for connected nodeboxes
m_nodedef->mapNodeboxConnections();
// init the recipe hashes to speed up crafting
m_craftdef->initHashes(this);
// Initialize Environment
m_env = new ServerEnvironment(servermap, m_script, this, m_path_world);
m_clients.setEnv(m_env);
if (!servermap->settings_mgr.makeMapgenParams())
FATAL_ERROR("Couldn't create any mapgen type");
// Initialize mapgens
m_emerge->initMapgens(servermap->getMapgenParams());
if (g_settings->getBool("enable_rollback_recording")) {
// Create rollback manager
m_rollback = new RollbackManager(m_path_world, this);
}
2011-11-12 01:25:30 +01:00
// Give environment reference to scripting api
m_script->initializeEnvironment(m_env);
// Register us to receive map edit events
servermap->addEventReceiver(this);
2011-02-23 01:49:57 +01:00
m_env->loadMeta();
2013-02-24 15:39:07 +01:00
m_liquid_transform_every = g_settings->getFloat("liquid_update");
m_max_chatmessage_length = g_settings->getU16("chat_message_max_size");
m_csm_restriction_flags = g_settings->getU64("csm_restriction_flags");
m_csm_restriction_noderange = g_settings->getU32("csm_restriction_noderange");
2010-11-27 00:02:21 +01:00
}
void Server::start()
2010-11-27 00:02:21 +01:00
{
infostream << "Starting server on " << m_bind_addr.serializeString()
<< "..." << std::endl;
2010-11-27 00:02:21 +01:00
// Stop thread if already running
m_thread->stop();
2010-11-27 00:02:21 +01:00
// Initialize connection
m_con->SetTimeoutMs(30);
m_con->Serve(m_bind_addr);
2010-11-27 00:02:21 +01:00
// Start thread
m_thread->start();
2012-03-11 03:15:45 +01:00
// ASCII art for the win!
std::cerr
<< " .__ __ __ " << std::endl
<< " _____ |__| ____ _____/ |_ ____ _______/ |_ " << std::endl
<< " / \\| |/ \\_/ __ \\ __\\/ __ \\ / ___/\\ __\\" << std::endl
<< "| Y Y \\ | | \\ ___/| | \\ ___/ \\___ \\ | | " << std::endl
<< "|__|_| /__|___| /\\___ >__| \\___ >____ > |__| " << std::endl
<< " \\/ \\/ \\/ \\/ \\/ " << std::endl;
actionstream << "World at [" << m_path_world << "]" << std::endl;
actionstream << "Server for gameid=\"" << m_gamespec.id
<< "\" listening on " << m_bind_addr.serializeString() << ":"
<< m_bind_addr.getPort() << "." << std::endl;
2010-11-27 00:02:21 +01:00
}
void Server::stop()
{
infostream<<"Server: Stopping and waiting threads"<<std::endl;
2010-11-27 00:02:21 +01:00
// Stop threads (set run=false first so both start stopping)
m_thread->stop();
//m_emergethread.setRun(false);
m_thread->wait();
//m_emergethread.stop();
infostream<<"Server: Threads stopped"<<std::endl;
2010-11-27 00:02:21 +01:00
}
void Server::step(float dtime)
{
// Limit a bit
if (dtime > 2.0)
2010-11-27 00:02:21 +01:00
dtime = 2.0;
{
MutexAutoLock lock(m_step_dtime_mutex);
2010-11-27 00:02:21 +01:00
m_step_dtime += dtime;
}
// Throw if fatal error occurred in thread
std::string async_err = m_async_fatal_error.get();
if (!async_err.empty()) {
if (!m_simple_singleplayer_mode) {
m_env->kickAllPlayers(SERVER_ACCESSDENIED_CRASH,
g_settings->get("kick_msg_crash"),
g_settings->getBool("ask_reconnect_on_crash"));
}
throw ServerError("AsyncErr: " + async_err);
}
2010-11-27 00:02:21 +01:00
}
void Server::AsyncRunStep(bool initial_step)
2010-11-27 00:02:21 +01:00
{
g_profiler->add("Server::AsyncRunStep (num)", 1);
2010-11-27 00:02:21 +01:00
float dtime;
{
MutexAutoLock lock1(m_step_dtime_mutex);
2010-11-27 00:02:21 +01:00
dtime = m_step_dtime;
}
{
// Send blocks to clients
SendBlocks(dtime);
}
if((dtime < 0.001) && !initial_step)
2010-12-13 20:32:35 +01:00
return;
g_profiler->add("Server::AsyncRunStep with dtime (num)", 1);
//infostream<<"Server steps "<<dtime<<std::endl;
//infostream<<"Server::AsyncRunStep(): dtime="<<dtime<<std::endl;
2010-12-13 20:32:35 +01:00
{
MutexAutoLock lock1(m_step_dtime_mutex);
2010-12-19 15:51:45 +01:00
m_step_dtime -= dtime;
2010-12-13 20:32:35 +01:00
}
/*
Update uptime
*/
{
m_uptime.set(m_uptime.get() + dtime);
}
handlePeerChanges();
/*
Update time of day and overall game time
*/
m_env->setTimeOfDaySpeed(g_settings->getFloat("time_speed"));
/*
Send to clients at constant intervals
*/
m_time_of_day_send_timer -= dtime;
if(m_time_of_day_send_timer < 0.0) {
m_time_of_day_send_timer = g_settings->getFloat("time_send_interval");
u16 time = m_env->getTimeOfDay();
float time_speed = g_settings->getFloat("time_speed");
SendTimeOfDay(PEER_ID_INEXISTENT, time, time_speed);
}
2010-12-13 20:32:35 +01:00
2010-11-27 00:02:21 +01:00
{
MutexAutoLock lock(m_env_mutex);
2013-08-03 22:16:37 +02:00
// Figure out and report maximum lag to environment
float max_lag = m_env->getMaxLagEstimate();
max_lag *= 0.9998; // Decrease slowly (about half per 5 minutes)
if(dtime > max_lag){
if(dtime > 0.1 && dtime > max_lag * 2.0)
infostream<<"Server: Maximum lag peaked to "<<dtime
<<" s"<<std::endl;
max_lag = dtime;
}
m_env->reportMaxLagEstimate(max_lag);
// Step environment
ScopeProfiler sp(g_profiler, "SEnv step");
ScopeProfiler sp2(g_profiler, "SEnv step avg", SPT_AVG);
2011-11-11 18:33:17 +01:00
m_env->step(dtime);
2010-11-27 00:02:21 +01:00
}
2014-12-12 09:06:36 +01:00
static const float map_timer_and_unload_dtime = 2.92;
if(m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime))
{
MutexAutoLock lock(m_env_mutex);
// Run Map's timers and unload unused data
2011-10-12 12:53:38 +02:00
ScopeProfiler sp(g_profiler, "Server: map timer and unload");
2011-11-11 18:33:17 +01:00
m_env->getMap().timerUpdate(map_timer_and_unload_dtime,
g_settings->getFloat("server_unload_unused_data_timeout"),
U32_MAX);
}
/*
Listen to the admin chat, if available
*/
if (m_admin_chat) {
if (!m_admin_chat->command_queue.empty()) {
MutexAutoLock lock(m_env_mutex);
while (!m_admin_chat->command_queue.empty()) {
ChatEvent *evt = m_admin_chat->command_queue.pop_frontNoEx();
handleChatInterfaceEvent(evt);
delete evt;
}
}
m_admin_chat->outgoing_queue.push_back(
new ChatEventTimeInfo(m_env->getGameTime(), m_env->getTimeOfDay()));
}
2010-11-27 00:02:21 +01:00
/*
Do background stuff
*/
/* Transform liquids */
m_liquid_transform_timer += dtime;
2013-02-24 15:39:07 +01:00
if(m_liquid_transform_timer >= m_liquid_transform_every)
{
2013-02-24 15:39:07 +01:00
m_liquid_transform_timer -= m_liquid_transform_every;
MutexAutoLock lock(m_env_mutex);
2011-10-12 12:53:38 +02:00
ScopeProfiler sp(g_profiler, "Server: liquid transform");
2012-12-20 18:19:49 +01:00
std::map<v3s16, MapBlock*> modified_blocks;
m_env->getMap().transformLiquids(modified_blocks, m_env);
/*
Set the modified blocks unsent for all the clients
*/
if (!modified_blocks.empty()) {
SetBlocksNotSent(modified_blocks);
2010-11-27 00:02:21 +01:00
}
}
m_clients.step(dtime);
2013-02-21 23:00:44 +01:00
m_lag += (m_lag > dtime ? -1 : 1) * dtime/100;
2013-02-21 23:00:44 +01:00
#if USE_CURL
// send masterserver announce
{
float &counter = m_masterserver_timer;
if (!isSingleplayer() && (!counter || counter >= 300.0) &&
g_settings->getBool("server_announce")) {
ServerList::sendAnnounce(counter ? ServerList::AA_UPDATE :
ServerList::AA_START,
2015-01-21 20:32:12 +01:00
m_bind_addr.getPort(),
m_clients.getPlayerNames(),
m_uptime.get(),
m_env->getGameTime(),
m_lag,
m_gamespec.id,
Mapgen::getMapgenName(m_emerge->mgparams->mgtype),
m_modmgr->getMods(),
m_dedicated);
2013-02-21 23:00:44 +01:00
counter = 0.01;
}
counter += dtime;
}
#endif
/*
Check added and deleted active objects
*/
{
//infostream<<"Server: Checking added and deleted active objects"<<std::endl;
MutexAutoLock envlock(m_env_mutex);
m_clients.lock();
const RemoteClientMap &clients = m_clients.getClientList();
ScopeProfiler sp(g_profiler, "Server: checking added and deleted objs");
2011-02-23 01:49:57 +01:00
// Radius inside which objects are active
static thread_local const s16 radius =
2015-09-02 21:21:55 +02:00
g_settings->getS16("active_object_send_range_blocks") * MAP_BLOCKSIZE;
// Radius inside which players are active
static thread_local const bool is_transfer_limited =
2015-09-02 21:21:55 +02:00
g_settings->exists("unlimited_player_transfer_distance") &&
!g_settings->getBool("unlimited_player_transfer_distance");
static thread_local const s16 player_transfer_dist =
g_settings->getS16("player_transfer_distance") * MAP_BLOCKSIZE;
2015-09-02 21:21:55 +02:00
s16 player_radius = player_transfer_dist;
if (player_radius == 0 && is_transfer_limited)
player_radius = radius;
for (const auto &client_it : clients) {
RemoteClient *client = client_it.second;
// If definitions and textures have not been sent, don't
// send objects either
if (client->getState() < CS_DefinitionsSent)
continue;
RemotePlayer *player = m_env->getPlayer(client->peer_id);
if (!player) {
// This can happen if the client timeouts somehow
2011-02-23 01:49:57 +01:00
continue;
}
PlayerSAO *playersao = player->getPlayerSAO();
if (!playersao)
continue;
s16 my_radius = MYMIN(radius, playersao->getWantedRange() * MAP_BLOCKSIZE);
if (my_radius <= 0) my_radius = radius;
//infostream << "Server: Active Radius " << my_radius << std::endl;
std::queue<u16> removed_objects;
std::queue<u16> added_objects;
m_env->getRemovedActiveObjects(playersao, my_radius, player_radius,
client->m_known_objects, removed_objects);
m_env->getAddedActiveObjects(playersao, my_radius, player_radius,
client->m_known_objects, added_objects);
// Ignore if nothing happened
if (removed_objects.empty() && added_objects.empty()) {
continue;
}
std::string data_buffer;
char buf[4];
// Handle removed objects
writeU16((u8*)buf, removed_objects.size());
data_buffer.append(buf, 2);
while (!removed_objects.empty()) {
// Get object
u16 id = removed_objects.front();
2011-11-11 18:33:17 +01:00
ServerActiveObject* obj = m_env->getActiveObject(id);
// Add to data buffer for sending
2012-12-20 18:19:49 +01:00
writeU16((u8*)buf, id);
data_buffer.append(buf, 2);
// Remove from known objects
2012-12-20 18:19:49 +01:00
client->m_known_objects.erase(id);
if(obj && obj->m_known_by_count > 0)
obj->m_known_by_count--;
removed_objects.pop();
}
// Handle added objects
writeU16((u8*)buf, added_objects.size());
data_buffer.append(buf, 2);
while (!added_objects.empty()) {
// Get object
u16 id = added_objects.front();
2011-11-11 18:33:17 +01:00
ServerActiveObject* obj = m_env->getActiveObject(id);
// Get object type
u8 type = ACTIVEOBJECT_TYPE_INVALID;
if (!obj)
warningstream << FUNCTION_NAME << ": NULL object" << std::endl;
else
type = obj->getSendType();
// Add to data buffer for sending
writeU16((u8*)buf, id);
data_buffer.append(buf, 2);
writeU8((u8*)buf, type);
data_buffer.append(buf, 1);
if(obj)
data_buffer.append(serializeLongString(
obj->getClientInitializationData(client->net_proto_version)));
else
data_buffer.append(serializeLongString(""));
// Add to known objects
2012-12-20 18:19:49 +01:00
client->m_known_objects.insert(id);
if(obj)
obj->m_known_by_count++;
added_objects.pop();
}
u32 pktSize = SendActiveObjectRemoveAdd(client->peer_id, data_buffer);
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
verbosestream << "Server: Sent object remove/add: "
<< removed_objects.size() << " removed, "
<< added_objects.size() << " added, "
<< "packet size is " << pktSize << std::endl;
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
}
m_clients.unlock();
m_mod_storage_save_timer -= dtime;
if (m_mod_storage_save_timer <= 0.0f) {
infostream << "Saving registered mod storages." << std::endl;
m_mod_storage_save_timer = g_settings->getFloat("server_map_save_interval");
for (std::unordered_map<std::string, ModMetadata *>::const_iterator
it = m_mod_storages.begin(); it != m_mod_storages.end(); ++it) {
if (it->second->isModified()) {
it->second->save(getModStoragePath());
}
}
}
}
/*
Send object messages
*/
{
MutexAutoLock envlock(m_env_mutex);
ScopeProfiler sp(g_profiler, "Server: sending object messages");
// Key = object id
// Value = data sent by object
std::unordered_map<u16, std::vector<ActiveObjectMessage>*> buffered_messages;
// Get active object messages from environment
for(;;) {
2011-11-11 18:33:17 +01:00
ActiveObjectMessage aom = m_env->getActiveObjectMessage();
if (aom.id == 0)
break;
std::vector<ActiveObjectMessage>* message_list = nullptr;
std::unordered_map<u16, std::vector<ActiveObjectMessage>* >::iterator n;
n = buffered_messages.find(aom.id);
if (n == buffered_messages.end()) {
message_list = new std::vector<ActiveObjectMessage>;
2012-12-20 18:19:49 +01:00
buffered_messages[aom.id] = message_list;
}
else {
2012-12-20 18:19:49 +01:00
message_list = n->second;
}
message_list->push_back(aom);
}
m_clients.lock();
const RemoteClientMap &clients = m_clients.getClientList();
// Route data to every client
for (const auto &client_it : clients) {
RemoteClient *client = client_it.second;
std::string reliable_data;
std::string unreliable_data;
// Go through all objects in message buffer
for (const auto &buffered_message : buffered_messages) {
// If object is not known by client, skip it
u16 id = buffered_message.first;
if (client->m_known_objects.find(id) == client->m_known_objects.end())
continue;
// Get message list of object
std::vector<ActiveObjectMessage>* list = buffered_message.second;
// Go through every message
for (const ActiveObjectMessage &aom : *list) {
// Compose the full new data with header
std::string new_data;
// Add object id
char buf[2];
writeU16((u8*)&buf[0], aom.id);
new_data.append(buf, 2);
// Add data
new_data += serializeString(aom.datastring);
// Add data to buffer
if (aom.reliable)
reliable_data += new_data;
else
unreliable_data += new_data;
}
}
/*
reliable_data and unreliable_data are now ready.
Send them.
*/
if (!reliable_data.empty()) {
SendActiveObjectMessages(client->peer_id, reliable_data);
}
if (!unreliable_data.empty()) {
SendActiveObjectMessages(client->peer_id, unreliable_data, false);
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
}
}
m_clients.unlock();
// Clear buffered_messages
for (auto &buffered_message : buffered_messages) {
delete buffered_message.second;
2010-11-27 00:02:21 +01:00
}
}
2010-11-27 00:02:21 +01:00
2011-02-23 01:49:57 +01:00
/*
Send queued-for-sending map edit events.
*/
{
// We will be accessing the environment
MutexAutoLock lock(m_env_mutex);
// Don't send too many at a time
//u32 count = 0;
// Single change sending is disabled if queue size is not small
bool disable_single_change_sending = false;
if(m_unsent_map_edit_queue.size() >= 4)
disable_single_change_sending = true;
2012-03-11 03:15:45 +01:00
int event_count = m_unsent_map_edit_queue.size();
// We'll log the amount of each
Profiler prof;
std::list<v3s16> node_meta_updates;
while (!m_unsent_map_edit_queue.empty()) {
MapEditEvent* event = m_unsent_map_edit_queue.front();
m_unsent_map_edit_queue.pop();
// Players far away from the change are stored here.
// Instead of sending the changes, MapBlocks are set not sent
// for them.
std::unordered_set<u16> far_players;
2011-02-23 01:49:57 +01:00
switch (event->type) {
case MEET_ADDNODE:
case MEET_SWAPNODE:
prof.add("MEET_ADDNODE", 1);
sendAddNode(event->p, event->n, &far_players,
disable_single_change_sending ? 5 : 30,
event->type == MEET_ADDNODE);
break;
case MEET_REMOVENODE:
prof.add("MEET_REMOVENODE", 1);
sendRemoveNode(event->p, &far_players,
disable_single_change_sending ? 5 : 30);
break;
case MEET_BLOCK_NODE_METADATA_CHANGED: {
verbosestream << "Server: MEET_BLOCK_NODE_METADATA_CHANGED" << std::endl;
prof.add("MEET_BLOCK_NODE_METADATA_CHANGED", 1);
if (!event->is_private_change) {
// Don't send the change yet. Collect them to eliminate dupes.
node_meta_updates.remove(event->p);
node_meta_updates.push_back(event->p);
}
if (MapBlock *block = m_env->getMap().getBlockNoCreateNoEx(
getNodeBlockPos(event->p))) {
block->raiseModified(MOD_STATE_WRITE_NEEDED,
MOD_REASON_REPORT_META_CHANGE);
}
break;
}
case MEET_OTHER:
infostream << "Server: MEET_OTHER" << std::endl;
prof.add("MEET_OTHER", 1);
for (const v3s16 &modified_block : event->modified_blocks) {
m_clients.markBlockposAsNotSent(modified_block);
2011-08-16 11:23:19 +02:00
}
break;
default:
prof.add("unknown", 1);
warningstream << "Server: Unknown MapEditEvent "
<< ((u32)event->type) << std::endl;
break;
2011-02-23 01:49:57 +01:00
}
/*
Set blocks not sent to far players
*/
if (!far_players.empty()) {
// Convert list format to that wanted by SetBlocksNotSent
2012-12-20 18:19:49 +01:00
std::map<v3s16, MapBlock*> modified_blocks2;
for (const v3s16 &modified_block : event->modified_blocks) {
modified_blocks2[modified_block] =
m_env->getMap().getBlockNoCreateNoEx(modified_block);
}
// Set blocks not sent
for (const u16 far_player : far_players) {
if (RemoteClient *client = getClient(far_player))
client->SetBlocksNotSent(modified_blocks2);
}
}
2011-02-23 01:49:57 +01:00
delete event;
}
if (event_count >= 5) {
infostream << "Server: MapEditEvents:" << std::endl;
prof.print(infostream);
} else if (event_count != 0) {
verbosestream << "Server: MapEditEvents:" << std::endl;
2012-03-11 03:15:45 +01:00
prof.print(verbosestream);
}
// Send all metadata updates
if (node_meta_updates.size())
sendMetadataChanged(node_meta_updates);
2011-02-23 01:49:57 +01:00
}
2011-02-05 13:55:16 +01:00
/*
Trigger emergethread (it somehow gets to a non-triggered but
bysy state sometimes)
*/
{
2010-12-19 15:51:45 +01:00
float &counter = m_emergethread_trigger_timer;
counter += dtime;
2015-09-02 21:21:55 +02:00
if (counter >= 2.0) {
counter = 0.0;
m_emerge->startThreads();
}
}
2010-11-27 00:02:21 +01:00
// Save map, players and auth stuff
2010-11-27 00:02:21 +01:00
{
2010-12-19 15:51:45 +01:00
float &counter = m_savemap_timer;
2010-11-27 00:02:21 +01:00
counter += dtime;
static thread_local const float save_interval =
2015-09-02 21:21:55 +02:00
g_settings->getFloat("server_map_save_interval");
if (counter >= save_interval) {
2010-11-27 00:02:21 +01:00
counter = 0.0;
MutexAutoLock lock(m_env_mutex);
2010-11-27 00:02:21 +01:00
2011-10-12 12:53:38 +02:00
ScopeProfiler sp(g_profiler, "Server: saving stuff");
// Save ban file
if (m_banmanager->isModified()) {
m_banmanager->save();
}
// Save changed parts of map
m_env->getMap().save(MOD_STATE_WRITE_NEEDED);
// Save players
m_env->saveLoadedPlayers();
// Save environment metadata
m_env->saveMeta();
2010-11-27 00:02:21 +01:00
}
}
m_shutdown_state.tick(dtime, this);
2010-11-27 00:02:21 +01:00
}
void Server::Receive()
{
session_t peer_id = 0;
try {
NetworkPacket pkt;
m_con->Receive(&pkt);
peer_id = pkt.getPeerId();
ProcessData(&pkt);
} catch (const con::InvalidIncomingDataException &e) {
infostream << "Server::Receive(): InvalidIncomingDataException: what()="
<< e.what() << std::endl;
} catch (const SerializationError &e) {
infostream << "Server::Receive(): SerializationError: what()="
<< e.what() << std::endl;
} catch (const ClientStateError &e) {
errorstream << "ProcessData: peer=" << peer_id << e.what() << std::endl;
DenyAccess_Legacy(peer_id, L"Your client sent something server didn't expect."
L"Try reconnecting or updating your client");
} catch (const con::PeerNotFoundException &e) {
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
// Do nothing
}
}
2011-11-29 16:15:18 +01:00
PlayerSAO* Server::StageTwoClientInit(session_t peer_id)
{
std::string playername;
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
PlayerSAO *playersao = NULL;
m_clients.lock();
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
try {
RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_InitDone);
if (client) {
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
playername = client->getName();
playersao = emergePlayer(playername.c_str(), peer_id, client->net_proto_version);
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
}
} catch (std::exception &e) {
m_clients.unlock();
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
throw;
}
m_clients.unlock();
RemotePlayer *player = m_env->getPlayer(playername.c_str());
2011-11-29 16:15:18 +01:00
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
// If failed, cancel
if (!playersao || !player) {
if (player && player->getPeerId() != PEER_ID_INEXISTENT) {
actionstream << "Server: Failed to emerge player \"" << playername
<< "\" (player allocated to an another client)" << std::endl;
DenyAccess_Legacy(peer_id, L"Another client is connected with this "
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
L"name. If your client closed unexpectedly, try again in "
L"a minute.");
} else {
errorstream << "Server: " << playername << ": Failed to emerge player"
<< std::endl;
DenyAccess_Legacy(peer_id, L"Could not allocate player.");
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
}
return NULL;
}
2011-11-29 16:15:18 +01:00
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
/*
Send complete position information
*/
SendMovePlayer(peer_id);
2011-11-29 16:15:18 +01:00
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
// Send privileges
SendPlayerPrivileges(peer_id);
2011-05-23 21:40:25 +02:00
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
// Send inventory formspec
SendPlayerInventoryFormspec(peer_id);
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
// Send inventory
SendInventory(playersao);
2011-11-29 16:15:18 +01:00
// Send HP or death screen
if (playersao->isDead())
SendDeathscreen(peer_id, false, v3f(0,0,0));
else
SendPlayerHPOrDie(playersao,
PlayerHPChangeReason(PlayerHPChangeReason::SET_HP));
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
// Send Breath
SendPlayerBreath(playersao);
Address addr = getPeerAddress(player->getPeerId());
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
std::string ip_str = addr.serializeString();
actionstream<<player->getName() <<" [" << ip_str << "] joins game. " << std::endl;
/*
Print out action
*/
{
const std::vector<std::string> &names = m_clients.getPlayerNames();
actionstream << player->getName() << " joins game. List of players: ";
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
for (const std::string &name : names) {
actionstream << name << " ";
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
}
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
actionstream << player->getName() <<std::endl;
}
return playersao;
}
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
inline void Server::handleCommand(NetworkPacket* pkt)
{
const ToServerCommandHandler& opHandle = toServerCommandTable[pkt->getCommand()];
(this->*opHandle.handler)(pkt);
}
void Server::ProcessData(NetworkPacket *pkt)
{
// Environment is locked first.
MutexAutoLock envlock(m_env_mutex);
ScopeProfiler sp(g_profiler, "Server::ProcessData");
u32 peer_id = pkt->getPeerId();
try {
Address address = getPeerAddress(peer_id);
std::string addr_s = address.serializeString();
if(m_banmanager->isIpBanned(addr_s)) {
std::string ban_name = m_banmanager->getBanName(addr_s);
infostream << "Server: A banned client tried to connect from "
<< addr_s << "; banned name was "
<< ban_name << std::endl;
// This actually doesn't seem to transfer to the client
DenyAccess_Legacy(peer_id, L"Your ip is banned. Banned name was "
+ utf8_to_wide(ban_name));
return;
2012-03-24 18:01:26 +01:00
}
}
catch(con::PeerNotFoundException &e) {
/*
* no peer for this packet found
* most common reason is peer timeout, e.g. peer didn't
* respond for some time, your server was overloaded or
* things like that.
*/
infostream << "Server::ProcessData(): Canceling: peer "
<< peer_id << " not found" << std::endl;
return;
}
try {
ToServerCommand command = (ToServerCommand) pkt->getCommand();
// Command must be handled into ToServerCommandHandler
if (command >= TOSERVER_NUM_MSG_TYPES) {
infostream << "Server: Ignoring unknown command "
<< command << std::endl;
2015-06-24 22:45:52 +02:00
return;
}
if (toServerCommandTable[command].state == TOSERVER_STATE_NOT_CONNECTED) {
handleCommand(pkt);
return;
}
u8 peer_ser_ver = getClient(peer_id, CS_InitDone)->serialization_version;
if(peer_ser_ver == SER_FMT_VER_INVALID) {
errorstream << "Server::ProcessData(): Cancelling: Peer"
" serialization format invalid or not initialized."
" Skipping incoming command=" << command << std::endl;
return;
}
/* Handle commands related to client startup */
if (toServerCommandTable[command].state == TOSERVER_STATE_STARTUP) {
handleCommand(pkt);
return;
}
if (m_clients.getClientState(peer_id) < CS_Active) {
if (command == TOSERVER_PLAYERPOS) return;
errorstream << "Got packet command: " << command << " for peer id "
<< peer_id << " but client isn't active yet. Dropping packet "
<< std::endl;
return;
}
handleCommand(pkt);
2015-05-08 06:51:03 +02:00
} catch (SendFailedException &e) {
errorstream << "Server::ProcessData(): SendFailedException: "
<< "what=" << e.what()
<< std::endl;
2015-05-08 06:51:03 +02:00
} catch (PacketError &e) {
actionstream << "Server::ProcessData(): PacketError: "
<< "what=" << e.what()
<< std::endl;
2010-11-27 00:02:21 +01:00
}
}
void Server::setTimeOfDay(u32 time)
{
m_env->setTimeOfDay(time);
m_time_of_day_send_timer = 0;
}
2011-02-23 01:49:57 +01:00
void Server::onMapEditEvent(MapEditEvent *event)
2010-11-27 00:02:21 +01:00
{
if (m_ignore_map_edit_events_area.contains(event->getArea()))
return;
2011-02-23 01:49:57 +01:00
MapEditEvent *e = event->clone();
m_unsent_map_edit_queue.push(e);
2010-11-27 00:02:21 +01:00
}
Inventory* Server::getInventory(const InventoryLocation &loc)
{
switch (loc.type) {
case InventoryLocation::UNDEFINED:
case InventoryLocation::CURRENT_PLAYER:
break;
case InventoryLocation::PLAYER:
{
RemotePlayer *player = m_env->getPlayer(loc.name.c_str());
if(!player)
return NULL;
PlayerSAO *playersao = player->getPlayerSAO();
if(!playersao)
return NULL;
return playersao->getInventory();
}
break;
case InventoryLocation::NODEMETA:
{
NodeMetadata *meta = m_env->getMap().getNodeMetadata(loc.p);
if(!meta)
return NULL;
return meta->getInventory();
}
break;
2012-07-24 19:57:17 +02:00
case InventoryLocation::DETACHED:
{
if(m_detached_inventories.count(loc.name) == 0)
return NULL;
return m_detached_inventories[loc.name];
}
break;
default:
sanity_check(false); // abort
break;
}
return NULL;
}
void Server::setInventoryModified(const InventoryLocation &loc, bool playerSend)
{
switch(loc.type){
case InventoryLocation::UNDEFINED:
break;
case InventoryLocation::PLAYER:
{
if (!playerSend)
return;
RemotePlayer *player = m_env->getPlayer(loc.name.c_str());
if (!player)
return;
PlayerSAO *playersao = player->getPlayerSAO();
if(!playersao)
return;
SendInventory(playersao);
}
break;
case InventoryLocation::NODEMETA:
{
MapEditEvent event;
event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
event.p = loc.p;
m_env->getMap().dispatchEvent(&event);
}
break;
2012-07-24 19:57:17 +02:00
case InventoryLocation::DETACHED:
{
sendDetachedInventory(loc.name,PEER_ID_INEXISTENT);
2012-07-24 19:57:17 +02:00
}
break;
default:
sanity_check(false); // abort
break;
}
}
2011-04-04 14:13:19 +02:00
void Server::SetBlocksNotSent(std::map<v3s16, MapBlock *>& block)
{
std::vector<session_t> clients = m_clients.getClientIDs();
m_clients.lock();
// Set the modified blocks unsent for all the clients
for (const session_t client_id : clients) {
if (RemoteClient *client = m_clients.lockedGetClientNoEx(client_id))
client->SetBlocksNotSent(block);
}
m_clients.unlock();
}
2010-11-27 00:02:21 +01:00
void Server::peerAdded(con::Peer *peer)
{
2012-03-11 03:15:45 +01:00
verbosestream<<"Server::peerAdded(): peer->id="
2010-11-27 00:02:21 +01:00
<<peer->id<<std::endl;
m_peer_change_queue.push(con::PeerChange(con::PEER_ADDED, peer->id, false));
2010-11-27 00:02:21 +01:00
}
void Server::deletingPeer(con::Peer *peer, bool timeout)
{
2012-03-11 03:15:45 +01:00
verbosestream<<"Server::deletingPeer(): peer->id="
2010-11-27 00:02:21 +01:00
<<peer->id<<", timeout="<<timeout<<std::endl;
m_clients.event(peer->id, CSE_Disconnect);
m_peer_change_queue.push(con::PeerChange(con::PEER_REMOVED, peer->id, timeout));
2010-11-27 00:02:21 +01:00
}
bool Server::getClientConInfo(session_t peer_id, con::rtt_stat_type type, float* retval)
{
*retval = m_con->getPeerStat(peer_id,type);
return *retval != -1;
}
bool Server::getClientInfo(
session_t peer_id,
ClientState* state,
u32* uptime,
u8* ser_vers,
u16* prot_vers,
u8* major,
u8* minor,
u8* patch,
std::string* vers_string
)
{
*state = m_clients.getClientState(peer_id);
m_clients.lock();
RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_Invalid);
if (!client) {
m_clients.unlock();
return false;
}
*uptime = client->uptime();
*ser_vers = client->serialization_version;
*prot_vers = client->net_proto_version;
*major = client->getMajor();
*minor = client->getMinor();
*patch = client->getPatch();
*vers_string = client->getPatch();
m_clients.unlock();
return true;
}
void Server::handlePeerChanges()
{
while(!m_peer_change_queue.empty())
{
con::PeerChange c = m_peer_change_queue.front();
m_peer_change_queue.pop();
verbosestream<<"Server: Handling peer change: "
<<"id="<<c.peer_id<<", timeout="<<c.timeout
<<std::endl;
switch(c.type)
{
case con::PEER_ADDED:
m_clients.CreateClient(c.peer_id);
break;
case con::PEER_REMOVED:
DeleteClient(c.peer_id, c.timeout?CDR_TIMEOUT:CDR_LEAVE);
break;
default:
FATAL_ERROR("Invalid peer change event received!");
break;
}
}
}
void Server::printToConsoleOnly(const std::string &text)
{
if (m_admin_chat) {
m_admin_chat->outgoing_queue.push_back(
new ChatEventChat("", utf8_to_wide(text)));
} else {
std::cout << text << std::endl;
}
}
void Server::Send(NetworkPacket *pkt)
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
{
Send(pkt->getPeerId(), pkt);
}
void Server::Send(session_t peer_id, NetworkPacket *pkt)
{
m_clients.send(peer_id,
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
clientCommandFactoryTable[pkt->getCommand()].channel,
pkt,
clientCommandFactoryTable[pkt->getCommand()].reliable);
}
void Server::SendMovement(session_t peer_id)
2013-02-08 21:54:01 +01:00
{
std::ostringstream os(std::ios_base::binary);
NetworkPacket pkt(TOCLIENT_MOVEMENT, 12 * sizeof(float), peer_id);
pkt << g_settings->getFloat("movement_acceleration_default");
pkt << g_settings->getFloat("movement_acceleration_air");
pkt << g_settings->getFloat("movement_acceleration_fast");
pkt << g_settings->getFloat("movement_speed_walk");
pkt << g_settings->getFloat("movement_speed_crouch");
pkt << g_settings->getFloat("movement_speed_fast");
pkt << g_settings->getFloat("movement_speed_climb");
pkt << g_settings->getFloat("movement_speed_jump");
pkt << g_settings->getFloat("movement_liquid_fluidity");
pkt << g_settings->getFloat("movement_liquid_fluidity_smooth");
pkt << g_settings->getFloat("movement_liquid_sink");
pkt << g_settings->getFloat("movement_gravity");
2013-02-08 21:54:01 +01:00
Send(&pkt);
2013-02-08 21:54:01 +01:00
}
void Server::SendPlayerHPOrDie(PlayerSAO *playersao, const PlayerHPChangeReason &reason)
2015-07-10 21:58:32 +02:00
{
if (!g_settings->getBool("enable_damage"))
return;
session_t peer_id = playersao->getPeerID();
2015-07-10 21:58:32 +02:00
bool is_alive = playersao->getHP() > 0;
if (is_alive)
SendPlayerHP(peer_id);
else
DiePlayer(peer_id, reason);
2015-07-10 21:58:32 +02:00
}
void Server::SendHP(session_t peer_id, u16 hp)
{
NetworkPacket pkt(TOCLIENT_HP, 1, peer_id);
pkt << hp;
Send(&pkt);
}
void Server::SendBreath(session_t peer_id, u16 breath)
{
NetworkPacket pkt(TOCLIENT_BREATH, 2, peer_id);
pkt << (u16) breath;
Send(&pkt);
}
void Server::SendAccessDenied(session_t peer_id, AccessDeniedCode reason,
const std::string &custom_reason, bool reconnect)
{
assert(reason < SERVER_ACCESSDENIED_MAX);
NetworkPacket pkt(TOCLIENT_ACCESS_DENIED, 1, peer_id);
pkt << (u8)reason;
if (reason == SERVER_ACCESSDENIED_CUSTOM_STRING)
pkt << custom_reason;
else if (reason == SERVER_ACCESSDENIED_SHUTDOWN ||
reason == SERVER_ACCESSDENIED_CRASH)
pkt << custom_reason << (u8)reconnect;
Send(&pkt);
}
void Server::SendAccessDenied_Legacy(session_t peer_id,const std::wstring &reason)
{
NetworkPacket pkt(TOCLIENT_ACCESS_DENIED_LEGACY, 0, peer_id);
pkt << reason;
Send(&pkt);
}
void Server::SendDeathscreen(session_t peer_id, bool set_camera_point_target,
v3f camera_point_target)
2011-10-15 13:46:59 +02:00
{
NetworkPacket pkt(TOCLIENT_DEATHSCREEN, 1 + sizeof(v3f), peer_id);
pkt << set_camera_point_target << camera_point_target;
Send(&pkt);
2011-10-15 13:46:59 +02:00
}
void Server::SendItemDef(session_t peer_id,
IItemDefManager *itemdef, u16 protocol_version)
2011-11-15 00:00:16 +01:00
{
NetworkPacket pkt(TOCLIENT_ITEMDEF, 0, peer_id);
2011-11-15 00:00:16 +01:00
/*
u16 command
u32 length of the next item
zlib-compressed serialized ItemDefManager
2011-11-15 00:00:16 +01:00
*/
std::ostringstream tmp_os(std::ios::binary);
itemdef->serialize(tmp_os, protocol_version);
std::ostringstream tmp_os2(std::ios::binary);
compressZlib(tmp_os.str(), tmp_os2);
pkt.putLongString(tmp_os2.str());
2011-11-15 00:00:16 +01:00
// Make data buffer
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
verbosestream << "Server: Sending item definitions to id(" << peer_id
<< "): size=" << pkt.getSize() << std::endl;
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
Send(&pkt);
2011-11-15 19:32:56 +01:00
}
void Server::SendNodeDef(session_t peer_id,
const NodeDefManager *nodedef, u16 protocol_version)
2011-11-15 19:32:56 +01:00
{
NetworkPacket pkt(TOCLIENT_NODEDEF, 0, peer_id);
2011-11-15 19:32:56 +01:00
/*
u16 command
u32 length of the next item
zlib-compressed serialized NodeDefManager
2011-11-15 19:32:56 +01:00
*/
std::ostringstream tmp_os(std::ios::binary);
nodedef->serialize(tmp_os, protocol_version);
std::ostringstream tmp_os2(std::ios::binary);
compressZlib(tmp_os.str(), tmp_os2);
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
pkt.putLongString(tmp_os2.str());
2011-11-15 19:32:56 +01:00
// Make data buffer
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
verbosestream << "Server: Sending node definitions to id(" << peer_id
<< "): size=" << pkt.getSize() << std::endl;
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
Send(&pkt);
2011-11-15 00:00:16 +01:00
}
/*
Non-static send methods
*/
void Server::SendInventory(PlayerSAO* playerSAO)
2010-11-27 00:02:21 +01:00
{
UpdateCrafting(playerSAO->getPlayer());
2010-12-22 15:30:23 +01:00
/*
Serialize it
2010-12-22 15:30:23 +01:00
*/
NetworkPacket pkt(TOCLIENT_INVENTORY, 0, playerSAO->getPeerID());
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
std::ostringstream os;
playerSAO->getInventory()->serialize(os);
std::string s = os.str();
pkt.putRawString(s.c_str(), s.size());
Send(&pkt);
}
void Server::SendChatMessage(session_t peer_id, const ChatMessage &message)
{
NetworkPacket pkt(TOCLIENT_CHAT_MESSAGE, 0, peer_id);
u8 version = 1;
u8 type = message.type;
pkt << version << type << std::wstring(L"") << message.message << message.timestamp;
if (peer_id != PEER_ID_INEXISTENT) {
RemotePlayer *player = m_env->getPlayer(peer_id);
if (!player)
return;
Send(&pkt);
} else {
m_clients.sendToAll(&pkt);
}
}
void Server::SendShowFormspecMessage(session_t peer_id, const std::string &formspec,
2014-02-27 21:12:59 +01:00
const std::string &formname)
{
NetworkPacket pkt(TOCLIENT_SHOW_FORMSPEC, 0 , peer_id);
if (formspec.empty()){
//the client should close the formspec
Fix randomly rejected form field submits (#8091) If a formspec is submitted from a form fields handling callback of another form (or "formspec shown from another formspec"), the fields submitted for it can get rejected by the form exploit mitigation subsystem with a message like "'zorman2000' submitted formspec ('formspec_error:form2') but server hasn't sent formspec to client, possible exploitation attempt" being sent to logs. This was already reported as #7374 and a change was made that fixed the simple testcase included with that bug report but the bug still kept lurking around and popping out in more complicated scenarios like the advtrains TSS route programming UI. Deep investigation of the problem revealed that this sequence of events is entirely possible and leads to the bug: 1. Server: show form1 2. Client *shows form1* 3. Client: submits form1 4. Server: show form2 5. Client: says form1 closed 6. Client *shows form2* 7. Client: submits form2 What happens inside the code is that when the server in step 4 sends form2, the registry of opened forms is updated to reflect the fact that form2 is now the valid form for the client to submit. Then when in step 5 client says "form1 was closed", the exploit mitigation subsystem code deletes the registry entry for the client without bothering to check whether the form client says was closed just now is indeed the form that is recorded in that entry as the valid form. Then later, in step 7 the client tries to submit its valid form fields, these will be rejected because the entry is missing. It turns out the procedure where the broken code resides already gets the form name so a simple "if" around the offending piece of code fixes the whole thing. And advtrains TSS agrees with that.
2019-01-21 09:53:09 +01:00
//but make sure there wasn't another one open in meantime
const auto it = m_formspec_state_data.find(peer_id);
if (it != m_formspec_state_data.end() && it->second == formname) {
m_formspec_state_data.erase(peer_id);
}
pkt.putLongString("");
} else {
m_formspec_state_data[peer_id] = formname;
pkt.putLongString(FORMSPEC_VERSION_STRING + formspec);
}
pkt << formname;
Send(&pkt);
}
// Spawns a particle on peer with peer_id
void Server::SendSpawnParticle(session_t peer_id, u16 protocol_version,
v3f pos, v3f velocity, v3f acceleration,
float expirationtime, float size, bool collisiondetection,
bool collision_removal, bool object_collision,
bool vertical, const std::string &texture,
const struct TileAnimationParams &animation, u8 glow)
{
static thread_local const float radius =
g_settings->getS16("max_block_send_distance") * MAP_BLOCKSIZE * BS;
if (peer_id == PEER_ID_INEXISTENT) {
std::vector<session_t> clients = m_clients.getClientIDs();
for (const session_t client_id : clients) {
RemotePlayer *player = m_env->getPlayer(client_id);
if (!player)
continue;
PlayerSAO *sao = player->getPlayerSAO();
if (!sao)
continue;
// Do not send to distant clients
if (sao->getBasePosition().getDistanceFrom(pos * BS) > radius)
continue;
SendSpawnParticle(client_id, player->protocol_version,
pos, velocity, acceleration,
expirationtime, size, collisiondetection, collision_removal,
object_collision, vertical, texture, animation, glow);
}
return;
}
NetworkPacket pkt(TOCLIENT_SPAWN_PARTICLE, 0, peer_id);
pkt << pos << velocity << acceleration << expirationtime
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
<< size << collisiondetection;
pkt.putLongString(texture);
pkt << vertical;
pkt << collision_removal;
// This is horrible but required (why are there two ways to serialize pkts?)
std::ostringstream os(std::ios_base::binary);
animation.serialize(os, protocol_version);
pkt.putRawString(os.str());
pkt << glow;
pkt << object_collision;
Send(&pkt);
}
// Adds a ParticleSpawner on peer with peer_id
void Server::SendAddParticleSpawner(session_t peer_id, u16 protocol_version,
u16 amount, float spawntime, v3f minpos, v3f maxpos,
v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime,
float minsize, float maxsize, bool collisiondetection, bool collision_removal,
bool object_collision, u16 attached_id, bool vertical, const std::string &texture, u32 id,
const struct TileAnimationParams &animation, u8 glow)
{
if (peer_id == PEER_ID_INEXISTENT) {
// This sucks and should be replaced:
std::vector<session_t> clients = m_clients.getClientIDs();
for (const session_t client_id : clients) {
RemotePlayer *player = m_env->getPlayer(client_id);
if (!player)
continue;
SendAddParticleSpawner(client_id, player->protocol_version,
amount, spawntime, minpos, maxpos,
minvel, maxvel, minacc, maxacc, minexptime, maxexptime,
minsize, maxsize, collisiondetection, collision_removal,
object_collision, attached_id, vertical, texture, id,
animation, glow);
}
return;
}
NetworkPacket pkt(TOCLIENT_ADD_PARTICLESPAWNER, 0, peer_id);
pkt << amount << spawntime << minpos << maxpos << minvel << maxvel
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
<< minacc << maxacc << minexptime << maxexptime << minsize
<< maxsize << collisiondetection;
pkt.putLongString(texture);
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
pkt << id << vertical;
pkt << collision_removal;
2016-08-04 22:09:21 +02:00
pkt << attached_id;
// This is horrible but required
std::ostringstream os(std::ios_base::binary);
animation.serialize(os, protocol_version);
pkt.putRawString(os.str());
pkt << glow;
pkt << object_collision;
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
Send(&pkt);
}
void Server::SendDeleteParticleSpawner(session_t peer_id, u32 id)
{
NetworkPacket pkt(TOCLIENT_DELETE_PARTICLESPAWNER, 4, peer_id);
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
// Ugly error in this packet
pkt << id;
if (peer_id != PEER_ID_INEXISTENT)
Send(&pkt);
else
m_clients.sendToAll(&pkt);
}
void Server::SendHUDAdd(session_t peer_id, u32 id, HudElement *form)
2013-04-11 20:23:38 +02:00
{
NetworkPacket pkt(TOCLIENT_HUDADD, 0 , peer_id);
2013-04-11 20:23:38 +02:00
pkt << id << (u8) form->type << form->pos << form->name << form->scale
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
<< form->text << form->number << form->item << form->dir
<< form->align << form->offset << form->world_pos << form->size;
2013-04-11 20:23:38 +02:00
Send(&pkt);
2013-04-11 20:23:38 +02:00
}
void Server::SendHUDRemove(session_t peer_id, u32 id)
2013-04-11 20:23:38 +02:00
{
NetworkPacket pkt(TOCLIENT_HUDRM, 4, peer_id);
pkt << id;
Send(&pkt);
2013-04-11 20:23:38 +02:00
}
void Server::SendHUDChange(session_t peer_id, u32 id, HudElementStat stat, void *value)
2013-04-11 20:23:38 +02:00
{
NetworkPacket pkt(TOCLIENT_HUDCHANGE, 0, peer_id);
pkt << id << (u8) stat;
2013-04-11 20:23:38 +02:00
switch (stat) {
case HUD_STAT_POS:
case HUD_STAT_SCALE:
case HUD_STAT_ALIGN:
2013-04-23 01:47:59 +02:00
case HUD_STAT_OFFSET:
pkt << *(v2f *) value;
break;
case HUD_STAT_NAME:
case HUD_STAT_TEXT:
pkt << *(std::string *) value;
break;
2014-01-26 21:31:59 +01:00
case HUD_STAT_WORLD_POS:
pkt << *(v3f *) value;
2014-01-26 21:31:59 +01:00
break;
case HUD_STAT_SIZE:
pkt << *(v2s32 *) value;
break;
case HUD_STAT_NUMBER:
case HUD_STAT_ITEM:
case HUD_STAT_DIR:
default:
pkt << *(u32 *) value;
break;
}
2013-04-11 20:23:38 +02:00
Send(&pkt);
2013-04-11 20:23:38 +02:00
}
void Server::SendHUDSetFlags(session_t peer_id, u32 flags, u32 mask)
{
NetworkPacket pkt(TOCLIENT_HUD_SET_FLAGS, 4 + 4, peer_id);
flags &= ~(HUD_FLAG_HEALTHBAR_VISIBLE | HUD_FLAG_BREATHBAR_VISIBLE);
pkt << flags << mask;
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
Send(&pkt);
}
void Server::SendHUDSetParam(session_t peer_id, u16 param, const std::string &value)
{
NetworkPacket pkt(TOCLIENT_HUD_SET_PARAM, 0, peer_id);
pkt << param << value;
Send(&pkt);
}
2010-12-25 00:54:39 +01:00
void Server::SendSetSky(session_t peer_id, const video::SColor &bgcolor,
const std::string &type, const std::vector<std::string> &params,
bool &clouds)
{
NetworkPacket pkt(TOCLIENT_SET_SKY, 0, peer_id);
pkt << bgcolor << type << (u16) params.size();
for (const std::string &param : params)
pkt << param;
pkt << clouds;
Send(&pkt);
}
void Server::SendCloudParams(session_t peer_id, const CloudParams &params)
2017-03-17 10:39:47 +01:00
{
NetworkPacket pkt(TOCLIENT_CLOUD_PARAMS, 0, peer_id);
pkt << params.density << params.color_bright << params.color_ambient
<< params.height << params.thickness << params.speed;
2017-03-17 10:39:47 +01:00
Send(&pkt);
}
void Server::SendOverrideDayNightRatio(session_t peer_id, bool do_override,
float ratio)
{
NetworkPacket pkt(TOCLIENT_OVERRIDE_DAY_NIGHT_RATIO,
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
1 + 2, peer_id);
pkt << do_override << (u16) (ratio * 65535);
Send(&pkt);
}
void Server::SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed)
{
NetworkPacket pkt(TOCLIENT_TIME_OF_DAY, 0, peer_id);
pkt << time << time_speed;
if (peer_id == PEER_ID_INEXISTENT) {
m_clients.sendToAll(&pkt);
}
else {
Send(&pkt);
}
}
void Server::SendPlayerHP(session_t peer_id)
{
PlayerSAO *playersao = getPlayerSAO(peer_id);
// In some rare case if the player is disconnected
// while Lua call l_punch, for example, this can be NULL
if (!playersao)
return;
SendHP(peer_id, playersao->getHP());
m_script->player_event(playersao,"health_changed");
// 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(aom);
}
void Server::SendPlayerBreath(PlayerSAO *sao)
{
assert(sao);
m_script->player_event(sao, "breath_changed");
SendBreath(sao->getPeerID(), sao->getBreath());
}
void Server::SendMovePlayer(session_t peer_id)
{
RemotePlayer *player = m_env->getPlayer(peer_id);
assert(player);
PlayerSAO *sao = player->getPlayerSAO();
assert(sao);
NetworkPacket pkt(TOCLIENT_MOVE_PLAYER, sizeof(v3f) + sizeof(f32) * 2, peer_id);
pkt << sao->getBasePosition() << sao->getLookPitch() << sao->getRotation().Y;
{
v3f pos = sao->getBasePosition();
verbosestream << "Server: Sending TOCLIENT_MOVE_PLAYER"
<< " pos=(" << pos.X << "," << pos.Y << "," << pos.Z << ")"
<< " pitch=" << sao->getLookPitch()
<< " yaw=" << sao->getRotation().Y
<< std::endl;
}
Send(&pkt);
}
void Server::SendLocalPlayerAnimations(session_t peer_id, v2s32 animation_frames[4],
f32 animation_speed)
2014-01-08 13:47:53 +01:00
{
NetworkPacket pkt(TOCLIENT_LOCAL_PLAYER_ANIMATIONS, 0,
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
peer_id);
2014-01-08 13:47:53 +01:00
pkt << animation_frames[0] << animation_frames[1] << animation_frames[2]
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
<< animation_frames[3] << animation_speed;
2014-01-08 13:47:53 +01:00
Send(&pkt);
2014-01-08 13:47:53 +01:00
}
void Server::SendEyeOffset(session_t peer_id, v3f first, v3f third)
{
NetworkPacket pkt(TOCLIENT_EYE_OFFSET, 0, peer_id);
pkt << first << third;
Send(&pkt);
}
void Server::SendPlayerPrivileges(session_t peer_id)
{
RemotePlayer *player = m_env->getPlayer(peer_id);
assert(player);
if(player->getPeerId() == PEER_ID_INEXISTENT)
return;
std::set<std::string> privs;
m_script->getAuth(player->getName(), NULL, &privs);
NetworkPacket pkt(TOCLIENT_PRIVILEGES, 0, peer_id);
pkt << (u16) privs.size();
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
for (const std::string &priv : privs) {
pkt << priv;
}
Send(&pkt);
}
void Server::SendPlayerInventoryFormspec(session_t peer_id)
{
RemotePlayer *player = m_env->getPlayer(peer_id);
assert(player);
if (player->getPeerId() == PEER_ID_INEXISTENT)
return;
NetworkPacket pkt(TOCLIENT_INVENTORY_FORMSPEC, 0, peer_id);
pkt.putLongString(FORMSPEC_VERSION_STRING + player->inventory_formspec);
Send(&pkt);
}
void Server::SendPlayerFormspecPrepend(session_t peer_id)
{
RemotePlayer *player = m_env->getPlayer(peer_id);
assert(player);
if (player->getPeerId() == PEER_ID_INEXISTENT)
return;
NetworkPacket pkt(TOCLIENT_FORMSPEC_PREPEND, 0, peer_id);
pkt << FORMSPEC_VERSION_STRING + player->formspec_prepend;
Send(&pkt);
}
u32 Server::SendActiveObjectRemoveAdd(session_t peer_id, const std::string &datas)
{
NetworkPacket pkt(TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD, datas.size(), peer_id);
pkt.putRawString(datas.c_str(), datas.size());
Send(&pkt);
return pkt.getSize();
}
void Server::SendActiveObjectMessages(session_t peer_id, const std::string &datas,
bool reliable)
{
NetworkPacket pkt(TOCLIENT_ACTIVE_OBJECT_MESSAGES,
datas.size(), peer_id);
pkt.putRawString(datas.c_str(), datas.size());
m_clients.send(pkt.getPeerId(),
reliable ? clientCommandFactoryTable[pkt.getCommand()].channel : 1,
&pkt, reliable);
}
void Server::SendCSMRestrictionFlags(session_t peer_id)
{
NetworkPacket pkt(TOCLIENT_CSM_RESTRICTION_FLAGS,
sizeof(m_csm_restriction_flags) + sizeof(m_csm_restriction_noderange), peer_id);
pkt << m_csm_restriction_flags << m_csm_restriction_noderange;
Send(&pkt);
}
2012-03-24 18:01:26 +01:00
s32 Server::playSound(const SimpleSoundSpec &spec,
const ServerSoundParams &params)
{
// Find out initial position of sound
bool pos_exists = false;
v3f pos = params.getPos(m_env, &pos_exists);
// If position is not found while it should be, cancel sound
if(pos_exists != (params.type != ServerSoundParams::SSP_LOCAL))
return -1;
2012-03-24 18:01:26 +01:00
// Filter destination clients
std::vector<session_t> dst_clients;
if(!params.to_player.empty()) {
RemotePlayer *player = m_env->getPlayer(params.to_player.c_str());
2012-03-24 18:01:26 +01:00
if(!player){
infostream<<"Server::playSound: Player \""<<params.to_player
<<"\" not found"<<std::endl;
return -1;
}
if (player->getPeerId() == PEER_ID_INEXISTENT) {
2012-03-24 18:01:26 +01:00
infostream<<"Server::playSound: Player \""<<params.to_player
<<"\" not connected"<<std::endl;
return -1;
}
dst_clients.push_back(player->getPeerId());
} else {
std::vector<session_t> clients = m_clients.getClientIDs();
for (const session_t client_id : clients) {
RemotePlayer *player = m_env->getPlayer(client_id);
if (!player)
2012-03-24 18:01:26 +01:00
continue;
PlayerSAO *sao = player->getPlayerSAO();
if (!sao)
continue;
if (pos_exists) {
if(sao->getBasePosition().getDistanceFrom(pos) >
2012-03-24 18:01:26 +01:00
params.max_hear_distance)
continue;
}
dst_clients.push_back(client_id);
2012-03-24 18:01:26 +01:00
}
}
if(dst_clients.empty())
2012-03-24 18:01:26 +01:00
return -1;
2012-03-24 18:01:26 +01:00
// Create the sound
s32 id = m_next_sound_id++;
// The sound will exist as a reference in m_playing_sounds
m_playing_sounds[id] = ServerPlayingSound();
ServerPlayingSound &psound = m_playing_sounds[id];
psound.params = params;
2016-07-10 07:08:26 +02:00
psound.spec = spec;
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
2016-07-10 07:08:26 +02:00
float gain = params.gain * spec.gain;
NetworkPacket pkt(TOCLIENT_PLAY_SOUND, 0);
2016-07-10 07:08:26 +02:00
pkt << id << spec.name << gain
<< (u8) params.type << pos << params.object
<< params.loop << params.fade << params.pitch;
2016-07-10 07:08:26 +02:00
// Backwards compability
bool play_sound = gain > 0;
for (const u16 dst_client : dst_clients) {
if (play_sound || m_clients.getProtocolVersion(dst_client) >= 32) {
psound.clients.insert(dst_client);
m_clients.send(dst_client, 0, &pkt, true);
2016-07-10 07:08:26 +02:00
}
2012-03-24 18:01:26 +01:00
}
return id;
}
void Server::stopSound(s32 handle)
{
// Get sound reference
std::unordered_map<s32, ServerPlayingSound>::iterator i =
m_playing_sounds.find(handle);
if (i == m_playing_sounds.end())
2012-03-24 18:01:26 +01:00
return;
ServerPlayingSound &psound = i->second;
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
NetworkPacket pkt(TOCLIENT_STOP_SOUND, 4);
pkt << handle;
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
for (std::unordered_set<session_t>::const_iterator si = psound.clients.begin();
si != psound.clients.end(); ++si) {
2012-03-24 18:01:26 +01:00
// Send as reliable
m_clients.send(*si, 0, &pkt, true);
2012-03-24 18:01:26 +01:00
}
// Remove sound reference
m_playing_sounds.erase(i);
}
2016-07-10 07:08:26 +02:00
void Server::fadeSound(s32 handle, float step, float gain)
{
// Get sound reference
std::unordered_map<s32, ServerPlayingSound>::iterator i =
m_playing_sounds.find(handle);
2016-07-10 07:08:26 +02:00
if (i == m_playing_sounds.end())
return;
ServerPlayingSound &psound = i->second;
psound.params.gain = gain;
NetworkPacket pkt(TOCLIENT_FADE_SOUND, 4);
pkt << handle << step << gain;
// Backwards compability
bool play_sound = gain > 0;
ServerPlayingSound compat_psound = psound;
compat_psound.clients.clear();
NetworkPacket compat_pkt(TOCLIENT_STOP_SOUND, 4);
compat_pkt << handle;
for (std::unordered_set<u16>::iterator it = psound.clients.begin();
2016-07-10 07:08:26 +02:00
it != psound.clients.end();) {
if (m_clients.getProtocolVersion(*it) >= 32) {
// Send as reliable
m_clients.send(*it, 0, &pkt, true);
++it;
} else {
compat_psound.clients.insert(*it);
// Stop old sound
m_clients.send(*it, 0, &compat_pkt, true);
psound.clients.erase(it++);
}
}
// Remove sound reference
if (!play_sound || psound.clients.empty())
2016-07-10 07:08:26 +02:00
m_playing_sounds.erase(i);
if (play_sound && !compat_psound.clients.empty()) {
2016-07-10 07:08:26 +02:00
// Play new sound volume on older clients
playSound(compat_psound.spec, compat_psound.params);
}
}
void Server::sendRemoveNode(v3s16 p, std::unordered_set<u16> *far_players,
float far_d_nodes)
{
float maxd = far_d_nodes * BS;
v3f p_f = intToFloat(p, BS);
v3s16 block_pos = getNodeBlockPos(p);
NetworkPacket pkt(TOCLIENT_REMOVENODE, 6);
pkt << p;
std::vector<session_t> clients = m_clients.getClientIDs();
m_clients.lock();
for (session_t client_id : clients) {
RemoteClient *client = m_clients.lockedGetClientNoEx(client_id);
if (!client)
continue;
RemotePlayer *player = m_env->getPlayer(client_id);
PlayerSAO *sao = player ? player->getPlayerSAO() : nullptr;
// If player is far away, only set modified blocks not sent
if (!client->isBlockSent(block_pos) || (sao &&
sao->getBasePosition().getDistanceFrom(p_f) > maxd)) {
if (far_players)
far_players->emplace(client_id);
else
client->SetBlockNotSent(block_pos);
continue;
}
2010-12-25 00:54:39 +01:00
// Send as reliable
m_clients.send(client_id, 0, &pkt, true);
}
m_clients.unlock();
}
void Server::sendAddNode(v3s16 p, MapNode n, std::unordered_set<u16> *far_players,
float far_d_nodes, bool remove_metadata)
{
float maxd = far_d_nodes * BS;
v3f p_f = intToFloat(p, BS);
v3s16 block_pos = getNodeBlockPos(p);
NetworkPacket pkt(TOCLIENT_ADDNODE, 6 + 2 + 1 + 1 + 1);
pkt << p << n.param0 << n.param1 << n.param2
<< (u8) (remove_metadata ? 0 : 1);
std::vector<session_t> clients = m_clients.getClientIDs();
m_clients.lock();
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
for (session_t client_id : clients) {
RemoteClient *client = m_clients.lockedGetClientNoEx(client_id);
if (!client)
continue;
RemotePlayer *player = m_env->getPlayer(client_id);
PlayerSAO *sao = player ? player->getPlayerSAO() : nullptr;
// If player is far away, only set modified blocks not sent
if (!client->isBlockSent(block_pos) || (sao &&
sao->getBasePosition().getDistanceFrom(p_f) > maxd)) {
if (far_players)
far_players->emplace(client_id);
else
client->SetBlockNotSent(block_pos);
continue;
2013-11-23 15:35:49 +01:00
}
// Send as reliable
m_clients.send(client_id, 0, &pkt, true);
}
m_clients.unlock();
}
void Server::sendMetadataChanged(const std::list<v3s16> &meta_updates, float far_d_nodes)
{
float maxd = far_d_nodes * BS;
NodeMetadataList meta_updates_list(false);
std::vector<session_t> clients = m_clients.getClientIDs();
m_clients.lock();
for (session_t i : clients) {
RemoteClient *client = m_clients.lockedGetClientNoEx(i);
if (!client)
continue;
ServerActiveObject *player = m_env->getActiveObject(i);
v3f player_pos = player ? player->getBasePosition() : v3f();
for (const v3s16 &pos : meta_updates) {
NodeMetadata *meta = m_env->getMap().getNodeMetadata(pos);
if (!meta)
continue;
v3s16 block_pos = getNodeBlockPos(pos);
if (!client->isBlockSent(block_pos) || (player &&
player_pos.getDistanceFrom(intToFloat(pos, BS)) > maxd)) {
client->SetBlockNotSent(block_pos);
continue;
}
// Add the change to send list
meta_updates_list.set(pos, meta);
}
if (meta_updates_list.size() == 0)
continue;
// Send the meta changes
std::ostringstream os(std::ios::binary);
meta_updates_list.serialize(os, client->net_proto_version, false, true);
std::ostringstream oss(std::ios::binary);
compressZlib(os.str(), oss);
NetworkPacket pkt(TOCLIENT_NODEMETA_CHANGED, 0);
pkt.putLongString(oss.str());
m_clients.send(i, 0, &pkt, true);
meta_updates_list.clear();
}
m_clients.unlock();
}
void Server::SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver,
u16 net_proto_version)
{
/*
Create a packet with the block in the right format
*/
std::ostringstream os(std::ios_base::binary);
block->serialize(os, ver, false);
block->serializeNetworkSpecific(os);
std::string s = os.str();
NetworkPacket pkt(TOCLIENT_BLOCKDATA, 2 + 2 + 2 + 2 + s.size(), peer_id);
pkt << block->getPos();
pkt.putRawString(s.c_str(), s.size());
Send(&pkt);
}
void Server::SendBlocks(float dtime)
{
MutexAutoLock envlock(m_env_mutex);
//TODO check if one big lock could be faster then multiple small ones
ScopeProfiler sp(g_profiler, "Server: sel and send blocks to clients");
2012-12-20 18:19:49 +01:00
std::vector<PrioritySortedBlockTransfer> queue;
u32 total_sending = 0;
{
ScopeProfiler sp2(g_profiler, "Server: selecting blocks for sending");
std::vector<session_t> clients = m_clients.getClientIDs();
m_clients.lock();
for (const session_t client_id : clients) {
RemoteClient *client = m_clients.lockedGetClientNoEx(client_id, CS_Active);
if (!client)
continue;
total_sending += client->getSendingCount();
client->GetNextBlocks(m_env,m_emerge, dtime, queue);
}
m_clients.unlock();
}
// Sort.
// Lowest priority number comes first.
// Lowest is most important.
2012-12-20 18:19:49 +01:00
std::sort(queue.begin(), queue.end());
m_clients.lock();
// Maximal total count calculation
// The per-client block sends is halved with the maximal online users
u32 max_blocks_to_send = (m_env->getPlayerCount() + g_settings->getU32("max_users")) *
g_settings->getU32("max_simultaneous_block_sends_per_client") / 4 + 1;
for (const PrioritySortedBlockTransfer &block_to_send : queue) {
if (total_sending >= max_blocks_to_send)
break;
MapBlock *block = nullptr;
try {
block = m_env->getMap().getBlockNoCreate(block_to_send.pos);
} catch (const InvalidPositionException &e) {
continue;
}
RemoteClient *client = m_clients.lockedGetClientNoEx(block_to_send.peer_id,
CS_Active);
if (!client)
continue;
SendBlockNoLock(block_to_send.peer_id, block, client->serialization_version,
client->net_proto_version);
client->SentBlock(block_to_send.pos);
total_sending++;
}
m_clients.unlock();
}
2012-03-25 10:50:29 +02:00
void Server::fillMediaCache()
2012-03-11 03:15:45 +01:00
{
infostream<<"Server: Calculating media file checksums"<<std::endl;
// Collect all media file paths
std::vector<std::string> paths;
m_modmgr->getModsMediaPaths(paths);
fs::GetRecursiveDirs(paths, m_gamespec.path + DIR_DELIM + "textures");
fs::GetRecursiveDirs(paths, porting::path_user + DIR_DELIM + "textures" + DIR_DELIM + "server");
// Collect media file information from paths into cache
for (const std::string &mediapath : paths) {
std::vector<fs::DirListNode> dirlist = fs::GetDirListing(mediapath);
for (const fs::DirListNode &dln : dirlist) {
if (dln.dir) // Ignode dirs
2012-03-11 03:15:45 +01:00
continue;
std::string filename = dln.name;
// If name contains illegal characters, ignore the file
if (!string_allowed(filename, TEXTURENAME_ALLOWED_CHARS)) {
infostream<<"Server: ignoring illegal file name: \""
<< filename << "\"" << std::endl;
2012-03-11 03:15:45 +01:00
continue;
}
// If name is not in a supported format, ignore it
const char *supported_ext[] = {
".png", ".jpg", ".bmp", ".tga",
".pcx", ".ppm", ".psd", ".wal", ".rgb",
".ogg",
".x", ".b3d", ".md2", ".obj",
2017-01-31 18:05:03 +01:00
// Custom translation file format
".tr",
NULL
};
if (removeStringEnd(filename, supported_ext).empty()){
infostream << "Server: ignoring unsupported file extension: \""
<< filename << "\"" << std::endl;
continue;
}
// Ok, attempt to load the file and add to cache
std::string filepath;
filepath.append(mediapath).append(DIR_DELIM).append(filename);
2012-03-11 03:15:45 +01:00
// Read data
std::ifstream fis(filepath.c_str(), std::ios_base::binary);
if (!fis.good()) {
errorstream << "Server::fillMediaCache(): Could not open \""
<< filename << "\" for reading" << std::endl;
2012-03-11 03:15:45 +01:00
continue;
}
std::ostringstream tmp_os(std::ios_base::binary);
bool bad = false;
for(;;) {
2012-03-11 03:15:45 +01:00
char buf[1024];
fis.read(buf, 1024);
std::streamsize len = fis.gcount();
tmp_os.write(buf, len);
if (fis.eof())
2012-03-11 03:15:45 +01:00
break;
if (!fis.good()) {
2012-03-11 03:15:45 +01:00
bad = true;
break;
2012-01-03 23:37:46 +01:00
}
2012-03-11 03:15:45 +01:00
}
if(bad) {
2012-03-25 10:50:29 +02:00
errorstream<<"Server::fillMediaCache(): Failed to read \""
<< filename << "\"" << std::endl;
2012-03-11 03:15:45 +01:00
continue;
}
if(tmp_os.str().length() == 0) {
errorstream << "Server::fillMediaCache(): Empty file \""
<< filepath << "\"" << std::endl;
2012-03-11 03:15:45 +01:00
continue;
}
2012-03-11 03:15:45 +01:00
SHA1 sha1;
sha1.addBytes(tmp_os.str().c_str(), tmp_os.str().length());
2012-03-11 03:15:45 +01:00
unsigned char *digest = sha1.getDigest();
std::string sha1_base64 = base64_encode(digest, 20);
std::string sha1_hex = hex_encode((char*)digest, 20);
2012-03-11 03:15:45 +01:00
free(digest);
2012-03-11 03:15:45 +01:00
// Put in list
m_media[filename] = MediaInfo(filepath, sha1_base64);
verbosestream << "Server: " << sha1_hex << " is " << filename
<< std::endl;
2012-03-11 03:15:45 +01:00
}
}
}
void Server::sendMediaAnnouncement(session_t peer_id, const std::string &lang_code)
2012-03-25 10:50:29 +02:00
{
verbosestream << "Server: Announcing files to id(" << peer_id << ")"
<< std::endl;
2012-03-25 10:50:29 +02:00
// Make packet
NetworkPacket pkt(TOCLIENT_ANNOUNCE_MEDIA, 0, peer_id);
2017-01-31 18:05:03 +01:00
u16 media_sent = 0;
std::string lang_suffix;
lang_suffix.append(".").append(lang_code).append(".tr");
for (const auto &i : m_media) {
if (str_ends_with(i.first, ".tr") && !str_ends_with(i.first, lang_suffix))
continue;
media_sent++;
}
pkt << media_sent;
for (const auto &i : m_media) {
2017-01-31 18:05:03 +01:00
if (str_ends_with(i.first, ".tr") && !str_ends_with(i.first, lang_suffix))
continue;
pkt << i.first << i.second.sha1_digest;
}
pkt << g_settings->get("remote_media");
Send(&pkt);
}
2012-03-25 10:50:29 +02:00
struct SendableMedia
2011-11-15 10:02:47 +01:00
{
std::string name;
std::string path;
std::string data;
2014-02-27 21:12:59 +01:00
SendableMedia(const std::string &name_="", const std::string &path_="",
const std::string &data_=""):
2011-11-15 10:02:47 +01:00
name(name_),
path(path_),
data(data_)
{}
};
void Server::sendRequestedMedia(session_t peer_id,
const std::vector<std::string> &tosend)
2012-03-25 10:50:29 +02:00
{
verbosestream<<"Server::sendRequestedMedia(): "
<<"Sending files to client"<<std::endl;
2012-03-25 10:50:29 +02:00
/* Read files */
2011-11-15 22:58:56 +01:00
// Put 5kB in one bunch (this is not accurate)
u32 bytes_per_bunch = 5000;
std::vector< std::vector<SendableMedia> > file_bunches;
file_bunches.emplace_back();
2012-03-25 10:50:29 +02:00
u32 file_size_bunch_total = 0;
for (const std::string &name : tosend) {
if (m_media.find(name) == m_media.end()) {
2012-03-25 10:50:29 +02:00
errorstream<<"Server::sendRequestedMedia(): Client asked for "
Rewrite client media download and support hash-based remote download Move most of the media-related code in client.cpp into a new class ClientMediaDownloader (clientmedia.cpp, clientmedia.h). Among other things, this class does the following things: - Download [remote_server][sha1] instead of [remote_server][name]. This is to support servers that provide the same file name with different contents. - Initially fetch [remote_server]index.mth. This file should follow the Minetest Hashset format (currently version 1) and contain a list of SHA1 hashes that exist on the server. - The list of needed SHA1s is uploaded (via HTTP POST) when index.mth is requested, so servers can optionally narrow down the list to the needs of the client. - If index.mth is missing (HTTP response code 404), we enter compat mode, fetching [remote_server][name] as before this commit. - remote_server can now contain multiple servers, separated by commas. The downloader code attempts to split requests between the different servers, as permitted by each server's index.mth. If one server claims to have a file but actually doesn't (or something fails), we ask a different server that also claims to have it. - As before, when none of the remote servers provide a particular file, we download it via the conventional method, i.e. using the minetest protocol: TOSERVER_REQUEST_MEDIA / TOCLIENT_MEDIA. - Bugfix: Every downloaded file's SHA1 is now verified against the SHA1 announced by the minetest server (before loading it and inserting it into the file cache). - Bugfix: Only send TOSERVER_RECEIVED_MEDIA when we actually have all media. This should fix #863.
2013-08-29 05:22:18 +02:00
<<"unknown file \""<<(name)<<"\""<<std::endl;
2012-01-03 23:37:46 +01:00
continue;
}
//TODO get path + name
Rewrite client media download and support hash-based remote download Move most of the media-related code in client.cpp into a new class ClientMediaDownloader (clientmedia.cpp, clientmedia.h). Among other things, this class does the following things: - Download [remote_server][sha1] instead of [remote_server][name]. This is to support servers that provide the same file name with different contents. - Initially fetch [remote_server]index.mth. This file should follow the Minetest Hashset format (currently version 1) and contain a list of SHA1 hashes that exist on the server. - The list of needed SHA1s is uploaded (via HTTP POST) when index.mth is requested, so servers can optionally narrow down the list to the needs of the client. - If index.mth is missing (HTTP response code 404), we enter compat mode, fetching [remote_server][name] as before this commit. - remote_server can now contain multiple servers, separated by commas. The downloader code attempts to split requests between the different servers, as permitted by each server's index.mth. If one server claims to have a file but actually doesn't (or something fails), we ask a different server that also claims to have it. - As before, when none of the remote servers provide a particular file, we download it via the conventional method, i.e. using the minetest protocol: TOSERVER_REQUEST_MEDIA / TOCLIENT_MEDIA. - Bugfix: Every downloaded file's SHA1 is now verified against the SHA1 announced by the minetest server (before loading it and inserting it into the file cache). - Bugfix: Only send TOSERVER_RECEIVED_MEDIA when we actually have all media. This should fix #863.
2013-08-29 05:22:18 +02:00
std::string tpath = m_media[name].path;
// Read data
std::ifstream fis(tpath.c_str(), std::ios_base::binary);
if(!fis.good()){
2012-03-25 10:50:29 +02:00
errorstream<<"Server::sendRequestedMedia(): Could not open \""
<<tpath<<"\" for reading"<<std::endl;
continue;
}
std::ostringstream tmp_os(std::ios_base::binary);
bool bad = false;
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
for(;;) {
char buf[1024];
fis.read(buf, 1024);
std::streamsize len = fis.gcount();
tmp_os.write(buf, len);
2012-03-25 10:50:29 +02:00
file_size_bunch_total += len;
if(fis.eof())
break;
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if(!fis.good()) {
bad = true;
break;
2011-11-15 22:58:56 +01:00
}
2011-11-15 10:02:47 +01:00
}
if (bad) {
2012-03-25 10:50:29 +02:00
errorstream<<"Server::sendRequestedMedia(): Failed to read \""
Rewrite client media download and support hash-based remote download Move most of the media-related code in client.cpp into a new class ClientMediaDownloader (clientmedia.cpp, clientmedia.h). Among other things, this class does the following things: - Download [remote_server][sha1] instead of [remote_server][name]. This is to support servers that provide the same file name with different contents. - Initially fetch [remote_server]index.mth. This file should follow the Minetest Hashset format (currently version 1) and contain a list of SHA1 hashes that exist on the server. - The list of needed SHA1s is uploaded (via HTTP POST) when index.mth is requested, so servers can optionally narrow down the list to the needs of the client. - If index.mth is missing (HTTP response code 404), we enter compat mode, fetching [remote_server][name] as before this commit. - remote_server can now contain multiple servers, separated by commas. The downloader code attempts to split requests between the different servers, as permitted by each server's index.mth. If one server claims to have a file but actually doesn't (or something fails), we ask a different server that also claims to have it. - As before, when none of the remote servers provide a particular file, we download it via the conventional method, i.e. using the minetest protocol: TOSERVER_REQUEST_MEDIA / TOCLIENT_MEDIA. - Bugfix: Every downloaded file's SHA1 is now verified against the SHA1 announced by the minetest server (before loading it and inserting it into the file cache). - Bugfix: Only send TOSERVER_RECEIVED_MEDIA when we actually have all media. This should fix #863.
2013-08-29 05:22:18 +02:00
<<name<<"\""<<std::endl;
continue;
}
2012-03-25 10:50:29 +02:00
/*infostream<<"Server::sendRequestedMedia(): Loaded \""
<<tname<<"\""<<std::endl;*/
// Put in list
file_bunches[file_bunches.size()-1].emplace_back(name, tpath, tmp_os.str());
// Start next bunch if got enough data
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if(file_size_bunch_total >= bytes_per_bunch) {
file_bunches.emplace_back();
2012-03-25 10:50:29 +02:00
file_size_bunch_total = 0;
}
2011-11-15 10:02:47 +01:00
}
2011-11-15 22:58:56 +01:00
/* Create and send packets */
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
u16 num_bunches = file_bunches.size();
for (u16 i = 0; i < num_bunches; i++) {
2012-03-25 10:50:29 +02:00
/*
u16 command
u16 total number of texture bunches
u16 index of this bunch
u32 number of files in this bunch
for each file {
u16 length of name
string name
u32 length of data
data
2011-11-15 22:58:56 +01:00
}
2012-03-25 10:50:29 +02:00
*/
2011-11-15 10:02:47 +01:00
NetworkPacket pkt(TOCLIENT_MEDIA, 4 + 0, peer_id);
pkt << num_bunches << i << (u32) file_bunches[i].size();
for (const SendableMedia &j : file_bunches[i]) {
pkt << j.name;
pkt.putLongString(j.data);
2012-03-25 10:50:29 +02:00
}
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
verbosestream << "Server::sendRequestedMedia(): bunch "
<< i << "/" << num_bunches
<< " files=" << file_bunches[i].size()
<< " size=" << pkt.getSize() << std::endl;
Send(&pkt);
2012-03-25 10:50:29 +02:00
}
2011-11-15 10:02:47 +01:00
}
void Server::sendDetachedInventory(const std::string &name, session_t peer_id)
2012-07-24 19:57:17 +02:00
{
const auto &inv_it = m_detached_inventories.find(name);
const auto &player_it = m_detached_inventories_player.find(name);
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (player_it == m_detached_inventories_player.end() ||
player_it->second.empty()) {
// OK. Send to everyone
} else {
RemotePlayer *p = m_env->getPlayer(player_it->second.c_str());
if (!p)
return; // Player is offline
2012-07-24 19:57:17 +02:00
if (peer_id != PEER_ID_INEXISTENT && peer_id != p->getPeerId())
return; // Caller requested send to a different player, so don't send.
peer_id = p->getPeerId();
}
2012-07-24 19:57:17 +02:00
NetworkPacket pkt(TOCLIENT_DETACHED_INVENTORY, 0, peer_id);
pkt << name;
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (inv_it == m_detached_inventories.end()) {
pkt << false; // Remove inventory
} else {
pkt << true; // Update inventory
// Serialization & NetworkPacket isn't a love story
std::ostringstream os(std::ios_base::binary);
inv_it->second->serialize(os);
pkt << os.str();
2012-07-24 19:57:17 +02:00
}
if (peer_id == PEER_ID_INEXISTENT)
m_clients.sendToAll(&pkt);
else
Send(&pkt);
2012-07-24 19:57:17 +02:00
}
void Server::sendDetachedInventories(session_t peer_id)
2012-07-24 19:57:17 +02:00
{
for (const auto &detached_inventory : m_detached_inventories) {
const std::string &name = detached_inventory.first;
2012-07-24 19:57:17 +02:00
//Inventory *inv = i->second;
sendDetachedInventory(name, peer_id);
}
}
/*
Something random
*/
void Server::DiePlayer(session_t peer_id, const PlayerHPChangeReason &reason)
2011-10-15 13:46:59 +02:00
{
PlayerSAO *playersao = getPlayerSAO(peer_id);
// In some rare cases this can be NULL -- if the player is disconnected
// when a Lua function modifies l_punch, for example
if (!playersao)
return;
infostream << "Server::DiePlayer(): Player "
<< playersao->getPlayer()->getName()
<< " dies" << std::endl;
playersao->setHP(0, reason);
playersao->clearParentAttachment();
// Trigger scripted stuff
m_script->on_dieplayer(playersao, reason);
SendPlayerHP(peer_id);
SendDeathscreen(peer_id, false, v3f(0,0,0));
2011-10-15 13:46:59 +02:00
}
void Server::RespawnPlayer(session_t peer_id)
2011-10-15 13:46:59 +02:00
{
PlayerSAO *playersao = getPlayerSAO(peer_id);
assert(playersao);
infostream << "Server::RespawnPlayer(): Player "
<< playersao->getPlayer()->getName()
<< " respawns" << std::endl;
playersao->setHP(playersao->accessObjectProperties()->hp_max,
PlayerHPChangeReason(PlayerHPChangeReason::RESPAWN));
playersao->setBreath(playersao->accessObjectProperties()->breath_max);
bool repositioned = m_script->on_respawnplayer(playersao);
if (!repositioned) {
// setPos will send the new position to client
playersao->setPos(findSpawnPos());
}
SendPlayerHP(peer_id);
2011-10-15 13:46:59 +02:00
}
void Server::DenySudoAccess(session_t peer_id)
{
NetworkPacket pkt(TOCLIENT_DENY_SUDO_MODE, 0, peer_id);
Send(&pkt);
}
2011-10-15 13:46:59 +02:00
void Server::DenyAccessVerCompliant(session_t peer_id, u16 proto_ver, AccessDeniedCode reason,
const std::string &str_reason, bool reconnect)
{
SendAccessDenied(peer_id, reason, str_reason, reconnect);
m_clients.event(peer_id, CSE_SetDenied);
DisconnectPeer(peer_id);
}
void Server::DenyAccess(session_t peer_id, AccessDeniedCode reason,
const std::string &custom_reason)
{
SendAccessDenied(peer_id, reason, custom_reason);
m_clients.event(peer_id, CSE_SetDenied);
DisconnectPeer(peer_id);
}
// 13/03/15: remove this function when protocol version 25 will become
// the minimum version for MT users, maybe in 1 year
void Server::DenyAccess_Legacy(session_t peer_id, const std::wstring &reason)
{
SendAccessDenied_Legacy(peer_id, reason);
m_clients.event(peer_id, CSE_SetDenied);
DisconnectPeer(peer_id);
}
void Server::DisconnectPeer(session_t peer_id)
{
m_modchannel_mgr->leaveAllChannels(peer_id);
m_con->DisconnectPeer(peer_id);
}
void Server::acceptAuth(session_t peer_id, bool forSudoMode)
{
if (!forSudoMode) {
RemoteClient* client = getClient(peer_id, CS_Invalid);
NetworkPacket resp_pkt(TOCLIENT_AUTH_ACCEPT, 1 + 6 + 8 + 4, peer_id);
// Right now, the auth mechs don't change between login and sudo mode.
u32 sudo_auth_mechs = client->allowed_auth_mechs;
client->allowed_sudo_mechs = sudo_auth_mechs;
resp_pkt << v3f(0,0,0) << (u64) m_env->getServerMap().getSeed()
<< g_settings->getFloat("dedicated_server_step")
<< sudo_auth_mechs;
Send(&resp_pkt);
m_clients.event(peer_id, CSE_AuthAccept);
} else {
NetworkPacket resp_pkt(TOCLIENT_ACCEPT_SUDO_MODE, 1 + 6 + 8 + 4, peer_id);
// We only support SRP right now
u32 sudo_auth_mechs = AUTH_MECHANISM_FIRST_SRP;
resp_pkt << sudo_auth_mechs;
Send(&resp_pkt);
m_clients.event(peer_id, CSE_SudoSuccess);
}
}
void Server::DeleteClient(session_t peer_id, ClientDeletionReason reason)
{
std::wstring message;
{
/*
Clear references to playing sounds
*/
for (std::unordered_map<s32, ServerPlayingSound>::iterator
i = m_playing_sounds.begin(); i != m_playing_sounds.end();) {
ServerPlayingSound &psound = i->second;
psound.clients.erase(peer_id);
if (psound.clients.empty())
m_playing_sounds.erase(i++);
else
2015-08-25 22:23:05 +02:00
++i;
}
// clear formspec info so the next client can't abuse the current state
m_formspec_state_data.erase(peer_id);
RemotePlayer *player = m_env->getPlayer(peer_id);
/* Run scripts and remove from environment */
if (player) {
PlayerSAO *playersao = player->getPlayerSAO();
assert(playersao);
playersao->clearChildAttachments();
playersao->clearParentAttachment();
// inform connected clients
const std::string &player_name = player->getName();
NetworkPacket notice(TOCLIENT_UPDATE_PLAYER_LIST, 0, PEER_ID_INEXISTENT);
// (u16) 1 + std::string represents a vector serialization representation
notice << (u8) PLAYER_LIST_REMOVE << (u16) 1 << player_name;
m_clients.sendToAll(&notice);
// run scripts
m_script->on_leaveplayer(playersao, reason == CDR_TIMEOUT);
playersao->disconnected();
}
/*
Print out action
*/
{
if (player && reason != CDR_DENY) {
std::ostringstream os(std::ios_base::binary);
std::vector<session_t> clients = m_clients.getClientIDs();
for (const session_t client_id : clients) {
// Get player
RemotePlayer *player = m_env->getPlayer(client_id);
if (!player)
continue;
// Get name of player
os << player->getName() << " ";
}
std::string name = player->getName();
actionstream << name << " "
<< (reason == CDR_TIMEOUT ? "times out." : "leaves game.")
<< " List of players: " << os.str() << std::endl;
if (m_admin_chat)
m_admin_chat->outgoing_queue.push_back(
new ChatEventNick(CET_NICK_REMOVE, name));
}
}
{
MutexAutoLock env_lock(m_env_mutex);
m_clients.DeleteClient(peer_id);
}
}
// Send leave chat message to all remaining clients
if (!message.empty()) {
SendChatMessage(PEER_ID_INEXISTENT,
ChatMessage(CHATMESSAGE_TYPE_ANNOUNCE, message));
}
}
void Server::UpdateCrafting(RemotePlayer *player)
{
InventoryList *clist = player->inventory.getList("craft");
if (!clist || clist->getSize() == 0)
return;
// Get a preview for crafting
ItemStack preview;
InventoryLocation loc;
loc.setPlayer(player->getName());
std::vector<ItemStack> output_replacements;
getCraftingResult(&player->inventory, preview, output_replacements, false, this);
m_env->getScriptIface()->item_CraftPredict(preview, player->getPlayerSAO(),
clist, loc);
InventoryList *plist = player->inventory.getList("craftpreview");
if (plist && plist->getSize() >= 1) {
// Put the new preview in
plist->changeItem(0, preview);
}
2010-11-27 00:02:21 +01:00
}
void Server::handleChatInterfaceEvent(ChatEvent *evt)
{
if (evt->type == CET_NICK_ADD) {
// The terminal informed us of its nick choice
m_admin_nick = ((ChatEventNick *)evt)->nick;
if (!m_script->getAuth(m_admin_nick, NULL, NULL)) {
errorstream << "You haven't set up an account." << std::endl
<< "Please log in using the client as '"
<< m_admin_nick << "' with a secure password." << std::endl
<< "Until then, you can't execute admin tasks via the console," << std::endl
<< "and everybody can claim the user account instead of you," << std::endl
<< "giving them full control over this server." << std::endl;
}
} else {
assert(evt->type == CET_CHAT);
handleAdminChat((ChatEventChat *)evt);
}
}
std::wstring Server::handleChat(const std::string &name, const std::wstring &wname,
std::wstring wmessage, bool check_shout_priv, RemotePlayer *player)
{
// If something goes wrong, this player is to blame
RollbackScopeActor rollback_scope(m_rollback,
std::string("player:") + name);
if (g_settings->getBool("strip_color_codes"))
wmessage = unescape_enriched(wmessage);
if (player) {
switch (player->canSendChatMessage()) {
case RPLAYER_CHATRESULT_FLOODING: {
std::wstringstream ws;
ws << L"You cannot send more messages. You are limited to "
<< g_settings->getFloat("chat_message_limit_per_10sec")
<< L" messages per 10 seconds.";
return ws.str();
}
case RPLAYER_CHATRESULT_KICK:
DenyAccess_Legacy(player->getPeerId(),
L"You have been kicked due to message flooding.");
return L"";
case RPLAYER_CHATRESULT_OK:
break;
default:
FATAL_ERROR("Unhandled chat filtering result found.");
}
}
if (m_max_chatmessage_length > 0
&& wmessage.length() > m_max_chatmessage_length) {
return L"Your message exceed the maximum chat message limit set on the server. "
L"It was refused. Send a shorter message";
}
// Run script hook, exit if script ate the chat message
if (m_script->on_chat_message(name, wide_to_utf8(wmessage)))
return L"";
// Line to send
std::wstring line;
// Whether to send line to the player that sent the message, or to all players
bool broadcast_line = true;
if (check_shout_priv && !checkPriv(name, "shout")) {
line += L"-!- You don't have permission to shout.";
broadcast_line = false;
} else {
line += L"<";
line += wname;
line += L"> ";
line += wmessage;
}
/*
Tell calling method to send the message to sender
*/
if (!broadcast_line)
return line;
/*
Send the message to others
*/
actionstream << "CHAT: " << wide_to_narrow(unescape_enriched(line)) << std::endl;
std::vector<session_t> clients = m_clients.getClientIDs();
/*
Send the message back to the inital sender
if they are using protocol version >= 29
*/
session_t peer_id_to_avoid_sending =
(player ? player->getPeerId() : PEER_ID_INEXISTENT);
if (player && player->protocol_version >= 29)
peer_id_to_avoid_sending = PEER_ID_INEXISTENT;
for (u16 cid : clients) {
if (cid != peer_id_to_avoid_sending)
SendChatMessage(cid, ChatMessage(line));
}
return L"";
}
void Server::handleAdminChat(const ChatEventChat *evt)
{
std::string name = evt->nick;
std::wstring wname = utf8_to_wide(name);
std::wstring wmessage = evt->evt_msg;
std::wstring answer = handleChat(name, wname, wmessage);
// If asked to send answer to sender
if (!answer.empty()) {
m_admin_chat->outgoing_queue.push_back(new ChatEventChat("", answer));
}
}
RemoteClient *Server::getClient(session_t peer_id, ClientState state_min)
2010-11-27 00:02:21 +01:00
{
RemoteClient *client = getClientNoEx(peer_id,state_min);
if(!client)
throw ClientNotFoundException("Client not found");
return client;
}
RemoteClient *Server::getClientNoEx(session_t peer_id, ClientState state_min)
{
return m_clients.getClientNoEx(peer_id, state_min);
2010-11-27 00:02:21 +01:00
}
std::string Server::getPlayerName(session_t peer_id)
{
RemotePlayer *player = m_env->getPlayer(peer_id);
if (!player)
return "[id="+itos(peer_id)+"]";
return player->getName();
}
PlayerSAO *Server::getPlayerSAO(session_t peer_id)
{
RemotePlayer *player = m_env->getPlayer(peer_id);
if (!player)
return NULL;
return player->getPlayerSAO();
}
std::wstring Server::getStatusString()
{
std::wostringstream os(std::ios_base::binary);
os << L"# Server: ";
2011-04-24 23:24:40 +02:00
// Version
os << L"version=" << narrow_to_wide(g_version_string);
// Uptime
os << L", uptime=" << m_uptime.get();
2013-08-03 22:16:37 +02:00
// Max lag estimate
os << L", max_lag=" << (m_env ? m_env->getMaxLagEstimate() : 0);
// Information about clients
bool first = true;
os << L", clients={";
if (m_env) {
std::vector<session_t> clients = m_clients.getClientIDs();
for (session_t client_id : clients) {
RemotePlayer *player = m_env->getPlayer(client_id);
// Get name of player
std::wstring name = L"unknown";
if (player)
name = narrow_to_wide(player->getName());
// Add name to information string
if (!first)
os << L", ";
else
first = false;
os << name;
}
}
os << L"}";
if (m_env && !((ServerMap*)(&m_env->getMap()))->isSavingEnabled())
os << std::endl << L"# Server: " << " WARNING: Map saving is disabled.";
if (!g_settings->get("motd").empty())
os << std::endl << L"# Server: " << narrow_to_wide(g_settings->get("motd"));
return os.str();
}
std::set<std::string> Server::getPlayerEffectivePrivs(const std::string &name)
{
std::set<std::string> privs;
m_script->getAuth(name, NULL, &privs);
return privs;
}
bool Server::checkPriv(const std::string &name, const std::string &priv)
{
std::set<std::string> privs = getPlayerEffectivePrivs(name);
return (privs.count(priv) != 0);
}
void Server::reportPrivsModified(const std::string &name)
{
if (name.empty()) {
std::vector<session_t> clients = m_clients.getClientIDs();
for (const session_t client_id : clients) {
RemotePlayer *player = m_env->getPlayer(client_id);
reportPrivsModified(player->getName());
}
} else {
RemotePlayer *player = m_env->getPlayer(name.c_str());
if (!player)
return;
SendPlayerPrivileges(player->getPeerId());
PlayerSAO *sao = player->getPlayerSAO();
if(!sao)
return;
sao->updatePrivileges(
getPlayerEffectivePrivs(name),
isSingleplayer());
}
}
void Server::reportInventoryFormspecModified(const std::string &name)
{
RemotePlayer *player = m_env->getPlayer(name.c_str());
if (!player)
return;
SendPlayerInventoryFormspec(player->getPeerId());
}
void Server::reportFormspecPrependModified(const std::string &name)
{
RemotePlayer *player = m_env->getPlayer(name.c_str());
if (!player)
return;
SendPlayerFormspecPrepend(player->getPeerId());
}
void Server::setIpBanned(const std::string &ip, const std::string &name)
2011-10-12 12:53:38 +02:00
{
m_banmanager->add(ip, name);
}
void Server::unsetIpBanned(const std::string &ip_or_name)
{
m_banmanager->remove(ip_or_name);
}
std::string Server::getBanDescription(const std::string &ip_or_name)
{
return m_banmanager->getBanDescription(ip_or_name);
2011-10-12 12:53:38 +02:00
}
2014-02-27 21:12:59 +01:00
void Server::notifyPlayer(const char *name, const std::wstring &msg)
{
// m_env will be NULL if the server is initializing
if (!m_env)
return;
if (m_admin_nick == name && !m_admin_nick.empty()) {
m_admin_chat->outgoing_queue.push_back(new ChatEventChat("", msg));
}
RemotePlayer *player = m_env->getPlayer(name);
if (!player) {
return;
}
if (player->getPeerId() == PEER_ID_INEXISTENT)
return;
SendChatMessage(player->getPeerId(), ChatMessage(msg));
}
bool Server::showFormspec(const char *playername, const std::string &formspec,
const std::string &formname)
{
// m_env will be NULL if the server is initializing
if (!m_env)
return false;
RemotePlayer *player = m_env->getPlayer(playername);
if (!player)
return false;
SendShowFormspecMessage(player->getPeerId(), formspec, formname);
return true;
}
u32 Server::hudAdd(RemotePlayer *player, HudElement *form)
{
if (!player)
return -1;
2014-05-25 14:34:32 +02:00
u32 id = player->addHud(form);
SendHUDAdd(player->getPeerId(), id, form);
2014-05-25 14:34:32 +02:00
return id;
2013-04-11 20:23:38 +02:00
}
bool Server::hudRemove(RemotePlayer *player, u32 id) {
2014-05-25 14:34:32 +02:00
if (!player)
2013-04-11 20:23:38 +02:00
return false;
2014-05-25 14:34:32 +02:00
HudElement* todel = player->removeHud(id);
if (!todel)
return false;
2014-05-25 14:34:32 +02:00
delete todel;
SendHUDRemove(player->getPeerId(), id);
2013-04-11 20:23:38 +02:00
return true;
}
bool Server::hudChange(RemotePlayer *player, u32 id, HudElementStat stat, void *data)
{
if (!player)
2013-04-11 20:23:38 +02:00
return false;
SendHUDChange(player->getPeerId(), id, stat, data);
2013-04-11 20:23:38 +02:00
return true;
}
bool Server::hudSetFlags(RemotePlayer *player, u32 flags, u32 mask)
{
if (!player)
return false;
SendHUDSetFlags(player->getPeerId(), flags, mask);
player->hud_flags &= ~mask;
player->hud_flags |= flags;
PlayerSAO* playersao = player->getPlayerSAO();
if (!playersao)
return false;
m_script->player_event(playersao, "hud_changed");
return true;
}
bool Server::hudSetHotbarItemcount(RemotePlayer *player, s32 hotbar_itemcount)
{
if (!player)
return false;
if (hotbar_itemcount <= 0 || hotbar_itemcount > HUD_HOTBAR_ITEMCOUNT_MAX)
return false;
player->setHotbarItemcount(hotbar_itemcount);
std::ostringstream os(std::ios::binary);
writeS32(os, hotbar_itemcount);
SendHUDSetParam(player->getPeerId(), HUD_PARAM_HOTBAR_ITEMCOUNT, os.str());
return true;
}
void Server::hudSetHotbarImage(RemotePlayer *player, std::string name)
{
if (!player)
return;
player->setHotbarImage(name);
SendHUDSetParam(player->getPeerId(), HUD_PARAM_HOTBAR_IMAGE, name);
}
void Server::hudSetHotbarSelectedImage(RemotePlayer *player, std::string name)
{
if (!player)
return;
player->setHotbarSelectedImage(name);
SendHUDSetParam(player->getPeerId(), HUD_PARAM_HOTBAR_SELECTED_IMAGE, name);
}
Address Server::getPeerAddress(session_t peer_id)
{
return m_con->GetPeerAddress(peer_id);
}
void Server::setLocalPlayerAnimations(RemotePlayer *player,
v2s32 animation_frames[4], f32 frame_speed)
2014-01-08 13:47:53 +01:00
{
sanity_check(player);
player->setLocalAnimations(animation_frames, frame_speed);
SendLocalPlayerAnimations(player->getPeerId(), animation_frames, frame_speed);
2014-01-08 13:47:53 +01:00
}
void Server::setPlayerEyeOffset(RemotePlayer *player, const v3f &first, const v3f &third)
{
sanity_check(player);
player->eye_offset_first = first;
player->eye_offset_third = third;
SendEyeOffset(player->getPeerId(), first, third);
}
void Server::setSky(RemotePlayer *player, const video::SColor &bgcolor,
const std::string &type, const std::vector<std::string> &params,
bool &clouds)
{
sanity_check(player);
player->setSky(bgcolor, type, params, clouds);
SendSetSky(player->getPeerId(), bgcolor, type, params, clouds);
}
void Server::setClouds(RemotePlayer *player, const CloudParams &params)
2017-03-17 10:39:47 +01:00
{
sanity_check(player);
player->setCloudParams(params);
SendCloudParams(player->getPeerId(), params);
2017-03-17 10:39:47 +01:00
}
bool Server::overrideDayNightRatio(RemotePlayer *player, bool do_override,
float ratio)
{
if (!player)
return false;
player->overrideDayNightRatio(do_override, ratio);
SendOverrideDayNightRatio(player->getPeerId(), do_override, ratio);
return true;
}
2014-02-27 21:12:59 +01:00
void Server::notifyPlayers(const std::wstring &msg)
2011-10-17 23:01:50 +02:00
{
SendChatMessage(PEER_ID_INEXISTENT, ChatMessage(msg));
2011-10-17 23:01:50 +02:00
}
void Server::spawnParticle(const std::string &playername, v3f pos,
v3f velocity, v3f acceleration,
float expirationtime, float size, bool
collisiondetection, bool collision_removal, bool object_collision,
bool vertical, const std::string &texture,
const struct TileAnimationParams &animation, u8 glow)
{
// m_env will be NULL if the server is initializing
if (!m_env)
return;
session_t peer_id = PEER_ID_INEXISTENT;
u16 proto_ver = 0;
if (!playername.empty()) {
RemotePlayer *player = m_env->getPlayer(playername.c_str());
if (!player)
return;
peer_id = player->getPeerId();
proto_ver = player->protocol_version;
}
SendSpawnParticle(peer_id, proto_ver, pos, velocity, acceleration,
expirationtime, size, collisiondetection, collision_removal,
object_collision, vertical, texture, animation, glow);
}
u32 Server::addParticleSpawner(u16 amount, float spawntime,
v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc,
float minexptime, float maxexptime, float minsize, float maxsize,
bool collisiondetection, bool collision_removal, bool object_collision,
2016-08-04 22:09:21 +02:00
ServerActiveObject *attached, bool vertical, const std::string &texture,
const std::string &playername, const struct TileAnimationParams &animation,
u8 glow)
{
// m_env will be NULL if the server is initializing
if (!m_env)
return -1;
session_t peer_id = PEER_ID_INEXISTENT;
u16 proto_ver = 0;
if (!playername.empty()) {
RemotePlayer *player = m_env->getPlayer(playername.c_str());
if (!player)
return -1;
peer_id = player->getPeerId();
proto_ver = player->protocol_version;
}
2016-08-04 22:09:21 +02:00
u16 attached_id = attached ? attached->getId() : 0;
u32 id;
if (attached_id == 0)
id = m_env->addParticleSpawner(spawntime);
else
id = m_env->addParticleSpawner(spawntime, attached_id);
SendAddParticleSpawner(peer_id, proto_ver, amount, spawntime,
minpos, maxpos, minvel, maxvel, minacc, maxacc,
minexptime, maxexptime, minsize, maxsize, collisiondetection,
collision_removal, object_collision, attached_id, vertical,
texture, id, animation, glow);
return id;
}
void Server::deleteParticleSpawner(const std::string &playername, u32 id)
{
// m_env will be NULL if the server is initializing
if (!m_env)
throw ServerError("Can't delete particle spawners during initialisation!");
session_t peer_id = PEER_ID_INEXISTENT;
if (!playername.empty()) {
RemotePlayer *player = m_env->getPlayer(playername.c_str());
if (!player)
return;
peer_id = player->getPeerId();
}
m_env->deleteParticleSpawner(id);
SendDeleteParticleSpawner(peer_id, id);
}
Inventory* Server::createDetachedInventory(const std::string &name, const std::string &player)
2012-07-24 19:57:17 +02:00
{
if(m_detached_inventories.count(name) > 0){
infostream<<"Server clearing detached inventory \""<<name<<"\""<<std::endl;
delete m_detached_inventories[name];
} else {
infostream<<"Server creating detached inventory \""<<name<<"\""<<std::endl;
}
Inventory *inv = new Inventory(m_itemdef);
sanity_check(inv);
2012-07-24 19:57:17 +02:00
m_detached_inventories[name] = inv;
m_detached_inventories_player[name] = player;
//TODO find a better way to do this
sendDetachedInventory(name,PEER_ID_INEXISTENT);
2012-07-24 19:57:17 +02:00
return inv;
}
bool Server::removeDetachedInventory(const std::string &name)
{
const auto &inv_it = m_detached_inventories.find(name);
if (inv_it == m_detached_inventories.end())
return false;
delete inv_it->second;
m_detached_inventories.erase(inv_it);
const auto &player_it = m_detached_inventories_player.find(name);
if (player_it != m_detached_inventories_player.end()) {
RemotePlayer *player = m_env->getPlayer(player_it->second.c_str());
if (player && player->getPeerId() != PEER_ID_INEXISTENT)
sendDetachedInventory(name, player->getPeerId());
m_detached_inventories_player.erase(player_it);
} else {
// Notify all players about the change
sendDetachedInventory(name, PEER_ID_INEXISTENT);
}
return true;
}
// actions: time-reversed list
// Return value: success/failure
bool Server::rollbackRevertActions(const std::list<RollbackAction> &actions,
std::list<std::string> *log)
{
infostream<<"Server::rollbackRevertActions(len="<<actions.size()<<")"<<std::endl;
ServerMap *map = (ServerMap*)(&m_env->getMap());
// Fail if no actions to handle
if (actions.empty()) {
assert(log);
log->push_back("Nothing to do.");
return false;
}
int num_tried = 0;
int num_failed = 0;
for (const RollbackAction &action : actions) {
num_tried++;
bool success = action.applyRevert(map, this, this);
if(!success){
num_failed++;
std::ostringstream os;
os<<"Revert of step ("<<num_tried<<") "<<action.toString()<<" failed";
infostream<<"Map::rollbackRevertActions(): "<<os.str()<<std::endl;
if (log)
log->push_back(os.str());
}else{
std::ostringstream os;
os<<"Successfully reverted step ("<<num_tried<<") "<<action.toString();
infostream<<"Map::rollbackRevertActions(): "<<os.str()<<std::endl;
if (log)
log->push_back(os.str());
}
}
infostream<<"Map::rollbackRevertActions(): "<<num_failed<<"/"<<num_tried
<<" failed"<<std::endl;
// Call it done if less than half failed
return num_failed <= num_tried/2;
}
2011-11-14 20:41:30 +01:00
// IGameDef interface
// Under envlock
IItemDefManager *Server::getItemDefManager()
2011-11-14 20:41:30 +01:00
{
return m_itemdef;
2011-11-14 20:41:30 +01:00
}
const NodeDefManager *Server::getNodeDefManager()
2011-11-14 20:41:30 +01:00
{
return m_nodedef;
2011-11-14 20:41:30 +01:00
}
ICraftDefManager *Server::getCraftDefManager()
2011-11-17 01:28:46 +01:00
{
return m_craftdef;
}
2011-11-16 12:03:28 +01:00
u16 Server::allocateUnknownNodeId(const std::string &name)
{
return m_nodedef->allocateDummy(name);
2011-11-16 12:03:28 +01:00
}
IWritableItemDefManager *Server::getWritableItemDefManager()
2011-11-15 01:03:28 +01:00
{
return m_itemdef;
2011-11-15 01:03:28 +01:00
}
NodeDefManager *Server::getWritableNodeDefManager()
2011-11-15 01:03:28 +01:00
{
return m_nodedef;
2011-11-15 01:03:28 +01:00
}
IWritableCraftDefManager *Server::getWritableCraftDefManager()
2011-11-17 01:28:46 +01:00
{
return m_craftdef;
}
2011-11-15 01:03:28 +01:00
const std::vector<ModSpec> & Server::getMods() const
{
return m_modmgr->getMods();
}
const ModSpec *Server::getModSpec(const std::string &modname) const
2011-12-11 15:49:40 +01:00
{
return m_modmgr->getModSpec(modname);
2011-12-11 15:49:40 +01:00
}
void Server::getModNames(std::vector<std::string> &modlist)
2012-07-22 03:29:37 +02:00
{
m_modmgr->getModNames(modlist);
2012-07-22 03:29:37 +02:00
}
2017-01-28 18:31:23 +01:00
std::string Server::getBuiltinLuaPath()
{
return porting::path_share + DIR_DELIM + "builtin";
}
2011-12-11 15:49:40 +01:00
std::string Server::getModStoragePath() const
{
return m_path_world + DIR_DELIM + "mod_storage";
}
v3f Server::findSpawnPos()
{
ServerMap &map = m_env->getServerMap();
v3f nodeposf;
if (g_settings->getV3FNoEx("static_spawnpoint", nodeposf)) {
return nodeposf * BS;
}
bool is_good = false;
// Limit spawn range to mapgen edges (determined by 'mapgen_limit')
s32 range_max = map.getMapgenParams()->getSpawnRangeMax();
// Try to find a good place a few times
for(s32 i = 0; i < 4000 && !is_good; i++) {
s32 range = MYMIN(1 + i, range_max);
// We're going to try to throw the player to this position
2013-04-21 21:39:34 +02:00
v2s16 nodepos2d = v2s16(
-range + (myrand() % (range * 2)),
-range + (myrand() % (range * 2)));
2013-04-21 21:39:34 +02:00
// Get spawn level at point
s16 spawn_level = m_emerge->getSpawnLevelAtPoint(nodepos2d);
// Continue if MAX_MAP_GENERATION_LIMIT was returned by
// the mapgen to signify an unsuitable spawn position
if (spawn_level == MAX_MAP_GENERATION_LIMIT)
continue;
v3s16 nodepos(nodepos2d.X, spawn_level, nodepos2d.Y);
s32 air_count = 0;
2013-04-21 21:39:34 +02:00
for (s32 i = 0; i < 10; i++) {
v3s16 blockpos = getNodeBlockPos(nodepos);
map.emergeBlock(blockpos, true);
2013-04-21 21:39:34 +02:00
content_t c = map.getNodeNoEx(nodepos).getContent();
if (c == CONTENT_AIR || c == CONTENT_IGNORE) {
air_count++;
if (air_count >= 2) {
nodeposf = intToFloat(nodepos, BS);
// Don't spawn the player outside map boundaries
if (objectpos_over_limit(nodeposf))
continue;
is_good = true;
break;
}
}
nodepos.Y++;
}
}
return nodeposf;
}
void Server::requestShutdown(const std::string &msg, bool reconnect, float delay)
{
if (delay == 0.0f) {
// No delay, shutdown immediately
m_shutdown_state.is_requested = true;
// only print to the infostream, a chat message saying
// "Server Shutting Down" is sent when the server destructs.
infostream << "*** Immediate Server shutdown requested." << std::endl;
} else if (delay < 0.0f && m_shutdown_state.isTimerRunning()) {
// Negative delay, cancel shutdown if requested
m_shutdown_state.reset();
std::wstringstream ws;
ws << L"*** Server shutdown canceled.";
infostream << wide_to_utf8(ws.str()).c_str() << std::endl;
SendChatMessage(PEER_ID_INEXISTENT, ws.str());
2018-06-11 13:43:12 +02:00
// m_shutdown_* are already handled, skip.
return;
} else if (delay > 0.0f) {
// Positive delay, tell the clients when the server will shut down
std::wstringstream ws;
ws << L"*** Server shutting down in "
2018-06-11 13:43:12 +02:00
<< duration_to_string(myround(delay)).c_str()
<< ".";
infostream << wide_to_utf8(ws.str()).c_str() << std::endl;
SendChatMessage(PEER_ID_INEXISTENT, ws.str());
}
2018-06-11 13:43:12 +02:00
m_shutdown_state.trigger(delay, msg, reconnect);
}
PlayerSAO* Server::emergePlayer(const char *name, session_t peer_id, u16 proto_version)
{
/*
Try to get an existing player
*/
RemotePlayer *player = m_env->getPlayer(name);
// If player is already connected, cancel
if (player && player->getPeerId() != PEER_ID_INEXISTENT) {
infostream<<"emergePlayer(): Player already connected"<<std::endl;
return NULL;
}
/*
If player with the wanted peer_id already exists, cancel.
*/
if (m_env->getPlayer(peer_id)) {
infostream<<"emergePlayer(): Player with wrong name but same"
" peer_id already exists"<<std::endl;
return NULL;
}
if (!player) {
player = new RemotePlayer(name, idef());
}
bool newplayer = false;
// Load player
PlayerSAO *playersao = m_env->loadPlayer(player, &newplayer, peer_id, isSingleplayer());
// Complete init with server parts
playersao->finalize(player, getPlayerEffectivePrivs(player->getName()));
player->protocol_version = proto_version;
/* Run scripts */
if (newplayer) {
m_script->on_newplayer(playersao);
}
return playersao;
}
bool Server::registerModStorage(ModMetadata *storage)
{
if (m_mod_storages.find(storage->getModName()) != m_mod_storages.end()) {
errorstream << "Unable to register same mod storage twice. Storage name: "
<< storage->getModName() << std::endl;
return false;
}
m_mod_storages[storage->getModName()] = storage;
return true;
}
void Server::unregisterModStorage(const std::string &name)
{
std::unordered_map<std::string, ModMetadata *>::const_iterator it = m_mod_storages.find(name);
if (it != m_mod_storages.end()) {
// Save unconditionaly on unregistration
it->second->save(getModStoragePath());
m_mod_storages.erase(name);
}
}
void dedicated_server_loop(Server &server, bool &kill)
2011-01-23 16:29:15 +01:00
{
2012-03-11 03:15:45 +01:00
verbosestream<<"dedicated_server_loop()"<<std::endl;
IntervalLimiter m_profiler_interval;
2011-01-23 16:29:15 +01:00
static thread_local const float steplen =
g_settings->getFloat("dedicated_server_step");
static thread_local const float profiler_print_interval =
2015-09-02 21:21:55 +02:00
g_settings->getFloat("profiler_print_interval");
for(;;) {
2011-01-23 16:29:15 +01:00
// This is kind of a hack but can be done like this
// because server.step() is very light
{
2011-10-12 12:53:38 +02:00
ScopeProfiler sp(g_profiler, "dedicated server sleep");
2012-03-07 20:44:53 +01:00
sleep_ms((int)(steplen*1000.0));
}
2012-03-07 20:44:53 +01:00
server.step(steplen);
2011-01-23 16:29:15 +01:00
if (server.isShutdownRequested() || kill)
break;
/*
Profiler
*/
2015-09-02 21:21:55 +02:00
if (profiler_print_interval != 0) {
2012-03-07 20:44:53 +01:00
if(m_profiler_interval.step(steplen, profiler_print_interval))
{
infostream<<"Profiler:"<<std::endl;
g_profiler->print(infostream);
2011-10-12 12:53:38 +02:00
g_profiler->clear();
}
}
2011-01-23 16:29:15 +01:00
}
infostream << "Dedicated server quitting" << std::endl;
#if USE_CURL
if (g_settings->getBool("server_announce"))
ServerList::sendAnnounce(ServerList::AA_DELETE,
server.m_bind_addr.getPort());
#endif
2011-01-23 16:29:15 +01:00
}
/*
* Mod channels
*/
bool Server::joinModChannel(const std::string &channel)
{
return m_modchannel_mgr->joinChannel(channel, PEER_ID_SERVER) &&
m_modchannel_mgr->setChannelState(channel, MODCHANNEL_STATE_READ_WRITE);
}
bool Server::leaveModChannel(const std::string &channel)
{
return m_modchannel_mgr->leaveChannel(channel, PEER_ID_SERVER);
}
bool Server::sendModChannelMessage(const std::string &channel, const std::string &message)
{
if (!m_modchannel_mgr->canWriteOnChannel(channel))
return false;
broadcastModChannelMessage(channel, message, PEER_ID_SERVER);
return true;
}
ModChannel* Server::getModChannel(const std::string &channel)
{
return m_modchannel_mgr->getModChannel(channel);
}
void Server::broadcastModChannelMessage(const std::string &channel,
const std::string &message, session_t from_peer)
{
const std::vector<u16> &peers = m_modchannel_mgr->getChannelPeers(channel);
if (peers.empty())
return;
if (message.size() > STRING_MAX_LEN) {
warningstream << "ModChannel message too long, dropping before sending "
<< " (" << message.size() << " > " << STRING_MAX_LEN << ", channel: "
<< channel << ")" << std::endl;
return;
}
std::string sender;
if (from_peer != PEER_ID_SERVER) {
sender = getPlayerName(from_peer);
}
NetworkPacket resp_pkt(TOCLIENT_MODCHANNEL_MSG,
2 + channel.size() + 2 + sender.size() + 2 + message.size());
resp_pkt << channel << sender << message;
for (session_t peer_id : peers) {
// Ignore sender
if (peer_id == from_peer)
continue;
Send(peer_id, &resp_pkt);
}
if (from_peer != PEER_ID_SERVER) {
m_script->on_modchannel_message(channel, sender, message);
}
}