Ctrl+C handling on POSIX, some commands for server and other tweaking
parent
be7391c2b1
commit
d065bae323
|
@ -1,5 +1,7 @@
|
|||
Minetest-c55 changelog
|
||||
----------------------
|
||||
This should contain all the major changes.
|
||||
For minor stuff, refer to the commit log of the repository.
|
||||
|
||||
2011-02-14:
|
||||
- Created changelog.txt
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
|
||||
#map-dir = /home/palle/custom_map
|
||||
|
||||
#operator_name =
|
||||
|
||||
#plants_amount = 1.0
|
||||
#ravines_amount = 1.0
|
||||
#coal_amount = 1.0
|
||||
|
|
|
@ -5,6 +5,8 @@ if(RUN_IN_PLACE)
|
|||
add_definitions ( -DRUN_IN_PLACE )
|
||||
endif(RUN_IN_PLACE)
|
||||
|
||||
set(USE_GPROF 0 CACHE BOOL "Use -pg flag for g++")
|
||||
|
||||
# Use cmake_config.h
|
||||
add_definitions ( -DUSE_CMAKE_CONFIG_H )
|
||||
|
||||
|
@ -162,6 +164,10 @@ else()
|
|||
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")
|
||||
|
||||
if(USE_GPROF)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg")
|
||||
endif()
|
||||
|
||||
if(BUILD_SERVER)
|
||||
set_target_properties(minetestserver PROPERTIES
|
||||
COMPILE_FLAGS "-DSERVER")
|
||||
|
|
|
@ -174,11 +174,19 @@ bool GUIPauseMenu::OnEvent(const SEvent& event)
|
|||
{
|
||||
if(event.EventType==EET_KEY_INPUT_EVENT)
|
||||
{
|
||||
if(event.KeyInput.Key==KEY_ESCAPE && event.KeyInput.PressedDown)
|
||||
if(event.KeyInput.PressedDown)
|
||||
{
|
||||
if(event.KeyInput.Key==KEY_ESCAPE)
|
||||
{
|
||||
quitMenu();
|
||||
return true;
|
||||
}
|
||||
else if(event.KeyInput.Key==KEY_RETURN)
|
||||
{
|
||||
quitMenu();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
* not done
|
||||
|
||||
=== Stuff to do before release
|
||||
=== Fixmes
|
||||
* Make server find the spawning place from the real map data, not from
|
||||
the heightmap
|
||||
- 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
|
||||
* only_from_disk might not work anymore - check and fix it.
|
||||
* 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
|
||||
* Some MSVC: std::sto* are defined without a namespace and collide
|
||||
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
|
||||
* Move digging property stuff from material.{h,cpp} to mapnode.cpp...
|
||||
- Or maybe move content_features to material.{h,cpp}?
|
||||
|
@ -567,7 +567,25 @@ struct TextDestChat : public TextDest
|
|||
}
|
||||
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);
|
||||
// Show locally
|
||||
m_client->addChatMessage(text);
|
||||
}
|
||||
|
||||
|
@ -1546,6 +1564,9 @@ int main(int argc, char *argv[])
|
|||
|
||||
DSTACK(__FUNCTION_NAME);
|
||||
|
||||
porting::signal_handler_init();
|
||||
bool &kill = *porting::signal_handler_killstatus();
|
||||
|
||||
porting::initializePaths();
|
||||
// Create user data directory
|
||||
fs::CreateDir(porting::path_userdata);
|
||||
|
@ -1681,7 +1702,7 @@ int main(int argc, char *argv[])
|
|||
server.start(port);
|
||||
|
||||
// Run server
|
||||
dedicated_server_loop(server);
|
||||
dedicated_server_loop(server, kill);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1771,11 +1771,11 @@ void MapBlock::serialize(std::ostream &os, u8 version)
|
|||
// First byte
|
||||
u8 flags = 0;
|
||||
if(is_underground)
|
||||
flags |= 1;
|
||||
flags |= 0x01;
|
||||
if(m_day_night_differs)
|
||||
flags |= 2;
|
||||
flags |= 0x02;
|
||||
if(m_lighting_expired)
|
||||
flags |= 3;
|
||||
flags |= 0x04;
|
||||
os.write((char*)&flags, 1);
|
||||
|
||||
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
|
||||
|
@ -1895,9 +1895,9 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
|
|||
|
||||
u8 flags;
|
||||
is.read((char*)&flags, 1);
|
||||
is_underground = (flags & 1) ? true : false;
|
||||
m_day_night_differs = (flags & 2) ? true : false;
|
||||
m_lighting_expired = (flags & 3) ? true : false;
|
||||
is_underground = (flags & 0x01) ? true : false;
|
||||
m_day_night_differs = (flags & 0x02) ? true : false;
|
||||
m_lighting_expired = (flags & 0x04) ? true : false;
|
||||
|
||||
// Uncompress data
|
||||
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
|
||||
{
|
||||
|
||||
/*
|
||||
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_userdata = "../";
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#define PORTING_HEADER
|
||||
|
||||
#include <string>
|
||||
// Included for u64 and such
|
||||
// Included for u32 and such
|
||||
#include "common_irrlicht.h"
|
||||
#include "debug.h"
|
||||
#include "constants.h"
|
||||
|
@ -47,6 +47,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
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.
|
||||
*/
|
||||
|
|
218
src/server.cpp
218
src/server.cpp
|
@ -46,7 +46,12 @@ void * ServerThread::Thread()
|
|||
while(getRun())
|
||||
{
|
||||
try{
|
||||
//TimeTaker timer("AsyncRunStep() + Receive()");
|
||||
|
||||
{
|
||||
//TimeTaker timer("AsyncRunStep()");
|
||||
m_server->AsyncRunStep();
|
||||
}
|
||||
|
||||
//dout_server<<"Running m_server->Receive()"<<std::endl;
|
||||
m_server->Receive();
|
||||
|
@ -967,7 +972,8 @@ Server::Server(
|
|||
m_time_counter(0),
|
||||
m_time_of_day_send_timer(0),
|
||||
m_uptime(0),
|
||||
m_mapsavedir(mapsavedir)
|
||||
m_mapsavedir(mapsavedir),
|
||||
m_shutdown_requested(false)
|
||||
{
|
||||
//m_flowwater_timer = 0.0;
|
||||
m_liquid_transform_timer = 0.0;
|
||||
|
@ -987,12 +993,45 @@ 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);
|
||||
|
||||
// Stop threads
|
||||
/*
|
||||
Stop threads
|
||||
*/
|
||||
stop();
|
||||
|
||||
/*
|
||||
Delete clients
|
||||
*/
|
||||
{
|
||||
JMutexAutoLock clientslock(m_con_mutex);
|
||||
|
||||
for(core::map<u16, RemoteClient*>::Iterator
|
||||
|
@ -1011,6 +1050,7 @@ Server::~Server()
|
|||
delete i.getNode()->getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Server::start(unsigned short port)
|
||||
{
|
||||
|
@ -1588,37 +1628,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
}
|
||||
|
||||
// Send information about server to player in chat
|
||||
{
|
||||
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());
|
||||
}
|
||||
SendChatMessage(peer_id, getStatusString());
|
||||
|
||||
// Send information about joining in chat
|
||||
{
|
||||
|
@ -2462,12 +2472,94 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
// Get player name of this client
|
||||
std::wstring name = narrow_to_wide(player->getName());
|
||||
|
||||
std::wstring line = std::wstring(L"<")+name+L"> "+message;
|
||||
// Line to send to players
|
||||
std::wstring line;
|
||||
// Whether to send to the player that sent the line
|
||||
bool send_to_sender = false;
|
||||
// Whether to send to other players
|
||||
bool send_to_others = false;
|
||||
|
||||
// Parse commands
|
||||
std::wstring commandprefix = L"/#";
|
||||
if(message.substr(0, commandprefix.size()) == commandprefix)
|
||||
{
|
||||
line += L"Server: ";
|
||||
|
||||
message = message.substr(commandprefix.size());
|
||||
// Get player name as narrow string
|
||||
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;
|
||||
|
||||
/*
|
||||
Send the message to all other clients
|
||||
Send the message to clients
|
||||
*/
|
||||
for(core::map<u16, RemoteClient*>::Iterator
|
||||
i = m_clients.getIterator();
|
||||
|
@ -2479,13 +2571,17 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
if(client->serialization_version == SER_FMT_VER_INVALID)
|
||||
continue;
|
||||
|
||||
// Don't send if it's the same one
|
||||
if(peer_id == client->peer_id)
|
||||
// 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
|
||||
{
|
||||
derr_server<<"WARNING: Server::ProcessData(): Ignoring "
|
||||
|
@ -2580,6 +2676,7 @@ core::list<PlayerInfo> Server::getPlayerInfo()
|
|||
return list;
|
||||
}
|
||||
|
||||
|
||||
void Server::peerAdded(con::Peer *peer)
|
||||
{
|
||||
DSTACK(__FUNCTION_NAME);
|
||||
|
@ -3020,6 +3117,8 @@ void Server::SendBlocks(float dtime)
|
|||
|
||||
JMutexAutoLock envlock(m_env_mutex);
|
||||
|
||||
//TimeTaker timer("Server::SendBlocks");
|
||||
|
||||
core::array<PrioritySortedBlockTransfer> queue;
|
||||
|
||||
s32 total_sending = 0;
|
||||
|
@ -3087,6 +3186,39 @@ RemoteClient* Server::getClient(u16 peer_id)
|
|||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
std::cout<<std::endl;
|
||||
std::cout<<DTIME<<std::endl;
|
||||
std::cout<<"========================"<<std::endl;
|
||||
std::cout<<"Running dedicated server"<<std::endl;
|
||||
std::cout<<"========================"<<std::endl;
|
||||
|
@ -3472,6 +3604,12 @@ void dedicated_server_loop(Server &server)
|
|||
sleep_ms(30);
|
||||
server.step(0.030);
|
||||
|
||||
if(server.getShutdownRequested() || kill)
|
||||
{
|
||||
std::cout<<DTIME<<" dedicated_server_loop(): Quitting."<<std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
static int counter = 0;
|
||||
counter--;
|
||||
if(counter <= 0)
|
||||
|
|
22
src/server.h
22
src/server.h
|
@ -390,14 +390,10 @@ public:
|
|||
void Receive();
|
||||
void ProcessData(u8 *data, u32 datasize, u16 peer_id);
|
||||
|
||||
/*void Send(u16 peer_id, u16 channelnum,
|
||||
SharedBuffer<u8> data, bool reliable);*/
|
||||
|
||||
// Environment and Connection must be locked when called
|
||||
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();
|
||||
|
||||
|
@ -413,6 +409,11 @@ public:
|
|||
return 1000;
|
||||
}
|
||||
|
||||
bool getShutdownRequested()
|
||||
{
|
||||
return m_shutdown_requested.get();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Virtual methods from con::PeerHandler.
|
||||
|
@ -433,6 +434,9 @@ private:
|
|||
// When called, connection mutex should be locked
|
||||
RemoteClient* getClient(u16 peer_id);
|
||||
|
||||
// Connection must be locked when called
|
||||
std::wstring getStatusString();
|
||||
|
||||
/*
|
||||
Get a player from memory or creates one.
|
||||
If player is already connected, return NULL
|
||||
|
@ -508,14 +512,18 @@ private:
|
|||
|
||||
std::string m_mapsavedir;
|
||||
|
||||
MutexedVariable<bool> m_shutdown_requested;
|
||||
|
||||
friend class EmergeThread;
|
||||
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
|
||||
|
||||
|
|
|
@ -98,7 +98,6 @@ std::ostream *derr_server_ptr = &dstream;
|
|||
std::ostream *dout_client_ptr = &dstream;
|
||||
std::ostream *derr_client_ptr = &dstream;
|
||||
|
||||
|
||||
/*
|
||||
gettime.h implementation
|
||||
*/
|
||||
|
@ -129,6 +128,9 @@ int main(int argc, char *argv[])
|
|||
|
||||
DSTACK(__FUNCTION_NAME);
|
||||
|
||||
porting::signal_handler_init();
|
||||
bool &kill = *porting::signal_handler_killstatus();
|
||||
|
||||
porting::initializePaths();
|
||||
|
||||
initializeMaterialProperties();
|
||||
|
@ -251,6 +253,11 @@ int main(int argc, char *argv[])
|
|||
srand(time(0));
|
||||
mysrand(time(0));
|
||||
|
||||
// Initialize stuff
|
||||
|
||||
init_mapnode();
|
||||
init_mineral();
|
||||
|
||||
/*
|
||||
Run unit tests
|
||||
*/
|
||||
|
@ -260,11 +267,6 @@ int main(int argc, char *argv[])
|
|||
run_tests();
|
||||
}
|
||||
|
||||
// Initialize stuff
|
||||
|
||||
init_mapnode();
|
||||
init_mineral();
|
||||
|
||||
/*
|
||||
Check parameters
|
||||
*/
|
||||
|
@ -310,7 +312,7 @@ int main(int argc, char *argv[])
|
|||
server.start(port);
|
||||
|
||||
// Run server
|
||||
dedicated_server_loop(server);
|
||||
dedicated_server_loop(server, kill);
|
||||
|
||||
} //try
|
||||
catch(con::PeerNotFoundException &e)
|
||||
|
|
|
@ -192,7 +192,7 @@ struct TestMapNode
|
|||
// Transparency
|
||||
n.d = CONTENT_AIR;
|
||||
assert(n.light_propagates() == true);
|
||||
n.d = 0;
|
||||
n.d = CONTENT_STONE;
|
||||
assert(n.light_propagates() == false);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -802,9 +802,15 @@ struct ValueSpec
|
|||
class Settings
|
||||
{
|
||||
public:
|
||||
Settings()
|
||||
{
|
||||
m_mutex.Init();
|
||||
}
|
||||
|
||||
void writeLines(std::ostream &os)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
|
||||
for(core::map<std::string, std::string>::Iterator
|
||||
i = m_settings.getIterator();
|
||||
i.atEnd() == false; i++)
|
||||
|
@ -817,6 +823,8 @@ public:
|
|||
|
||||
bool parseConfigLine(const std::string &line)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
|
||||
std::string trimmedline = trim(line);
|
||||
|
||||
// Ignore comments
|
||||
|
@ -899,6 +907,8 @@ public:
|
|||
core::list<std::string> &dst,
|
||||
core::map<std::string, bool> &updated)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
|
||||
if(is.eof())
|
||||
return false;
|
||||
|
||||
|
@ -981,6 +991,8 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
|
||||
// Write stuff back
|
||||
{
|
||||
std::ofstream os(filename);
|
||||
|
@ -1087,21 +1099,29 @@ public:
|
|||
|
||||
void set(std::string name, std::string value)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
|
||||
m_settings[name] = value;
|
||||
}
|
||||
|
||||
void setDefault(std::string name, std::string value)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
|
||||
m_defaults[name] = value;
|
||||
}
|
||||
|
||||
bool exists(std::string name)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
|
||||
return (m_settings.find(name) || m_defaults.find(name));
|
||||
}
|
||||
|
||||
std::string get(std::string name)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
|
||||
core::map<std::string, std::string>::Node *n;
|
||||
n = m_settings.find(name);
|
||||
if(n == NULL)
|
||||
|
@ -1139,7 +1159,7 @@ public:
|
|||
bool getBoolAsk(std::string name, std::string question, bool def)
|
||||
{
|
||||
// If it is in settings
|
||||
if(m_settings.find(name))
|
||||
if(exists(name))
|
||||
return getBool(name);
|
||||
|
||||
std::string s;
|
||||
|
@ -1167,7 +1187,7 @@ public:
|
|||
u16 getU16Ask(std::string name, std::string question, u16 def)
|
||||
{
|
||||
// If it is in settings
|
||||
if(m_settings.find(name))
|
||||
if(exists(name))
|
||||
return getU16(name);
|
||||
|
||||
std::string s;
|
||||
|
@ -1238,12 +1258,17 @@ public:
|
|||
|
||||
void clear()
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
|
||||
m_settings.clear();
|
||||
m_defaults.clear();
|
||||
}
|
||||
|
||||
Settings & operator+=(Settings &other)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
JMutexAutoLock lock2(other.m_mutex);
|
||||
|
||||
if(&other == this)
|
||||
return *this;
|
||||
|
||||
|
@ -1267,6 +1292,9 @@ public:
|
|||
|
||||
Settings & operator=(Settings &other)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
JMutexAutoLock lock2(other.m_mutex);
|
||||
|
||||
if(&other == this)
|
||||
return *this;
|
||||
|
||||
|
@ -1279,6 +1307,8 @@ public:
|
|||
private:
|
||||
core::map<std::string, std::string> m_settings;
|
||||
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