mirror of
https://github.com/minetest/minetest.git
synced 2024-09-12 00:26:50 +02:00
Ctrl+C handling on POSIX, some commands for server and other tweaking
This commit is contained in:
parent
be7391c2b1
commit
d065bae323
@ -1,5 +1,7 @@
|
|||||||
Minetest-c55 changelog
|
Minetest-c55 changelog
|
||||||
----------------------
|
----------------------
|
||||||
|
This should contain all the major changes.
|
||||||
|
For minor stuff, refer to the commit log of the repository.
|
||||||
|
|
||||||
2011-02-14:
|
2011-02-14:
|
||||||
- Created changelog.txt
|
- Created changelog.txt
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
|
|
||||||
#map-dir = /home/palle/custom_map
|
#map-dir = /home/palle/custom_map
|
||||||
|
|
||||||
|
#operator_name =
|
||||||
|
|
||||||
#plants_amount = 1.0
|
#plants_amount = 1.0
|
||||||
#ravines_amount = 1.0
|
#ravines_amount = 1.0
|
||||||
#coal_amount = 1.0
|
#coal_amount = 1.0
|
||||||
|
@ -5,6 +5,8 @@ if(RUN_IN_PLACE)
|
|||||||
add_definitions ( -DRUN_IN_PLACE )
|
add_definitions ( -DRUN_IN_PLACE )
|
||||||
endif(RUN_IN_PLACE)
|
endif(RUN_IN_PLACE)
|
||||||
|
|
||||||
|
set(USE_GPROF 0 CACHE BOOL "Use -pg flag for g++")
|
||||||
|
|
||||||
# Use cmake_config.h
|
# Use cmake_config.h
|
||||||
add_definitions ( -DUSE_CMAKE_CONFIG_H )
|
add_definitions ( -DUSE_CMAKE_CONFIG_H )
|
||||||
|
|
||||||
@ -161,6 +163,10 @@ else()
|
|||||||
|
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG ${WARNING_FLAGS} -O3 -ffast-math -Wall -fomit-frame-pointer -pipe -funroll-loops")
|
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG ${WARNING_FLAGS} -O3 -ffast-math -Wall -fomit-frame-pointer -pipe -funroll-loops")
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -O1 -Wall")
|
set(CMAKE_CXX_FLAGS_DEBUG "-g -O1 -Wall")
|
||||||
|
|
||||||
|
if(USE_GPROF)
|
||||||
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(BUILD_SERVER)
|
if(BUILD_SERVER)
|
||||||
set_target_properties(minetestserver PROPERTIES
|
set_target_properties(minetestserver PROPERTIES
|
||||||
|
@ -174,10 +174,18 @@ bool GUIPauseMenu::OnEvent(const SEvent& event)
|
|||||||
{
|
{
|
||||||
if(event.EventType==EET_KEY_INPUT_EVENT)
|
if(event.EventType==EET_KEY_INPUT_EVENT)
|
||||||
{
|
{
|
||||||
if(event.KeyInput.Key==KEY_ESCAPE && event.KeyInput.PressedDown)
|
if(event.KeyInput.PressedDown)
|
||||||
{
|
{
|
||||||
quitMenu();
|
if(event.KeyInput.Key==KEY_ESCAPE)
|
||||||
return true;
|
{
|
||||||
|
quitMenu();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(event.KeyInput.Key==KEY_RETURN)
|
||||||
|
{
|
||||||
|
quitMenu();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(event.EventType==EET_GUI_EVENT)
|
if(event.EventType==EET_GUI_EVENT)
|
||||||
|
33
src/main.cpp
33
src/main.cpp
@ -268,7 +268,7 @@ Doing now (most important at the top):
|
|||||||
# maybe done
|
# maybe done
|
||||||
* not done
|
* not done
|
||||||
|
|
||||||
=== Stuff to do before release
|
=== Fixmes
|
||||||
* Make server find the spawning place from the real map data, not from
|
* Make server find the spawning place from the real map data, not from
|
||||||
the heightmap
|
the heightmap
|
||||||
- But the changing borders of chunk have to be avoided, because
|
- But the changing borders of chunk have to be avoided, because
|
||||||
@ -277,15 +277,15 @@ Doing now (most important at the top):
|
|||||||
placement and transfer
|
placement and transfer
|
||||||
* only_from_disk might not work anymore - check and fix it.
|
* only_from_disk might not work anymore - check and fix it.
|
||||||
* Check the fixmes in the list above
|
* Check the fixmes in the list above
|
||||||
* FIXME: Sneaking doesn't switch sneak node when moving sideways
|
* When sending blocks to the client, the server takes way too much
|
||||||
|
CPU time (20-30% for single player), find out what it is doing.
|
||||||
|
- Make a simple profiler
|
||||||
|
|
||||||
=== Making it more portable
|
=== Making it more portable
|
||||||
* Some MSVC: std::sto* are defined without a namespace and collide
|
* Some MSVC: std::sto* are defined without a namespace and collide
|
||||||
with the ones in utility.h
|
with the ones in utility.h
|
||||||
* On Kray's machine, the new find_library(XXF86VM_LIBRARY, Xxf86vm)
|
|
||||||
line doesn't find the library.
|
|
||||||
|
|
||||||
=== Stuff to do after release
|
=== Features
|
||||||
* Make an "environment metafile" to store at least time of day
|
* Make an "environment metafile" to store at least time of day
|
||||||
* Move digging property stuff from material.{h,cpp} to mapnode.cpp...
|
* Move digging property stuff from material.{h,cpp} to mapnode.cpp...
|
||||||
- Or maybe move content_features to material.{h,cpp}?
|
- Or maybe move content_features to material.{h,cpp}?
|
||||||
@ -567,7 +567,25 @@ struct TextDestChat : public TextDest
|
|||||||
}
|
}
|
||||||
void gotText(std::wstring text)
|
void gotText(std::wstring text)
|
||||||
{
|
{
|
||||||
|
// Discard empty line
|
||||||
|
if(text == L"")
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Parse command (server command starts with "/#")
|
||||||
|
if(text[0] == L'/' && text[1] != L'#')
|
||||||
|
{
|
||||||
|
std::wstring reply = L"Local: ";
|
||||||
|
|
||||||
|
reply += L"Local commands not yet supported. "
|
||||||
|
"Server prefix is \"/#\".";
|
||||||
|
|
||||||
|
m_client->addChatMessage(reply);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send to others
|
||||||
m_client->sendChatMessage(text);
|
m_client->sendChatMessage(text);
|
||||||
|
// Show locally
|
||||||
m_client->addChatMessage(text);
|
m_client->addChatMessage(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1546,6 +1564,9 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
|
|
||||||
|
porting::signal_handler_init();
|
||||||
|
bool &kill = *porting::signal_handler_killstatus();
|
||||||
|
|
||||||
porting::initializePaths();
|
porting::initializePaths();
|
||||||
// Create user data directory
|
// Create user data directory
|
||||||
fs::CreateDir(porting::path_userdata);
|
fs::CreateDir(porting::path_userdata);
|
||||||
@ -1681,7 +1702,7 @@ int main(int argc, char *argv[])
|
|||||||
server.start(port);
|
server.start(port);
|
||||||
|
|
||||||
// Run server
|
// Run server
|
||||||
dedicated_server_loop(server);
|
dedicated_server_loop(server, kill);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1771,11 +1771,11 @@ void MapBlock::serialize(std::ostream &os, u8 version)
|
|||||||
// First byte
|
// First byte
|
||||||
u8 flags = 0;
|
u8 flags = 0;
|
||||||
if(is_underground)
|
if(is_underground)
|
||||||
flags |= 1;
|
flags |= 0x01;
|
||||||
if(m_day_night_differs)
|
if(m_day_night_differs)
|
||||||
flags |= 2;
|
flags |= 0x02;
|
||||||
if(m_lighting_expired)
|
if(m_lighting_expired)
|
||||||
flags |= 3;
|
flags |= 0x04;
|
||||||
os.write((char*)&flags, 1);
|
os.write((char*)&flags, 1);
|
||||||
|
|
||||||
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
|
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
|
||||||
@ -1895,9 +1895,9 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
|
|||||||
|
|
||||||
u8 flags;
|
u8 flags;
|
||||||
is.read((char*)&flags, 1);
|
is.read((char*)&flags, 1);
|
||||||
is_underground = (flags & 1) ? true : false;
|
is_underground = (flags & 0x01) ? true : false;
|
||||||
m_day_night_differs = (flags & 2) ? true : false;
|
m_day_night_differs = (flags & 0x02) ? true : false;
|
||||||
m_lighting_expired = (flags & 3) ? true : false;
|
m_lighting_expired = (flags & 0x04) ? true : false;
|
||||||
|
|
||||||
// Uncompress data
|
// Uncompress data
|
||||||
std::ostringstream os(std::ios_base::binary);
|
std::ostringstream os(std::ios_base::binary);
|
||||||
|
@ -29,6 +29,53 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
namespace porting
|
namespace porting
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
Signal handler (grabs Ctrl-C on POSIX systems)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(_WIN32) // POSIX
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
bool g_killed = false;
|
||||||
|
|
||||||
|
void sigint_handler(int sig)
|
||||||
|
{
|
||||||
|
if(g_killed == false)
|
||||||
|
{
|
||||||
|
dstream<<DTIME<<"sigint_handler(): "
|
||||||
|
<<"Ctrl-C pressed, shutting down."<<std::endl;
|
||||||
|
g_killed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(void)signal(SIGINT, SIG_DFL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void signal_handler_init(void)
|
||||||
|
{
|
||||||
|
dstream<<"signal_handler_init()"<<std::endl;
|
||||||
|
(void)signal(SIGINT, sigint_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // _WIN32
|
||||||
|
|
||||||
|
void signal_handler_init(void)
|
||||||
|
{
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool * signal_handler_killstatus(void)
|
||||||
|
{
|
||||||
|
return &g_killed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Path mangler
|
||||||
|
*/
|
||||||
|
|
||||||
std::string path_data = "../data";
|
std::string path_data = "../data";
|
||||||
std::string path_userdata = "../";
|
std::string path_userdata = "../";
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#define PORTING_HEADER
|
#define PORTING_HEADER
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
// Included for u64 and such
|
// Included for u32 and such
|
||||||
#include "common_irrlicht.h"
|
#include "common_irrlicht.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
@ -47,6 +47,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
namespace porting
|
namespace porting
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
Signal handler (grabs Ctrl-C on POSIX systems)
|
||||||
|
*/
|
||||||
|
|
||||||
|
void signal_handler_init(void);
|
||||||
|
// Returns a pointer to a bool.
|
||||||
|
// When the bool is true, program should quit.
|
||||||
|
bool * signal_handler_killstatus(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Path of static data directory.
|
Path of static data directory.
|
||||||
*/
|
*/
|
||||||
|
282
src/server.cpp
282
src/server.cpp
@ -46,7 +46,12 @@ void * ServerThread::Thread()
|
|||||||
while(getRun())
|
while(getRun())
|
||||||
{
|
{
|
||||||
try{
|
try{
|
||||||
m_server->AsyncRunStep();
|
//TimeTaker timer("AsyncRunStep() + Receive()");
|
||||||
|
|
||||||
|
{
|
||||||
|
//TimeTaker timer("AsyncRunStep()");
|
||||||
|
m_server->AsyncRunStep();
|
||||||
|
}
|
||||||
|
|
||||||
//dout_server<<"Running m_server->Receive()"<<std::endl;
|
//dout_server<<"Running m_server->Receive()"<<std::endl;
|
||||||
m_server->Receive();
|
m_server->Receive();
|
||||||
@ -967,7 +972,8 @@ Server::Server(
|
|||||||
m_time_counter(0),
|
m_time_counter(0),
|
||||||
m_time_of_day_send_timer(0),
|
m_time_of_day_send_timer(0),
|
||||||
m_uptime(0),
|
m_uptime(0),
|
||||||
m_mapsavedir(mapsavedir)
|
m_mapsavedir(mapsavedir),
|
||||||
|
m_shutdown_requested(false)
|
||||||
{
|
{
|
||||||
//m_flowwater_timer = 0.0;
|
//m_flowwater_timer = 0.0;
|
||||||
m_liquid_transform_timer = 0.0;
|
m_liquid_transform_timer = 0.0;
|
||||||
@ -987,28 +993,62 @@ Server::Server(
|
|||||||
|
|
||||||
Server::~Server()
|
Server::~Server()
|
||||||
{
|
{
|
||||||
// Save players
|
/*
|
||||||
|
Send shutdown message
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
JMutexAutoLock conlock(m_con_mutex);
|
||||||
|
|
||||||
|
std::wstring line = L"*** Server shutting down";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Send the message to clients
|
||||||
|
*/
|
||||||
|
for(core::map<u16, RemoteClient*>::Iterator
|
||||||
|
i = m_clients.getIterator();
|
||||||
|
i.atEnd() == false; i++)
|
||||||
|
{
|
||||||
|
// Get client and check that it is valid
|
||||||
|
RemoteClient *client = i.getNode()->getValue();
|
||||||
|
assert(client->peer_id == i.getNode()->getKey());
|
||||||
|
if(client->serialization_version == SER_FMT_VER_INVALID)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SendChatMessage(client->peer_id, line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Save players
|
||||||
|
*/
|
||||||
m_env.serializePlayers(m_mapsavedir);
|
m_env.serializePlayers(m_mapsavedir);
|
||||||
|
|
||||||
// Stop threads
|
/*
|
||||||
|
Stop threads
|
||||||
|
*/
|
||||||
stop();
|
stop();
|
||||||
|
|
||||||
JMutexAutoLock clientslock(m_con_mutex);
|
/*
|
||||||
|
Delete clients
|
||||||
for(core::map<u16, RemoteClient*>::Iterator
|
*/
|
||||||
i = m_clients.getIterator();
|
|
||||||
i.atEnd() == false; i++)
|
|
||||||
{
|
{
|
||||||
/*// Delete player
|
JMutexAutoLock clientslock(m_con_mutex);
|
||||||
// NOTE: These are removed by env destructor
|
|
||||||
|
for(core::map<u16, RemoteClient*>::Iterator
|
||||||
|
i = m_clients.getIterator();
|
||||||
|
i.atEnd() == false; i++)
|
||||||
{
|
{
|
||||||
u16 peer_id = i.getNode()->getKey();
|
/*// Delete player
|
||||||
JMutexAutoLock envlock(m_env_mutex);
|
// NOTE: These are removed by env destructor
|
||||||
m_env.removePlayer(peer_id);
|
{
|
||||||
}*/
|
u16 peer_id = i.getNode()->getKey();
|
||||||
|
JMutexAutoLock envlock(m_env_mutex);
|
||||||
// Delete client
|
m_env.removePlayer(peer_id);
|
||||||
delete i.getNode()->getValue();
|
}*/
|
||||||
|
|
||||||
|
// Delete client
|
||||||
|
delete i.getNode()->getValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1586,39 +1626,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
m_time_of_day.get());
|
m_time_of_day.get());
|
||||||
m_con.Send(peer->id, 0, data, true);
|
m_con.Send(peer->id, 0, data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send information about server to player in chat
|
// Send information about server to player in chat
|
||||||
{
|
SendChatMessage(peer_id, getStatusString());
|
||||||
std::wostringstream os(std::ios_base::binary);
|
|
||||||
os<<L"# Server: ";
|
|
||||||
// Uptime
|
|
||||||
os<<L"uptime="<<m_uptime.get();
|
|
||||||
// Information about clients
|
|
||||||
os<<L", clients={";
|
|
||||||
for(core::map<u16, RemoteClient*>::Iterator
|
|
||||||
i = m_clients.getIterator();
|
|
||||||
i.atEnd() == false; i++)
|
|
||||||
{
|
|
||||||
// Get client and check that it is valid
|
|
||||||
RemoteClient *client = i.getNode()->getValue();
|
|
||||||
assert(client->peer_id == i.getNode()->getKey());
|
|
||||||
if(client->serialization_version == SER_FMT_VER_INVALID)
|
|
||||||
continue;
|
|
||||||
// Get player
|
|
||||||
Player *player = m_env.getPlayer(client->peer_id);
|
|
||||||
// Get name of player
|
|
||||||
std::wstring name = L"unknown";
|
|
||||||
if(player != NULL)
|
|
||||||
name = narrow_to_wide(player->getName());
|
|
||||||
// Add name to information string
|
|
||||||
os<<name<<L",";
|
|
||||||
}
|
|
||||||
os<<L"}";
|
|
||||||
if(((ServerMap*)(&m_env.getMap()))->isSavingEnabled() == false)
|
|
||||||
os<<" WARNING: Map saving is disabled."<<std::endl;
|
|
||||||
// Send message
|
|
||||||
SendChatMessage(peer_id, os.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send information about joining in chat
|
// Send information about joining in chat
|
||||||
{
|
{
|
||||||
@ -2461,29 +2471,115 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
|
|
||||||
// Get player name of this client
|
// Get player name of this client
|
||||||
std::wstring name = narrow_to_wide(player->getName());
|
std::wstring name = narrow_to_wide(player->getName());
|
||||||
|
|
||||||
std::wstring line = std::wstring(L"<")+name+L"> "+message;
|
|
||||||
|
|
||||||
dstream<<"CHAT: "<<wide_to_narrow(line)<<std::endl;
|
// Line to send to players
|
||||||
|
std::wstring line;
|
||||||
/*
|
// Whether to send to the player that sent the line
|
||||||
Send the message to all other clients
|
bool send_to_sender = false;
|
||||||
*/
|
// Whether to send to other players
|
||||||
for(core::map<u16, RemoteClient*>::Iterator
|
bool send_to_others = false;
|
||||||
i = m_clients.getIterator();
|
|
||||||
i.atEnd() == false; i++)
|
// Parse commands
|
||||||
|
std::wstring commandprefix = L"/#";
|
||||||
|
if(message.substr(0, commandprefix.size()) == commandprefix)
|
||||||
{
|
{
|
||||||
// Get client and check that it is valid
|
line += L"Server: ";
|
||||||
RemoteClient *client = i.getNode()->getValue();
|
|
||||||
assert(client->peer_id == i.getNode()->getKey());
|
|
||||||
if(client->serialization_version == SER_FMT_VER_INVALID)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Don't send if it's the same one
|
message = message.substr(commandprefix.size());
|
||||||
if(peer_id == client->peer_id)
|
// Get player name as narrow string
|
||||||
continue;
|
std::string name_s = player->getName();
|
||||||
|
// Convert message to narrow string
|
||||||
|
std::string message_s = wide_to_narrow(message);
|
||||||
|
// Operator is the single name defined in config.
|
||||||
|
std::string operator_name = g_settings.get("name");
|
||||||
|
bool is_operator = (operator_name != "" &&
|
||||||
|
wide_to_narrow(name) == operator_name);
|
||||||
|
bool valid_command = false;
|
||||||
|
if(message_s == "help")
|
||||||
|
{
|
||||||
|
line += L"-!- Available commands: ";
|
||||||
|
line += L"status ";
|
||||||
|
if(is_operator)
|
||||||
|
{
|
||||||
|
line += L"shutdown setting ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
send_to_sender = true;
|
||||||
|
valid_command = true;
|
||||||
|
}
|
||||||
|
else if(message_s == "status")
|
||||||
|
{
|
||||||
|
line = getStatusString();
|
||||||
|
send_to_sender = true;
|
||||||
|
valid_command = true;
|
||||||
|
}
|
||||||
|
else if(is_operator)
|
||||||
|
{
|
||||||
|
if(message_s == "shutdown")
|
||||||
|
{
|
||||||
|
dstream<<DTIME<<" Server: Operator requested shutdown."
|
||||||
|
<<std::endl;
|
||||||
|
m_shutdown_requested.set(true);
|
||||||
|
|
||||||
|
line += L"*** Server shutting down (operator request)";
|
||||||
|
send_to_sender = true;
|
||||||
|
valid_command = true;
|
||||||
|
}
|
||||||
|
else if(message_s.substr(0,8) == "setting ")
|
||||||
|
{
|
||||||
|
std::string confline = message_s.substr(8);
|
||||||
|
g_settings.parseConfigLine(confline);
|
||||||
|
line += L"-!- Setting changed.";
|
||||||
|
send_to_sender = true;
|
||||||
|
valid_command = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(valid_command == false)
|
||||||
|
{
|
||||||
|
line += L"-!- Invalid command: " + message;
|
||||||
|
send_to_sender = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
line += L"<";
|
||||||
|
/*if(is_operator)
|
||||||
|
line += L"@";*/
|
||||||
|
line += name;
|
||||||
|
line += L"> ";
|
||||||
|
line += message;
|
||||||
|
send_to_others = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(line != L"")
|
||||||
|
{
|
||||||
|
dstream<<"CHAT: "<<wide_to_narrow(line)<<std::endl;
|
||||||
|
|
||||||
SendChatMessage(client->peer_id, line);
|
/*
|
||||||
|
Send the message to clients
|
||||||
|
*/
|
||||||
|
for(core::map<u16, RemoteClient*>::Iterator
|
||||||
|
i = m_clients.getIterator();
|
||||||
|
i.atEnd() == false; i++)
|
||||||
|
{
|
||||||
|
// Get client and check that it is valid
|
||||||
|
RemoteClient *client = i.getNode()->getValue();
|
||||||
|
assert(client->peer_id == i.getNode()->getKey());
|
||||||
|
if(client->serialization_version == SER_FMT_VER_INVALID)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Filter recipient
|
||||||
|
bool sender_selected = (peer_id == client->peer_id);
|
||||||
|
if(sender_selected == true && send_to_sender == false)
|
||||||
|
continue;
|
||||||
|
if(sender_selected == false && send_to_others == false)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SendChatMessage(client->peer_id, line);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2580,6 +2676,7 @@ core::list<PlayerInfo> Server::getPlayerInfo()
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Server::peerAdded(con::Peer *peer)
|
void Server::peerAdded(con::Peer *peer)
|
||||||
{
|
{
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
@ -3020,6 +3117,8 @@ void Server::SendBlocks(float dtime)
|
|||||||
|
|
||||||
JMutexAutoLock envlock(m_env_mutex);
|
JMutexAutoLock envlock(m_env_mutex);
|
||||||
|
|
||||||
|
//TimeTaker timer("Server::SendBlocks");
|
||||||
|
|
||||||
core::array<PrioritySortedBlockTransfer> queue;
|
core::array<PrioritySortedBlockTransfer> queue;
|
||||||
|
|
||||||
s32 total_sending = 0;
|
s32 total_sending = 0;
|
||||||
@ -3087,6 +3186,39 @@ RemoteClient* Server::getClient(u16 peer_id)
|
|||||||
return n->getValue();
|
return n->getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::wstring Server::getStatusString()
|
||||||
|
{
|
||||||
|
std::wostringstream os(std::ios_base::binary);
|
||||||
|
os<<L"# Server: ";
|
||||||
|
// Uptime
|
||||||
|
os<<L"uptime="<<m_uptime.get();
|
||||||
|
// Information about clients
|
||||||
|
os<<L", clients={";
|
||||||
|
for(core::map<u16, RemoteClient*>::Iterator
|
||||||
|
i = m_clients.getIterator();
|
||||||
|
i.atEnd() == false; i++)
|
||||||
|
{
|
||||||
|
// Get client and check that it is valid
|
||||||
|
RemoteClient *client = i.getNode()->getValue();
|
||||||
|
assert(client->peer_id == i.getNode()->getKey());
|
||||||
|
if(client->serialization_version == SER_FMT_VER_INVALID)
|
||||||
|
continue;
|
||||||
|
// Get player
|
||||||
|
Player *player = m_env.getPlayer(client->peer_id);
|
||||||
|
// Get name of player
|
||||||
|
std::wstring name = L"unknown";
|
||||||
|
if(player != NULL)
|
||||||
|
name = narrow_to_wide(player->getName());
|
||||||
|
// Add name to information string
|
||||||
|
os<<name<<L",";
|
||||||
|
}
|
||||||
|
os<<L"}";
|
||||||
|
if(((ServerMap*)(&m_env.getMap()))->isSavingEnabled() == false)
|
||||||
|
os<<" WARNING: Map saving is disabled."<<std::endl;
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void setCreativeInventory(Player *player)
|
void setCreativeInventory(Player *player)
|
||||||
{
|
{
|
||||||
player->resetInventory();
|
player->resetInventory();
|
||||||
@ -3455,11 +3587,11 @@ void Server::handlePeerChanges()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dedicated_server_loop(Server &server)
|
void dedicated_server_loop(Server &server, bool &kill)
|
||||||
{
|
{
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
|
|
||||||
std::cout<<std::endl;
|
std::cout<<DTIME<<std::endl;
|
||||||
std::cout<<"========================"<<std::endl;
|
std::cout<<"========================"<<std::endl;
|
||||||
std::cout<<"Running dedicated server"<<std::endl;
|
std::cout<<"Running dedicated server"<<std::endl;
|
||||||
std::cout<<"========================"<<std::endl;
|
std::cout<<"========================"<<std::endl;
|
||||||
@ -3472,6 +3604,12 @@ void dedicated_server_loop(Server &server)
|
|||||||
sleep_ms(30);
|
sleep_ms(30);
|
||||||
server.step(0.030);
|
server.step(0.030);
|
||||||
|
|
||||||
|
if(server.getShutdownRequested() || kill)
|
||||||
|
{
|
||||||
|
std::cout<<DTIME<<" dedicated_server_loop(): Quitting."<<std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
static int counter = 0;
|
static int counter = 0;
|
||||||
counter--;
|
counter--;
|
||||||
if(counter <= 0)
|
if(counter <= 0)
|
||||||
|
32
src/server.h
32
src/server.h
@ -390,15 +390,11 @@ public:
|
|||||||
void Receive();
|
void Receive();
|
||||||
void ProcessData(u8 *data, u32 datasize, u16 peer_id);
|
void ProcessData(u8 *data, u32 datasize, u16 peer_id);
|
||||||
|
|
||||||
/*void Send(u16 peer_id, u16 channelnum,
|
// Environment and Connection must be locked when called
|
||||||
SharedBuffer<u8> data, bool reliable);*/
|
|
||||||
|
|
||||||
// Environment and Connection must be locked when called
|
|
||||||
void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver);
|
void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver);
|
||||||
|
|
||||||
// Environment and Connection must be locked when called
|
//
|
||||||
//void SendSectorMeta(u16 peer_id, core::list<v2s16> ps, u8 ver);
|
|
||||||
|
|
||||||
core::list<PlayerInfo> getPlayerInfo();
|
core::list<PlayerInfo> getPlayerInfo();
|
||||||
|
|
||||||
u32 getDayNightRatio()
|
u32 getDayNightRatio()
|
||||||
@ -412,7 +408,12 @@ public:
|
|||||||
else
|
else
|
||||||
return 1000;
|
return 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool getShutdownRequested()
|
||||||
|
{
|
||||||
|
return m_shutdown_requested.get();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Virtual methods from con::PeerHandler.
|
// Virtual methods from con::PeerHandler.
|
||||||
@ -432,7 +433,10 @@ private:
|
|||||||
|
|
||||||
// When called, connection mutex should be locked
|
// When called, connection mutex should be locked
|
||||||
RemoteClient* getClient(u16 peer_id);
|
RemoteClient* getClient(u16 peer_id);
|
||||||
|
|
||||||
|
// Connection must be locked when called
|
||||||
|
std::wstring getStatusString();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get a player from memory or creates one.
|
Get a player from memory or creates one.
|
||||||
If player is already connected, return NULL
|
If player is already connected, return NULL
|
||||||
@ -490,7 +494,7 @@ private:
|
|||||||
float m_time_of_day_send_timer;
|
float m_time_of_day_send_timer;
|
||||||
|
|
||||||
MutexedVariable<double> m_uptime;
|
MutexedVariable<double> m_uptime;
|
||||||
|
|
||||||
enum PeerChangeType
|
enum PeerChangeType
|
||||||
{
|
{
|
||||||
PEER_ADDED,
|
PEER_ADDED,
|
||||||
@ -508,14 +512,18 @@ private:
|
|||||||
|
|
||||||
std::string m_mapsavedir;
|
std::string m_mapsavedir;
|
||||||
|
|
||||||
|
MutexedVariable<bool> m_shutdown_requested;
|
||||||
|
|
||||||
friend class EmergeThread;
|
friend class EmergeThread;
|
||||||
friend class RemoteClient;
|
friend class RemoteClient;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Runs a simple dedicated server loop
|
Runs a simple dedicated server loop.
|
||||||
|
|
||||||
|
Shuts down when run is set to false.
|
||||||
*/
|
*/
|
||||||
void dedicated_server_loop(Server &server);
|
void dedicated_server_loop(Server &server, bool &run);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -98,7 +98,6 @@ std::ostream *derr_server_ptr = &dstream;
|
|||||||
std::ostream *dout_client_ptr = &dstream;
|
std::ostream *dout_client_ptr = &dstream;
|
||||||
std::ostream *derr_client_ptr = &dstream;
|
std::ostream *derr_client_ptr = &dstream;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
gettime.h implementation
|
gettime.h implementation
|
||||||
*/
|
*/
|
||||||
@ -129,6 +128,9 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
|
|
||||||
|
porting::signal_handler_init();
|
||||||
|
bool &kill = *porting::signal_handler_killstatus();
|
||||||
|
|
||||||
porting::initializePaths();
|
porting::initializePaths();
|
||||||
|
|
||||||
initializeMaterialProperties();
|
initializeMaterialProperties();
|
||||||
@ -251,6 +253,11 @@ int main(int argc, char *argv[])
|
|||||||
srand(time(0));
|
srand(time(0));
|
||||||
mysrand(time(0));
|
mysrand(time(0));
|
||||||
|
|
||||||
|
// Initialize stuff
|
||||||
|
|
||||||
|
init_mapnode();
|
||||||
|
init_mineral();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Run unit tests
|
Run unit tests
|
||||||
*/
|
*/
|
||||||
@ -260,11 +267,6 @@ int main(int argc, char *argv[])
|
|||||||
run_tests();
|
run_tests();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize stuff
|
|
||||||
|
|
||||||
init_mapnode();
|
|
||||||
init_mineral();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check parameters
|
Check parameters
|
||||||
*/
|
*/
|
||||||
@ -308,9 +310,9 @@ int main(int argc, char *argv[])
|
|||||||
// Create server
|
// Create server
|
||||||
Server server(map_dir.c_str());
|
Server server(map_dir.c_str());
|
||||||
server.start(port);
|
server.start(port);
|
||||||
|
|
||||||
// Run server
|
// Run server
|
||||||
dedicated_server_loop(server);
|
dedicated_server_loop(server, kill);
|
||||||
|
|
||||||
} //try
|
} //try
|
||||||
catch(con::PeerNotFoundException &e)
|
catch(con::PeerNotFoundException &e)
|
||||||
|
@ -192,7 +192,7 @@ struct TestMapNode
|
|||||||
// Transparency
|
// Transparency
|
||||||
n.d = CONTENT_AIR;
|
n.d = CONTENT_AIR;
|
||||||
assert(n.light_propagates() == true);
|
assert(n.light_propagates() == true);
|
||||||
n.d = 0;
|
n.d = CONTENT_STONE;
|
||||||
assert(n.light_propagates() == false);
|
assert(n.light_propagates() == false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -802,9 +802,15 @@ struct ValueSpec
|
|||||||
class Settings
|
class Settings
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Settings()
|
||||||
|
{
|
||||||
|
m_mutex.Init();
|
||||||
|
}
|
||||||
|
|
||||||
void writeLines(std::ostream &os)
|
void writeLines(std::ostream &os)
|
||||||
{
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
for(core::map<std::string, std::string>::Iterator
|
for(core::map<std::string, std::string>::Iterator
|
||||||
i = m_settings.getIterator();
|
i = m_settings.getIterator();
|
||||||
i.atEnd() == false; i++)
|
i.atEnd() == false; i++)
|
||||||
@ -817,6 +823,8 @@ public:
|
|||||||
|
|
||||||
bool parseConfigLine(const std::string &line)
|
bool parseConfigLine(const std::string &line)
|
||||||
{
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
std::string trimmedline = trim(line);
|
std::string trimmedline = trim(line);
|
||||||
|
|
||||||
// Ignore comments
|
// Ignore comments
|
||||||
@ -899,6 +907,8 @@ public:
|
|||||||
core::list<std::string> &dst,
|
core::list<std::string> &dst,
|
||||||
core::map<std::string, bool> &updated)
|
core::map<std::string, bool> &updated)
|
||||||
{
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
if(is.eof())
|
if(is.eof())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -981,6 +991,8 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
// Write stuff back
|
// Write stuff back
|
||||||
{
|
{
|
||||||
std::ofstream os(filename);
|
std::ofstream os(filename);
|
||||||
@ -1087,21 +1099,29 @@ public:
|
|||||||
|
|
||||||
void set(std::string name, std::string value)
|
void set(std::string name, std::string value)
|
||||||
{
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
m_settings[name] = value;
|
m_settings[name] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setDefault(std::string name, std::string value)
|
void setDefault(std::string name, std::string value)
|
||||||
{
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
m_defaults[name] = value;
|
m_defaults[name] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool exists(std::string name)
|
bool exists(std::string name)
|
||||||
{
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
return (m_settings.find(name) || m_defaults.find(name));
|
return (m_settings.find(name) || m_defaults.find(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string get(std::string name)
|
std::string get(std::string name)
|
||||||
{
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
core::map<std::string, std::string>::Node *n;
|
core::map<std::string, std::string>::Node *n;
|
||||||
n = m_settings.find(name);
|
n = m_settings.find(name);
|
||||||
if(n == NULL)
|
if(n == NULL)
|
||||||
@ -1139,7 +1159,7 @@ public:
|
|||||||
bool getBoolAsk(std::string name, std::string question, bool def)
|
bool getBoolAsk(std::string name, std::string question, bool def)
|
||||||
{
|
{
|
||||||
// If it is in settings
|
// If it is in settings
|
||||||
if(m_settings.find(name))
|
if(exists(name))
|
||||||
return getBool(name);
|
return getBool(name);
|
||||||
|
|
||||||
std::string s;
|
std::string s;
|
||||||
@ -1167,7 +1187,7 @@ public:
|
|||||||
u16 getU16Ask(std::string name, std::string question, u16 def)
|
u16 getU16Ask(std::string name, std::string question, u16 def)
|
||||||
{
|
{
|
||||||
// If it is in settings
|
// If it is in settings
|
||||||
if(m_settings.find(name))
|
if(exists(name))
|
||||||
return getU16(name);
|
return getU16(name);
|
||||||
|
|
||||||
std::string s;
|
std::string s;
|
||||||
@ -1238,12 +1258,17 @@ public:
|
|||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
m_settings.clear();
|
m_settings.clear();
|
||||||
m_defaults.clear();
|
m_defaults.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings & operator+=(Settings &other)
|
Settings & operator+=(Settings &other)
|
||||||
{
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
JMutexAutoLock lock2(other.m_mutex);
|
||||||
|
|
||||||
if(&other == this)
|
if(&other == this)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
@ -1267,6 +1292,9 @@ public:
|
|||||||
|
|
||||||
Settings & operator=(Settings &other)
|
Settings & operator=(Settings &other)
|
||||||
{
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
JMutexAutoLock lock2(other.m_mutex);
|
||||||
|
|
||||||
if(&other == this)
|
if(&other == this)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
@ -1279,6 +1307,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
core::map<std::string, std::string> m_settings;
|
core::map<std::string, std::string> m_settings;
|
||||||
core::map<std::string, std::string> m_defaults;
|
core::map<std::string, std::string> m_defaults;
|
||||||
|
// All methods that access m_settings/m_defaults directly should lock this.
|
||||||
|
JMutex m_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user