#include "constants.h"
#include "voxel.h"
#include "config.h"
-#include "servercommand.h"
#include "filesys.h"
#include "mapblock.h"
#include "serverobject.h"
m_nearest_unsent_reset_timer += dtime;
if(m_nothing_to_send_pause_timer >= 0)
- {
return;
- }
+
+ Player *player = server->m_env->getPlayer(peer_id);
+ // This can happen sometimes; clients and players are not in perfect sync.
+ if(player == NULL)
+ return;
// Won't send anything if already sending
if(m_blocks_sending.size() >= g_settings->getU16
//TimeTaker timer("RemoteClient::GetNextBlocks");
- Player *player = server->m_env->getPlayer(peer_id);
-
- assert(player != NULL);
-
v3f playerpos = player->getPosition();
v3f playerspeed = player->getSpeed();
v3f playerspeeddir(0,0,0);
m_banmanager(path_world+DIR_DELIM+"ipban.txt"),
m_rollback(NULL),
m_rollback_sink_enabled(true),
+ m_enable_rollback_recording(false),
m_lua(NULL),
m_itemdef(createItemDefManager()),
m_nodedef(createNodeDefManager()),
/*
Send player inventories and HPs if necessary
*/
- if(playersao->m_teleported){
+ if(playersao->m_moved){
SendMovePlayer(client->peer_id);
- playersao->m_teleported = false;
+ playersao->m_moved = false;
}
if(playersao->m_inventory_not_sent){
UpdateCrafting(client->peer_id);
counter = 0.0;
m_emergethread.trigger();
+
+ // Update m_enable_rollback_recording here too
+ m_enable_rollback_recording =
+ g_settings->getBool("enable_rollback_recording");
}
}
if(command == TOSERVER_PLAYERPOS)
{
- if(datasize < 2+12+12+4+4)
+ if(datasize < 2+12+12+4+4+4)
return;
u32 start = 0;
v3s32 ss = readV3S32(&data[start+2+12]);
f32 pitch = (f32)readS32(&data[2+12+12]) / 100.0;
f32 yaw = (f32)readS32(&data[2+12+12+4]) / 100.0;
+ u32 keyPressed = (u32)readU32(&data[2+12+12+4+4]);
v3f position((f32)ps.X/100., (f32)ps.Y/100., (f32)ps.Z/100.);
v3f speed((f32)ss.X/100., (f32)ss.Y/100., (f32)ss.Z/100.);
pitch = wrapDegrees(pitch);
player->setSpeed(speed);
player->setPitch(pitch);
player->setYaw(yaw);
+ player->keyPressed=keyPressed;
+ player->control.up = (bool)(keyPressed&1);
+ player->control.down = (bool)(keyPressed&2);
+ player->control.left = (bool)(keyPressed&4);
+ player->control.right = (bool)(keyPressed&8);
+ player->control.jump = (bool)(keyPressed&16);
+ player->control.aux1 = (bool)(keyPressed&32);
+ player->control.sneak = (bool)(keyPressed&64);
+ player->control.LMB = (bool)(keyPressed&128);
+ player->control.RMB = (bool)(keyPressed&256);
/*infostream<<"Server::ProcessData(): Moved player "<<peer_id<<" to "
<<"("<<position.X<<","<<position.Y<<","<<position.Z<<")"
message += (wchar_t)readU16(buf);
}
+ // If something goes wrong, this player is to blame
+ RollbackScopeActor rollback_scope(m_rollback,
+ std::string("player:")+player->getName());
+
// Get player name of this client
std::wstring name = narrow_to_wide(player->getName());
// Whether to send to other players
bool send_to_others = false;
- // Parse commands
+ // Commands are implemented in Lua, so only catch invalid
+ // commands that were not "eaten" and send an error back
if(message[0] == L'/')
{
- size_t strip_size = 1;
- if (message[1] == L'#') // support old-style commans
- ++strip_size;
- message = message.substr(strip_size);
-
- WStrfnd f1(message);
- f1.next(L" "); // Skip over /#whatever
- std::wstring paramstring = f1.next(L"");
-
- ServerCommandContext *ctx = new ServerCommandContext(
- str_split(message, L' '),
- paramstring,
- this,
- m_env,
- player);
-
- std::wstring reply(processServerCommand(ctx));
- send_to_sender = ctx->flags & SEND_TO_SENDER;
- send_to_others = ctx->flags & SEND_TO_OTHERS;
-
- if (ctx->flags & SEND_NO_PREFIX)
- line += reply;
+ message = message.substr(1);
+ send_to_sender = true;
+ if(message.length() == 0)
+ line += L"-!- Empty command";
else
- line += L"Server: " + reply;
-
- delete ctx;
-
+ line += L"-!- Invalid command: " + str_split(message, L' ')[0];
}
else
{
}
} // action == 4
+
/*
Catch invalid actions
paths.push_back(mod.path + DIR_DELIM + "textures");
paths.push_back(mod.path + DIR_DELIM + "sounds");
paths.push_back(mod.path + DIR_DELIM + "media");
+ paths.push_back(mod.path + DIR_DELIM + "models");
}
std::string path_all = "textures";
paths.push_back(path_all + DIR_DELIM + "all");
".png", ".jpg", ".bmp", ".tga",
".pcx", ".ppm", ".psd", ".wal", ".rgb",
".ogg",
+ ".x", ".b3d", ".md2", ".obj",
NULL
};
if(removeStringEnd(filename, supported_ext) == ""){
// Uptime
os<<L", uptime="<<m_uptime.get();
// Information about clients
+ core::map<u16, RemoteClient*>::Iterator i;
+ bool first;
os<<L", clients={";
- for(core::map<u16, RemoteClient*>::Iterator
- i = m_clients.getIterator();
+ for(i = m_clients.getIterator(), first = true;
i.atEnd() == false; i++)
{
// Get client and check that it is valid
if(player != NULL)
name = narrow_to_wide(player->getName());
// Add name to information string
- os<<name<<L",";
+ if(!first)
+ os<<L",";
+ else
+ first = false;
+ os<<name;
}
os<<L"}";
if(((ServerMap*)(&m_env->getMap()))->isSavingEnabled() == false)
}
IRollbackReportSink* Server::getRollbackReportSink()
{
+ if(!m_enable_rollback_recording)
+ return NULL;
if(!m_rollback_sink_enabled)
return NULL;
return m_rollback;