forked from oerkki/voxelands
new ban manager
This commit is contained in:
parent
f0e36c0404
commit
7a7423825d
|
@ -166,6 +166,7 @@ configure_file(
|
|||
set(common_SRCS
|
||||
auth.c
|
||||
array.c
|
||||
ban.c
|
||||
list.c
|
||||
nvp.c
|
||||
crypto.c
|
||||
|
@ -224,7 +225,6 @@ set(common_SRCS
|
|||
test.cpp
|
||||
sha1.cpp
|
||||
base64.cpp
|
||||
ban.cpp
|
||||
http.cpp
|
||||
)
|
||||
|
||||
|
|
169
src/ban.cpp
169
src/ban.cpp
|
@ -1,169 +0,0 @@
|
|||
/************************************************************************
|
||||
* Minetest-c55
|
||||
* Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
*
|
||||
* ban.cpp
|
||||
* voxelands - 3d voxel world sandbox game
|
||||
* Copyright (C) Lisa 'darkrose' Milne 2014 <lisa@ltmnet.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
* License updated from GPLv2 or later to GPLv3 or later by Lisa Milne
|
||||
* for Voxelands.
|
||||
************************************************************************/
|
||||
|
||||
#include "ban.h"
|
||||
#include <fstream>
|
||||
#include <jmutexautolock.h>
|
||||
#include <sstream>
|
||||
#include <set>
|
||||
#include "strfnd.h"
|
||||
#include "debug.h"
|
||||
|
||||
BanManager::BanManager(const std::string &banfilepath):
|
||||
m_banfilepath(banfilepath),
|
||||
m_modified(false)
|
||||
{
|
||||
m_mutex.Init();
|
||||
try{
|
||||
load();
|
||||
}
|
||||
catch(SerializationError &e)
|
||||
{
|
||||
dstream<<"WARNING: BanManager: creating "
|
||||
<<m_banfilepath<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
BanManager::~BanManager()
|
||||
{
|
||||
save();
|
||||
}
|
||||
|
||||
void BanManager::load()
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
dstream<<"BanManager: loading from "<<m_banfilepath<<std::endl;
|
||||
std::ifstream is(m_banfilepath.c_str(), std::ios::binary);
|
||||
if(is.good() == false)
|
||||
{
|
||||
dstream<<"BanManager: failed loading from "<<m_banfilepath<<std::endl;
|
||||
throw SerializationError("BanManager::load(): Couldn't open file");
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if(is.eof() || is.good() == false)
|
||||
break;
|
||||
std::string line;
|
||||
std::getline(is, line, '\n');
|
||||
Strfnd f(line);
|
||||
std::string ip = trim(f.next("|"));
|
||||
std::string name = trim(f.next("|"));
|
||||
if(ip.empty())
|
||||
continue;
|
||||
m_ips[ip] = name;
|
||||
}
|
||||
m_modified = false;
|
||||
}
|
||||
|
||||
void BanManager::save()
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
dstream<<"BanManager: saving to "<<m_banfilepath<<std::endl;
|
||||
std::ofstream os(m_banfilepath.c_str(), std::ios::binary);
|
||||
|
||||
if(os.good() == false)
|
||||
{
|
||||
dstream<<"BanManager: failed loading from "<<m_banfilepath<<std::endl;
|
||||
throw SerializationError("BanManager::load(): Couldn't open file");
|
||||
}
|
||||
|
||||
for(std::map<std::string, std::string>::iterator
|
||||
i = m_ips.begin();
|
||||
i != m_ips.end(); i++)
|
||||
{
|
||||
os<<i->first<<"|"<<i->second<<"\n";
|
||||
}
|
||||
m_modified = false;
|
||||
}
|
||||
|
||||
bool BanManager::isIpBanned(const std::string &ip)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
return m_ips.find(ip) != m_ips.end();
|
||||
}
|
||||
|
||||
std::string BanManager::getBanDescription(const std::string &ip_or_name)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
std::string s = "";
|
||||
for(std::map<std::string, std::string>::iterator
|
||||
i = m_ips.begin();
|
||||
i != m_ips.end(); i++)
|
||||
{
|
||||
if(i->first == ip_or_name || i->second == ip_or_name
|
||||
|| ip_or_name == "")
|
||||
s += i->first + "|" + i->second + ", ";
|
||||
}
|
||||
s = s.substr(0, s.size()-2);
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string BanManager::getBanName(const std::string &ip)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
std::map<std::string, std::string>::iterator i = m_ips.find(ip);
|
||||
if(i == m_ips.end())
|
||||
return "";
|
||||
return i->second;
|
||||
}
|
||||
|
||||
void BanManager::add(const std::string &ip, const std::string &name)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
m_ips[ip] = name;
|
||||
m_modified = true;
|
||||
}
|
||||
|
||||
void BanManager::remove(const std::string &ip_or_name)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
//m_ips.erase(m_ips.find(ip));
|
||||
// Find out all ip-name pairs that match the ip or name
|
||||
std::set<std::string> ips_to_delete;
|
||||
for(std::map<std::string, std::string>::iterator
|
||||
i = m_ips.begin();
|
||||
i != m_ips.end(); i++)
|
||||
{
|
||||
if(i->first == ip_or_name || i->second == ip_or_name)
|
||||
ips_to_delete.insert(i->first);
|
||||
}
|
||||
// Erase them
|
||||
for(std::set<std::string>::iterator
|
||||
i = ips_to_delete.begin();
|
||||
i != ips_to_delete.end(); i++)
|
||||
{
|
||||
m_ips.erase(*i);
|
||||
}
|
||||
m_modified = true;
|
||||
}
|
||||
|
||||
|
||||
bool BanManager::isModified()
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
return m_modified;
|
||||
}
|
||||
|
73
src/ban.h
73
src/ban.h
|
@ -1,60 +1,23 @@
|
|||
/************************************************************************
|
||||
* Minetest-c55
|
||||
* Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
*
|
||||
* ban.h
|
||||
* voxelands - 3d voxel world sandbox game
|
||||
* Copyright (C) Lisa 'darkrose' Milne 2014 <lisa@ltmnet.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
* License updated from GPLv2 or later to GPLv3 or later by Lisa Milne
|
||||
* for Voxelands.
|
||||
************************************************************************/
|
||||
#ifndef _BAN_H_
|
||||
#define _BAN_H_
|
||||
|
||||
#ifndef BAN_HEADER
|
||||
#define BAN_HEADER
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <jthread.h>
|
||||
#include <jmutex.h>
|
||||
#include "common_irrlicht.h"
|
||||
#include "exceptions.h"
|
||||
/* defined in ban.c */
|
||||
int ban_init(char* file);
|
||||
void ban_exit(void);
|
||||
void ban_load(void);
|
||||
void ban_save(void);
|
||||
int ban_ipbanned(char* ip);
|
||||
int ban_description(char* ip_or_name, char* buff, int size);
|
||||
char* ban_ip2name(char* ip);
|
||||
void ban_add(char* ip, char* name);
|
||||
void ban_remove(char* ip_or_name);
|
||||
|
||||
using namespace jthread;
|
||||
|
||||
class BanManager
|
||||
{
|
||||
public:
|
||||
BanManager(const std::string &bannfilepath);
|
||||
~BanManager();
|
||||
void load();
|
||||
void save();
|
||||
bool isIpBanned(const std::string &ip);
|
||||
// Supplying ip_or_name = "" lists all bans.
|
||||
std::string getBanDescription(const std::string &ip_or_name);
|
||||
std::string getBanName(const std::string &ip);
|
||||
void add(const std::string &ip, const std::string &name);
|
||||
void remove(const std::string &ip_or_name);
|
||||
bool isModified();
|
||||
private:
|
||||
JMutex m_mutex;
|
||||
std::string m_banfilepath;
|
||||
std::map<std::string, std::string> m_ips;
|
||||
bool m_modified;
|
||||
|
||||
};
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "client.h"
|
||||
|
||||
#include "nvp.h"
|
||||
#include "path.h"
|
||||
|
||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||
|
||||
|
@ -331,30 +332,41 @@ ServerEnvironment::~ServerEnvironment()
|
|||
m_map->drop();
|
||||
}
|
||||
|
||||
void ServerEnvironment::serializePlayers(const std::string &savedir)
|
||||
void ServerEnvironment::serializePlayers()
|
||||
{
|
||||
std::string players_path = savedir + "/players";
|
||||
fs::CreateDir(players_path);
|
||||
Player *player;
|
||||
uint32_t i;
|
||||
|
||||
dirlist_t *list;
|
||||
dirlist_t *list_file;
|
||||
nvp_t *saved_players = NULL;
|
||||
char path[1024];
|
||||
|
||||
std::vector<fs::DirListNode> player_files = fs::GetDirListing(players_path);
|
||||
for (i=0; i<player_files.size(); i++) {
|
||||
if (player_files[i].dir)
|
||||
if (path_create((char*)"player",NULL)) {
|
||||
infostream<<"failed to open players path"<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
list = path_dirlist((char*)"player",NULL);
|
||||
list_file = list;
|
||||
|
||||
while (list_file) {
|
||||
if (list_file->dir) {
|
||||
list_file = list_file->next;
|
||||
continue;
|
||||
|
||||
// Full path to this file
|
||||
std::string path = players_path + "/" + player_files[i].name;
|
||||
}
|
||||
|
||||
// Load player to see what is its name
|
||||
ServerRemotePlayer testplayer;
|
||||
{
|
||||
if (!path_get((char*)"player",list_file->name,1,path,1024)) {
|
||||
list_file = list_file->next;
|
||||
continue;
|
||||
}
|
||||
// Open file and deserialize
|
||||
std::ifstream is(path.c_str(), std::ios_base::binary);
|
||||
std::ifstream is(path, std::ios_base::binary);
|
||||
if (is.good() == false) {
|
||||
infostream<<"Failed to read "<<path<<std::endl;
|
||||
list_file = list_file->next;
|
||||
continue;
|
||||
}
|
||||
testplayer.deSerialize(is);
|
||||
|
@ -366,7 +378,8 @@ void ServerEnvironment::serializePlayers(const std::string &savedir)
|
|||
std::string playername = testplayer.getName();
|
||||
player = getPlayer(playername.c_str());
|
||||
if (player == NULL) {
|
||||
fs::RecursiveDelete(path);
|
||||
path_remove(NULL,path);
|
||||
list_file = list_file->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -375,14 +388,16 @@ void ServerEnvironment::serializePlayers(const std::string &savedir)
|
|||
// OK, found. Save player there.
|
||||
{
|
||||
// Open file and serialize
|
||||
std::ofstream os(path.c_str(), std::ios_base::binary);
|
||||
std::ofstream os(path, std::ios_base::binary);
|
||||
if (os.good() == false) {
|
||||
infostream<<"Failed to overwrite "<<path<<std::endl;
|
||||
list_file = list_file->next;
|
||||
continue;
|
||||
}
|
||||
player->serialize(os);
|
||||
nvp_set(&saved_players, (char*)player->getName(), (char*)player->getName(), player);
|
||||
}
|
||||
list_file = list_file->next;
|
||||
}
|
||||
|
||||
for (i=0; i<m_players->length; i++) {
|
||||
|
@ -391,34 +406,17 @@ void ServerEnvironment::serializePlayers(const std::string &savedir)
|
|||
continue;
|
||||
if (nvp_get(&saved_players, (char*)player->getName()) != NULL)
|
||||
continue;
|
||||
std::string playername = player->getName();
|
||||
// Don't save unnamed player
|
||||
if (playername == "")
|
||||
char* playername = const_cast<char*>(player->getName());
|
||||
/* don't save unnamed player */
|
||||
if (!playername[0])
|
||||
continue;
|
||||
/*
|
||||
Find a sane filename
|
||||
*/
|
||||
/* ... or dodgy names */
|
||||
if (string_allowed(playername, PLAYERNAME_ALLOWED_CHARS) == false)
|
||||
playername = "player";
|
||||
std::string path = players_path + "/" + playername;
|
||||
bool found = false;
|
||||
for (u32 i=0; i<1000; i++) {
|
||||
if (fs::PathExists(path) == false) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
path = players_path + "/" + playername + itos(i);
|
||||
}
|
||||
if (found == false) {
|
||||
infostream<<"Didn't find free file for player"<<std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
{
|
||||
/*infostream<<"Saving player "<<player->getName()<<" to "
|
||||
<<path<<std::endl;*/
|
||||
if (path_get((char*)"player",playername,0,path,1024)) {
|
||||
// Open file and serialize
|
||||
std::ofstream os(path.c_str(), std::ios_base::binary);
|
||||
std::ofstream os(path, std::ios_base::binary);
|
||||
if (os.good() == false) {
|
||||
infostream<<"Failed to overwrite "<<path<<std::endl;
|
||||
continue;
|
||||
|
@ -432,36 +430,45 @@ void ServerEnvironment::serializePlayers(const std::string &savedir)
|
|||
|
||||
}
|
||||
|
||||
void ServerEnvironment::deSerializePlayers(const std::string &savedir)
|
||||
void ServerEnvironment::deSerializePlayers()
|
||||
{
|
||||
std::string players_path = savedir + "/players";
|
||||
|
||||
core::map<Player*, bool> saved_players;
|
||||
char path[1024];
|
||||
dirlist_t *list;
|
||||
dirlist_t *list_file;
|
||||
|
||||
std::vector<fs::DirListNode> player_files = fs::GetDirListing(players_path);
|
||||
for (u32 i=0; i<player_files.size(); i++) {
|
||||
if (player_files[i].dir)
|
||||
if (!path_get((char*)"player",NULL,1,path,1024))
|
||||
return;
|
||||
|
||||
list = path_dirlist((char*)"player",NULL);
|
||||
list_file = list;
|
||||
|
||||
while (list_file) {
|
||||
if (list_file->dir) {
|
||||
list_file = list_file->next;
|
||||
continue;
|
||||
|
||||
// Full path to this file
|
||||
std::string path = players_path + "/" + player_files[i].name;
|
||||
|
||||
infostream<<"Checking player file "<<path<<std::endl;
|
||||
}
|
||||
|
||||
// Load player to see what is its name
|
||||
ServerRemotePlayer testplayer;
|
||||
{
|
||||
if (!path_get((char*)"player",list_file->name,1,path,1024)) {
|
||||
list_file = list_file->next;
|
||||
continue;
|
||||
}
|
||||
// Open file and deserialize
|
||||
std::ifstream is(path.c_str(), std::ios_base::binary);
|
||||
std::ifstream is(path, std::ios_base::binary);
|
||||
if (is.good() == false) {
|
||||
infostream<<"Failed to read "<<path<<std::endl;
|
||||
list_file = list_file->next;
|
||||
continue;
|
||||
}
|
||||
testplayer.deSerialize(is);
|
||||
}
|
||||
|
||||
if (!string_allowed(testplayer.getName(), PLAYERNAME_ALLOWED_CHARS)) {
|
||||
fs::RecursiveDelete(path);
|
||||
path_remove(NULL,path);
|
||||
list_file = list_file->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -483,9 +490,10 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir)
|
|||
infostream<<"Reading player "<<testplayer.getName()<<" from "
|
||||
<<path<<std::endl;
|
||||
// Open file and deserialize
|
||||
std::ifstream is(path.c_str(), std::ios_base::binary);
|
||||
std::ifstream is(path, std::ios_base::binary);
|
||||
if (is.good() == false) {
|
||||
infostream<<"Failed to read "<<path<<std::endl;
|
||||
list_file = list_file->next;
|
||||
continue;
|
||||
}
|
||||
player->deSerialize(is);
|
||||
|
@ -493,19 +501,21 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir)
|
|||
|
||||
if (newplayer)
|
||||
addPlayer(player);
|
||||
list_file = list_file->next;
|
||||
}
|
||||
}
|
||||
|
||||
void ServerEnvironment::saveMeta(const std::string &savedir)
|
||||
void ServerEnvironment::saveMeta()
|
||||
{
|
||||
std::string path = savedir + "/env_meta.txt";
|
||||
char buff[1024];
|
||||
if (!path_get((char*)"world",(char*)"env_meta.txt",0,buff,1024))
|
||||
return;
|
||||
|
||||
// Open file and serialize
|
||||
std::ofstream os(path.c_str(), std::ios_base::binary);
|
||||
if(os.good() == false)
|
||||
{
|
||||
std::ofstream os(buff, std::ios_base::binary);
|
||||
if (os.good() == false) {
|
||||
infostream<<"ServerEnvironment::saveMeta(): Failed to open "
|
||||
<<path<<std::endl;
|
||||
<<buff<<std::endl;
|
||||
throw SerializationError("Couldn't save env meta");
|
||||
}
|
||||
|
||||
|
@ -517,16 +527,17 @@ void ServerEnvironment::saveMeta(const std::string &savedir)
|
|||
os<<"EnvArgsEnd\n";
|
||||
}
|
||||
|
||||
void ServerEnvironment::loadMeta(const std::string &savedir)
|
||||
void ServerEnvironment::loadMeta()
|
||||
{
|
||||
std::string path = savedir + "/env_meta.txt";
|
||||
char buff[1024];
|
||||
if (!path_get((char*)"world",(char*)"env_meta.txt",1,buff,1024))
|
||||
return;
|
||||
|
||||
// Open file and deserialize
|
||||
std::ifstream is(path.c_str(), std::ios_base::binary);
|
||||
if(is.good() == false)
|
||||
{
|
||||
std::ifstream is(buff, std::ios_base::binary);
|
||||
if (is.good() == false) {
|
||||
infostream<<"ServerEnvironment::loadMeta(): Failed to open "
|
||||
<<path<<std::endl;
|
||||
<<buff<<std::endl;
|
||||
throw SerializationError("Couldn't load env meta");
|
||||
}
|
||||
|
||||
|
|
|
@ -288,14 +288,14 @@ public:
|
|||
/*
|
||||
Save players
|
||||
*/
|
||||
void serializePlayers(const std::string &savedir);
|
||||
void deSerializePlayers(const std::string &savedir);
|
||||
void serializePlayers();
|
||||
void deSerializePlayers();
|
||||
|
||||
/*
|
||||
Save and load time of day and game timer
|
||||
*/
|
||||
void saveMeta(const std::string &savedir);
|
||||
void loadMeta(const std::string &savedir);
|
||||
void saveMeta();
|
||||
void loadMeta();
|
||||
|
||||
/*
|
||||
External ActiveObject interface
|
||||
|
|
|
@ -637,13 +637,11 @@ void the_game(
|
|||
InputHandler *input,
|
||||
IrrlichtDevice *device,
|
||||
gui::IGUIFont* font,
|
||||
std::string map_dir,
|
||||
std::string playername,
|
||||
std::string password,
|
||||
std::string address,
|
||||
u16 port,
|
||||
std::wstring &error_message,
|
||||
std::string configpath,
|
||||
ISoundManager *sound
|
||||
)
|
||||
{
|
||||
|
@ -675,7 +673,7 @@ void the_game(
|
|||
//draw_load_screen(L"Creating server...", driver, font);
|
||||
drawLoadingScreen(device,narrow_to_wide(gettext("Creating server...")));
|
||||
infostream<<"Creating server"<<std::endl;
|
||||
server = new Server(map_dir, configpath);
|
||||
server = new Server();
|
||||
server->start(port);
|
||||
}
|
||||
|
||||
|
|
|
@ -139,13 +139,11 @@ void the_game(
|
|||
InputHandler *input,
|
||||
IrrlichtDevice *device,
|
||||
gui::IGUIFont* font,
|
||||
std::string map_dir,
|
||||
std::string playername,
|
||||
std::string password,
|
||||
std::string address,
|
||||
u16 port,
|
||||
std::wstring &error_message,
|
||||
std::string configpath,
|
||||
ISoundManager *sound
|
||||
);
|
||||
|
||||
|
|
90
src/main.cpp
90
src/main.cpp
|
@ -828,26 +828,17 @@ int main(int argc, char *argv[])
|
|||
porting::signal_handler_init();
|
||||
bool &kill = *porting::signal_handler_killstatus();
|
||||
|
||||
// Initialize porting::path_data, porting::path_userdata and porting::userconfig
|
||||
porting::initializePaths(argv[0]);
|
||||
|
||||
// Create user data directory
|
||||
fs::CreateDir(porting::path_userdata);
|
||||
|
||||
#if defined(__FreeBSD__) || defined(linux)
|
||||
// Create user config directory
|
||||
fs::CreateDir(porting::path_configdata);
|
||||
#endif
|
||||
|
||||
thread_init();
|
||||
path_init();
|
||||
intl_init();
|
||||
|
||||
// Initialize debug streams
|
||||
#ifdef RUN_IN_PLACE
|
||||
std::string debugfile = DEBUGFILE;
|
||||
#else
|
||||
std::string debugfile = porting::path_userdata+DIR_DELIM+DEBUGFILE;
|
||||
#endif
|
||||
debugstreams_init(disable_stderr, debugfile.c_str());
|
||||
{
|
||||
char buff[1024];
|
||||
if (!path_get(NULL,(char*)"debug.txt",0,buff,1024))
|
||||
return 1;
|
||||
debugstreams_init(disable_stderr, buff);
|
||||
}
|
||||
// Initialize debug stacks
|
||||
debug_stacks_init();
|
||||
|
||||
|
@ -869,9 +860,6 @@ int main(int argc, char *argv[])
|
|||
Basic initialization
|
||||
*/
|
||||
|
||||
thread_init();
|
||||
path_init();
|
||||
|
||||
// Initialize default settings
|
||||
set_default_settings(g_settings);
|
||||
|
||||
|
@ -883,37 +871,10 @@ int main(int argc, char *argv[])
|
|||
Read config file
|
||||
*/
|
||||
|
||||
// Path of configuration file in use
|
||||
std::string configpath = "";
|
||||
|
||||
if (cmd_args.exists("config")) {
|
||||
bool r = g_settings->readConfigFile(cmd_args.get("config").c_str());
|
||||
if (r == false) {
|
||||
errorstream<<"Could not read configuration from \""
|
||||
<<cmd_args.get("config")<<"\""<<std::endl;
|
||||
return 1;
|
||||
}
|
||||
configpath = cmd_args.get("config");
|
||||
}else{
|
||||
core::array<std::string> filenames;
|
||||
filenames.push_back(porting::path_configdata +
|
||||
DIR_DELIM + "voxelands.conf");
|
||||
#ifdef RUN_IN_PLACE
|
||||
filenames.push_back(porting::path_configdata +
|
||||
DIR_DELIM + ".." + DIR_DELIM + "voxelands.conf");
|
||||
#endif
|
||||
|
||||
for (u32 i=0; i<filenames.size(); i++) {
|
||||
bool r = g_settings->readConfigFile(filenames[i].c_str());
|
||||
if (r) {
|
||||
configpath = filenames[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If no path found, use the first one (menu creates the file)
|
||||
if (configpath == "")
|
||||
configpath = filenames[0];
|
||||
{
|
||||
char buff[1024];
|
||||
if (path_get((char*)"config",(char*)"voxelands.conf",0,buff,1024))
|
||||
g_settings->readConfigFile(buff);
|
||||
}
|
||||
|
||||
// Initialize random seed
|
||||
|
@ -970,13 +931,8 @@ int main(int argc, char *argv[])
|
|||
if (port == 0)
|
||||
port = 30000;
|
||||
|
||||
// Map directory
|
||||
std::string map_dir = porting::path_userdata+DIR_DELIM+"world";
|
||||
if (cmd_args.exists("map-dir")) {
|
||||
map_dir = cmd_args.get("map-dir");
|
||||
}else if (g_settings->exists("map-dir")) {
|
||||
map_dir = g_settings->get("map-dir");
|
||||
}
|
||||
/* TODO: configise this */
|
||||
path_world_setter((char*)"default");
|
||||
|
||||
// Run dedicated server if asked to
|
||||
if (cmd_args.getFlag("server")) {
|
||||
|
@ -986,7 +942,7 @@ int main(int argc, char *argv[])
|
|||
g_timegetter = new SimpleTimeGetter();
|
||||
|
||||
// Create server
|
||||
Server server(map_dir.c_str(), configpath);
|
||||
Server server;
|
||||
server.start(port);
|
||||
|
||||
// Run server
|
||||
|
@ -1341,8 +1297,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
// Delete map if requested
|
||||
if (menudata.delete_map) {
|
||||
bool r = fs::RecursiveDeleteContent(map_dir);
|
||||
if(r == false) {
|
||||
if (path_remove((char*)"world",NULL)) {
|
||||
error_message = L"Map deletion failed";
|
||||
continue;
|
||||
}
|
||||
|
@ -1350,9 +1305,7 @@ int main(int argc, char *argv[])
|
|||
g_settings->set("fixed_map_seed",wide_to_narrow(menudata.fixed_seed));
|
||||
g_settings->set("mapgen_type",menudata.map_type);
|
||||
}else if (menudata.clear_map) {
|
||||
std::string map_file = map_dir+DIR_DELIM+"map.sqlite";
|
||||
bool r = fs::RecursiveDelete(map_file);
|
||||
if(r == false) {
|
||||
if (path_remove((char*)"world",(char*)"map.sqlite")) {
|
||||
error_message = L"Map clearing failed";
|
||||
continue;
|
||||
}
|
||||
|
@ -1385,8 +1338,11 @@ int main(int argc, char *argv[])
|
|||
g_settings->set("address", address);
|
||||
g_settings->set("port", itos(port));
|
||||
// Update configuration file
|
||||
if (configpath != "")
|
||||
g_settings->updateConfigFile(configpath.c_str());
|
||||
{
|
||||
char buff[1024];
|
||||
if (path_get((char*)"config",(char*)"voxelands.conf",0,buff,1024))
|
||||
g_settings->updateConfigFile(buff);
|
||||
}
|
||||
|
||||
// Continue to game
|
||||
break;
|
||||
|
@ -1447,13 +1403,11 @@ int main(int argc, char *argv[])
|
|||
input,
|
||||
device,
|
||||
font,
|
||||
map_dir,
|
||||
playername,
|
||||
password,
|
||||
address,
|
||||
port,
|
||||
error_message,
|
||||
configpath,
|
||||
sound
|
||||
);
|
||||
|
||||
|
|
130
src/map.cpp
130
src/map.cpp
|
@ -45,6 +45,7 @@
|
|||
#include "profiler.h"
|
||||
#include "inventory.h"
|
||||
#include "enchantment.h"
|
||||
#include "path.h"
|
||||
|
||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||
|
||||
|
@ -1682,7 +1683,7 @@ void Map::nodeMetadataStep(float dtime, core::map<v3s16, MapBlock*> &changed_blo
|
|||
ServerMap
|
||||
*/
|
||||
|
||||
ServerMap::ServerMap(std::string savedir):
|
||||
ServerMap::ServerMap():
|
||||
Map(dout_server),
|
||||
m_seed(0),
|
||||
m_map_metadata_changed(true),
|
||||
|
@ -1733,23 +1734,25 @@ ServerMap::ServerMap(std::string savedir):
|
|||
Try to load map; if not found, create a new one.
|
||||
*/
|
||||
|
||||
m_savedir = savedir;
|
||||
m_map_saving_enabled = false;
|
||||
|
||||
try
|
||||
{
|
||||
try{
|
||||
// If directory exists, check contents and load if possible
|
||||
if(fs::PathExists(m_savedir))
|
||||
{
|
||||
char buff[1024];
|
||||
if (path_get((char*)"world",NULL,1,buff,1024)) {
|
||||
// If directory is empty, it is safe to save into it.
|
||||
if(fs::GetDirListing(m_savedir).size() == 0)
|
||||
{
|
||||
char b[1024];
|
||||
if (
|
||||
!path_get((char*)"world",(char*)"map_meta.txt",1,b,1024)
|
||||
&& !path_get((char*)"world",(char*)"map.sqlite",1,b,1024)
|
||||
&& !path_get((char*)"world",(char*)"auth.txt",1,b,1024)
|
||||
&& !path_get((char*)"world",(char*)"ipban.txt",1,b,1024)
|
||||
&& !path_get((char*)"world",(char*)"env_meta.txt",1,b,1024)
|
||||
) {
|
||||
infostream<<"Server: Empty save directory is valid."
|
||||
<<std::endl;
|
||||
m_map_saving_enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
}else{
|
||||
try{
|
||||
// Load map metadata (seed, type, chunksize)
|
||||
loadMapMeta();
|
||||
|
@ -1761,24 +1764,8 @@ ServerMap::ServerMap(std::string savedir):
|
|||
//m_chunksize = 0;
|
||||
}
|
||||
|
||||
/*try{
|
||||
// Load chunk metadata
|
||||
loadChunkMeta();
|
||||
}
|
||||
catch(FileNotGoodException &e){
|
||||
infostream<<"WARNING: Could not load chunk metadata."
|
||||
<<" Disabling chunk-based generator."
|
||||
<<std::endl;
|
||||
m_chunksize = 0;
|
||||
}*/
|
||||
|
||||
/*infostream<<"Server: Successfully loaded chunk "
|
||||
"metadata and sector (0,0) from "<<savedir<<
|
||||
", assuming valid save directory."
|
||||
<<std::endl;*/
|
||||
|
||||
infostream<<"Server: Successfully loaded map "
|
||||
<<"and chunk metadata from "<<savedir
|
||||
<<"and chunk metadata from "<<buff
|
||||
<<", assuming valid save directory."
|
||||
<<std::endl;
|
||||
|
||||
|
@ -1786,16 +1773,14 @@ ServerMap::ServerMap(std::string savedir):
|
|||
// Map loaded, not creating new one
|
||||
return;
|
||||
}
|
||||
}
|
||||
// If directory doesn't exist, it is safe to save to it
|
||||
else{
|
||||
}else{
|
||||
m_map_saving_enabled = true;
|
||||
}
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
infostream<<"WARNING: Server: Failed to load map from "<<savedir
|
||||
<<", exception: "<<e.what()<<std::endl;
|
||||
infostream<<"WARNING: Server: Failed to load map, exception: "<<e.what()<<std::endl;
|
||||
infostream<<"Please remove the map or fix it."<<std::endl;
|
||||
infostream<<"WARNING: Map saving will be disabled."<<std::endl;
|
||||
}
|
||||
|
@ -1813,23 +1798,18 @@ ServerMap::~ServerMap()
|
|||
{
|
||||
infostream<<__FUNCTION_NAME<<std::endl;
|
||||
|
||||
try
|
||||
{
|
||||
if(m_map_saving_enabled)
|
||||
{
|
||||
try{
|
||||
if (m_map_saving_enabled) {
|
||||
// Save only changed parts
|
||||
save(true);
|
||||
infostream<<"Server: saved map to "<<m_savedir<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
infostream<<"Server: saved map"<<std::endl;
|
||||
}else{
|
||||
infostream<<"Server: map not saved"<<std::endl;
|
||||
}
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
infostream<<"Server: Failed to save map to "<<m_savedir
|
||||
<<", exception: "<<e.what()<<std::endl;
|
||||
infostream<<"Server: Failed to save map, exception: "<<e.what()<<std::endl;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2332,7 +2312,7 @@ void ServerMap::verifyDatabase() {
|
|||
return;
|
||||
|
||||
{
|
||||
std::string dbp = m_savedir + DIR_DELIM + "map.sqlite";
|
||||
char buff[1024];
|
||||
bool needs_create = false;
|
||||
int d;
|
||||
|
||||
|
@ -2340,12 +2320,16 @@ void ServerMap::verifyDatabase() {
|
|||
Open the database connection
|
||||
*/
|
||||
|
||||
createDirs(m_savedir);
|
||||
if (!path_get((char*)"world",(char*)"map.sqlite",0,buff,1024))
|
||||
throw FileNotGoodException("map.sqlite: Cannot find database file path");
|
||||
|
||||
if(!fs::PathExists(dbp))
|
||||
if (path_create((char*)"world",NULL))
|
||||
throw FileNotGoodException("map.sqlite: Cannot create database file path");
|
||||
|
||||
if (!path_exists(buff))
|
||||
needs_create = true;
|
||||
|
||||
d = sqlite3_open_v2(dbp.c_str(), &m_database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
|
||||
d = sqlite3_open_v2(buff, &m_database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
|
||||
if(d != SQLITE_OK) {
|
||||
infostream<<"WARNING: Database failed to open: "<<sqlite3_errmsg(m_database)<<std::endl;
|
||||
throw FileNotGoodException("map.sqlite: Cannot open database file");
|
||||
|
@ -2391,28 +2375,6 @@ void ServerMap::createDirs(std::string path)
|
|||
}
|
||||
}
|
||||
|
||||
std::string ServerMap::getSectorDir(v2s16 pos, int layout)
|
||||
{
|
||||
char cc[9];
|
||||
switch(layout)
|
||||
{
|
||||
case 1:
|
||||
snprintf(cc, 9, "%.4x%.4x",
|
||||
(unsigned int)pos.X&0xffff,
|
||||
(unsigned int)pos.Y&0xffff);
|
||||
|
||||
return m_savedir + DIR_DELIM + "sectors" + DIR_DELIM + cc;
|
||||
case 2:
|
||||
snprintf(cc, 9, "%.3x" DIR_DELIM "%.3x",
|
||||
(unsigned int)pos.X&0xfff,
|
||||
(unsigned int)pos.Y&0xfff);
|
||||
|
||||
return m_savedir + DIR_DELIM + "sectors2" + DIR_DELIM + cc;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
v2s16 ServerMap::getSectorPos(std::string dirname)
|
||||
{
|
||||
unsigned int x, y;
|
||||
|
@ -2568,14 +2530,17 @@ void ServerMap::saveMapMeta()
|
|||
<<"seed="<<m_seed
|
||||
<<std::endl;
|
||||
|
||||
createDirs(m_savedir);
|
||||
|
||||
std::string fullpath = m_savedir + DIR_DELIM + "map_meta.txt";
|
||||
std::ofstream os(fullpath.c_str(), std::ios_base::binary);
|
||||
if(os.good() == false)
|
||||
{
|
||||
char buff[1024];
|
||||
if (!path_get((char*)"world",(char*)"map_meta.txt",0,buff,1024)) {
|
||||
infostream<<"ERROR: ServerMap::saveMapMeta(): "
|
||||
<<"could not open"<<fullpath<<std::endl;
|
||||
<<"could not find map_meta.txt"<<std::endl;
|
||||
throw FileNotGoodException("Cannot find chunk metadata");
|
||||
}
|
||||
|
||||
std::ofstream os(buff, std::ios_base::binary);
|
||||
if (os.good() == false) {
|
||||
infostream<<"ERROR: ServerMap::saveMapMeta(): "
|
||||
<<"could not open map_meta.txt"<<std::endl;
|
||||
throw FileNotGoodException("Cannot open chunk metadata");
|
||||
}
|
||||
|
||||
|
@ -2618,14 +2583,19 @@ void ServerMap::loadMapMeta()
|
|||
{
|
||||
DSTACK(__FUNCTION_NAME);
|
||||
|
||||
infostream<<"ServerMap::loadMapMeta(): Loading map metadata"
|
||||
<<std::endl;
|
||||
infostream<<"ServerMap::loadMapMeta(): Loading map metadata"<<std::endl;
|
||||
|
||||
std::string fullpath = m_savedir + DIR_DELIM + "map_meta.txt";
|
||||
std::ifstream is(fullpath.c_str(), std::ios_base::binary);
|
||||
char buff[1024];
|
||||
if (!path_get((char*)"world",(char*)"map_meta.txt",0,buff,1024)) {
|
||||
infostream<<"ERROR: ServerMap::saveMapMeta(): "
|
||||
<<"could not find map_meta.txt"<<std::endl;
|
||||
throw FileNotGoodException("Cannot find chunk metadata");
|
||||
}
|
||||
|
||||
std::ifstream is(buff, std::ios_base::binary);
|
||||
if (is.good() == false) {
|
||||
infostream<<"ERROR: ServerMap::loadMapMeta(): "
|
||||
<<"could not open"<<fullpath<<std::endl;
|
||||
<<"could not open map_meta.txt"<<std::endl;
|
||||
throw FileNotGoodException("Cannot open map metadata");
|
||||
}
|
||||
|
||||
|
|
|
@ -322,10 +322,7 @@ protected:
|
|||
class ServerMap : public Map
|
||||
{
|
||||
public:
|
||||
/*
|
||||
savedir: directory to which map data should be saved
|
||||
*/
|
||||
ServerMap(std::string savedir);
|
||||
ServerMap();
|
||||
~ServerMap();
|
||||
|
||||
s32 mapType() const
|
||||
|
@ -428,7 +425,6 @@ private:
|
|||
uint64_t m_seed;
|
||||
MapGenType m_type;
|
||||
|
||||
std::string m_savedir;
|
||||
bool m_map_saving_enabled;
|
||||
|
||||
/*
|
||||
|
|
45
src/path.c
45
src/path.c
|
@ -136,8 +136,15 @@ static char* path_set(char* base, char* rel, char* buff, int size)
|
|||
int l;
|
||||
char path[2048];
|
||||
|
||||
if (!base && !rel)
|
||||
return NULL;
|
||||
|
||||
if (base) {
|
||||
l = snprintf(path,2048,"%s/%s",base,rel);
|
||||
if (rel) {
|
||||
l = snprintf(path,2048,"%s/%s",base,rel);
|
||||
}else{
|
||||
l = snprintf(path,2048,"%s",base);
|
||||
}
|
||||
}else{
|
||||
l = snprintf(path,2048,"%s",rel);
|
||||
}
|
||||
|
@ -195,6 +202,7 @@ static int dir_create(char* path)
|
|||
return 1;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
if ((dir_create(up) == 1) && (errno != EEXIST))
|
||||
goto out;
|
||||
|
||||
|
@ -251,6 +259,7 @@ int path_init()
|
|||
}else{
|
||||
path.data_user = path_set(path.cwd,"data",NULL,0);
|
||||
}
|
||||
path_create(NULL,path.data_user);
|
||||
|
||||
path.config = getenv("XDG_CONFIG_HOME");
|
||||
if (path.config) {
|
||||
|
@ -260,6 +269,7 @@ int path_init()
|
|||
}else{
|
||||
path.config = strdup(path.cwd);
|
||||
}
|
||||
path_create(NULL,path.config);
|
||||
#else
|
||||
/* TODO: windows, and mac? */
|
||||
#endif
|
||||
|
@ -392,10 +402,10 @@ char* path_get(char* type, char* file, int must_exist, char* buff, int size)
|
|||
{
|
||||
char rel_path[1024];
|
||||
|
||||
if (!file)
|
||||
if (!file && !type)
|
||||
return NULL;
|
||||
|
||||
if (file[0] == '/') {
|
||||
if (file && file[0] == '/') {
|
||||
return path_set(NULL,file,buff,size);
|
||||
}else if (!type) {
|
||||
strcpy(rel_path,file);
|
||||
|
@ -403,6 +413,25 @@ char* path_get(char* type, char* file, int must_exist, char* buff, int size)
|
|||
if (path.world && (!must_exist || path_check(path.world,file)))
|
||||
return path_set(path.world,file,buff,size);
|
||||
return NULL;
|
||||
}else if (!strcmp(type,"player")) {
|
||||
int ck;
|
||||
if (!path.world)
|
||||
return NULL;
|
||||
ck = path_check(path.world,"players");
|
||||
if (!ck) {
|
||||
}
|
||||
|
||||
if (ck != 2)
|
||||
return NULL;
|
||||
|
||||
if (file) {
|
||||
if (snprintf(rel_path,1024,"players/%s",file) >= 1024)
|
||||
return NULL;
|
||||
}else{
|
||||
strcpy(rel_path,"players");
|
||||
}
|
||||
|
||||
return path_set(path.world,rel_path,buff,size);
|
||||
}else if (!strcmp(type,"worlds")) {
|
||||
char* base = path.data_user;
|
||||
if (!base)
|
||||
|
@ -413,8 +442,12 @@ char* path_get(char* type, char* file, int must_exist, char* buff, int size)
|
|||
base = path.cwd;
|
||||
if (!base)
|
||||
return NULL;
|
||||
if (snprintf(rel_path,1024,"worlds/%s",file) >= 1024)
|
||||
return NULL;
|
||||
if (file) {
|
||||
if (snprintf(rel_path,1024,"worlds/%s",file) >= 1024)
|
||||
return NULL;
|
||||
}else{
|
||||
strcpy(rel_path,"worlds");
|
||||
}
|
||||
if (!must_exist || path_check(base,rel_path) == 2)
|
||||
return path_set(base,rel_path,buff,size);
|
||||
return NULL;
|
||||
|
@ -433,6 +466,8 @@ char* path_get(char* type, char* file, int must_exist, char* buff, int size)
|
|||
if (path.config && (!must_exist || path_check(path.config,file)))
|
||||
return path_set(path.config,file,buff,size);
|
||||
return NULL;
|
||||
}else if (!file) {
|
||||
return NULL;
|
||||
}else if (!strcmp(type,"model")) {
|
||||
snprintf(rel_path,1024,"models/%s",file);
|
||||
}else if (!strcmp(type,"texture")) {
|
||||
|
|
347
src/porting.cpp
347
src/porting.cpp
|
@ -120,353 +120,6 @@ void signal_handler_init(void)
|
|||
|
||||
#endif
|
||||
|
||||
/*
|
||||
Path mangler
|
||||
*/
|
||||
|
||||
std::string path_data = ".." DIR_DELIM "data";
|
||||
std::string path_configdata = "..";
|
||||
std::string path_userdata = "..";
|
||||
|
||||
std::string getDataPath(const char *subpath)
|
||||
{
|
||||
return path_data + DIR_DELIM + subpath;
|
||||
}
|
||||
|
||||
void pathRemoveFile(char *path, char delim)
|
||||
{
|
||||
// Remove filename and path delimiter
|
||||
int i = strlen(path)-1;
|
||||
for (; i>=0; i--) {
|
||||
if (path[i] == delim)
|
||||
break;
|
||||
}
|
||||
path[i] = 0;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
char* posix_guess_path(char* argv0)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
size_t l = BUFSIZ;
|
||||
buf[0] = 0;
|
||||
|
||||
if (argv0[0] != '/') {
|
||||
if (!getcwd(buf,BUFSIZ))
|
||||
return strdup("..");
|
||||
l -= (strlen(buf)+1);
|
||||
strncat(buf,"/",l);
|
||||
l--;
|
||||
}
|
||||
|
||||
strncat(buf,argv0,l);
|
||||
pathRemoveFile(buf, '/');
|
||||
pathRemoveFile(buf, '/');
|
||||
|
||||
/* get rid of any path trickery */
|
||||
if (strstr(buf,"..")) {
|
||||
char buff[BUFSIZ];
|
||||
char* t;
|
||||
strcpy(buff,buf);
|
||||
buf[0] = 0;
|
||||
t = strtok(buff,"/");
|
||||
while (t) {
|
||||
if (!strcmp(t,"..")) {
|
||||
pathRemoveFile(buf,'/');
|
||||
}else{
|
||||
strcat(buf,"/");
|
||||
strcat(buf,t);
|
||||
}
|
||||
t = strtok(NULL,"/");
|
||||
}
|
||||
}
|
||||
|
||||
return strdup(buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
void initializePaths(char* argv0)
|
||||
{
|
||||
#ifdef RUN_IN_PLACE
|
||||
/*
|
||||
Use relative paths if RUN_IN_PLACE
|
||||
*/
|
||||
|
||||
dstream<<"Using relative paths (RUN_IN_PLACE)"<<std::endl;
|
||||
|
||||
/*
|
||||
Windows
|
||||
*/
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
|
||||
const DWORD buflen = 1000;
|
||||
char buf[buflen];
|
||||
DWORD len;
|
||||
|
||||
// Find path of executable and set path_data relative to it
|
||||
len = GetModuleFileName(GetModuleHandle(NULL), buf, buflen);
|
||||
assert(len < buflen);
|
||||
pathRemoveFile(buf, '\\');
|
||||
pathRemoveFile(buf, '\\');
|
||||
|
||||
// Use "./bin/../data"
|
||||
path_data = std::string(buf) + DIR_DELIM + "data";
|
||||
|
||||
// Use "./bin/.."
|
||||
path_userdata = std::string(buf);
|
||||
path_configdata = std::string(buf);
|
||||
|
||||
/*
|
||||
Linux
|
||||
*/
|
||||
#elif defined(linux) || defined(__linux)
|
||||
#include <unistd.h>
|
||||
|
||||
char buf[BUFSIZ];
|
||||
memset(buf, 0, BUFSIZ);
|
||||
// Get path to executable
|
||||
if (readlink("/proc/self/exe", buf, BUFSIZ-1) < 0) {
|
||||
char* b = posix_guess_path(argv0);
|
||||
if (!b) {
|
||||
strcpy(buf,"..");
|
||||
}else{
|
||||
strcpy(buf,b);
|
||||
free(b);
|
||||
}
|
||||
}else{
|
||||
pathRemoveFile(buf, '/');
|
||||
pathRemoveFile(buf, '/');
|
||||
}
|
||||
|
||||
// Use "./bin/../data"
|
||||
path_data = std::string(buf) + "/data";
|
||||
|
||||
// Use "./bin/../"
|
||||
path_userdata = std::string(buf);
|
||||
path_configdata = std::string(buf);
|
||||
|
||||
/*
|
||||
OS X
|
||||
*/
|
||||
#elif defined(__APPLE__) || defined(__FreeBSD__)
|
||||
|
||||
const int info[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
|
||||
char* path = NULL;
|
||||
size_t size = 0;
|
||||
|
||||
if (!sysctl(info, 4, NULL, &size, NULL, 0)) {
|
||||
path = (char*)malloc(size);
|
||||
if (path) {
|
||||
if (!sysctl(info, 4, path, &size, NULL, 0)) {
|
||||
pathRemoveFile(path, '/');
|
||||
pathRemoveFile(path, '/');
|
||||
}else{
|
||||
free(path);
|
||||
path = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!path)
|
||||
path = posix_guess_path(argv0);
|
||||
|
||||
if (path) {
|
||||
path_userdata = std::string(path);
|
||||
path_configdata = std::string(path);
|
||||
path_data = std::string(path) + "/data";
|
||||
|
||||
free(path);
|
||||
}else{
|
||||
path_userdata = std::string("..");
|
||||
path_configdata = std::string("..");
|
||||
path_data = std::string("../data");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#else // RUN_IN_PLACE
|
||||
|
||||
/*
|
||||
Use platform-specific paths otherwise
|
||||
*/
|
||||
|
||||
dstream<<"Using system-wide paths (NOT RUN_IN_PLACE)"<<std::endl;
|
||||
|
||||
/*
|
||||
Windows
|
||||
*/
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
|
||||
const DWORD buflen = 1000;
|
||||
char buf[buflen];
|
||||
DWORD len;
|
||||
|
||||
// Find path of executable and set path_data relative to it
|
||||
len = GetModuleFileName(GetModuleHandle(NULL), buf, buflen);
|
||||
assert(len < buflen);
|
||||
pathRemoveFile(buf, '\\');
|
||||
|
||||
// Use "./bin/../data"
|
||||
path_data = std::string(buf) + DIR_DELIM ".." DIR_DELIM "data";
|
||||
path_configdata = std::string(buf) + DIR_DELIM + PROJECT_NAME;
|
||||
//path_data = std::string(buf) + "/../share/" + PROJECT_NAME;
|
||||
|
||||
// Use "C:\Documents and Settings\user\Application Data\<PROJECT_NAME>"
|
||||
len = GetEnvironmentVariable("APPDATA", buf, buflen);
|
||||
assert(len < buflen);
|
||||
path_userdata = std::string(buf) + DIR_DELIM + PROJECT_NAME;
|
||||
|
||||
/*
|
||||
Linux
|
||||
*/
|
||||
#elif defined(linux)
|
||||
#include <unistd.h>
|
||||
|
||||
char buf[BUFSIZ];
|
||||
memset(buf, 0, BUFSIZ);
|
||||
// Get path to executable
|
||||
assert(readlink("/proc/self/exe", buf, BUFSIZ-1) != -1);
|
||||
|
||||
pathRemoveFile(buf, '/');
|
||||
pathRemoveFile(buf, '/');
|
||||
|
||||
path_data = std::string(buf) + "/share/" + PROJECT_NAME;
|
||||
//path_data = std::string(INSTALL_PREFIX) + "/share/" + PROJECT_NAME;
|
||||
if (!fs::PathExists(path_data))
|
||||
{
|
||||
dstream<<"WARNING: data path " << path_data << " not found!";
|
||||
path_data = std::string(buf) + "/data";
|
||||
dstream<<" Trying " << path_data << std::endl;
|
||||
}
|
||||
|
||||
if (getenv("XDG_CONFIG_HOME") == NULL)
|
||||
{
|
||||
path_configdata = std::string(getenv("HOME"))
|
||||
+ "/.config/" + PROJECT_NAME;
|
||||
} else
|
||||
{
|
||||
path_configdata = std::string(getenv("XDG_CONFIG_HOME"))
|
||||
+ "/" + PROJECT_NAME;
|
||||
}
|
||||
if (getenv("XDG_DATA_HOME") == NULL)
|
||||
{
|
||||
path_userdata = std::string(getenv("HOME"))
|
||||
+ "/.local/share/" + PROJECT_NAME;
|
||||
} else
|
||||
{
|
||||
path_userdata = std::string(getenv("XDG_DATA_HOME"))
|
||||
+ "/" + PROJECT_NAME;
|
||||
}
|
||||
|
||||
/*
|
||||
OS X
|
||||
*/
|
||||
#elif defined(__APPLE__)
|
||||
#include <unistd.h>
|
||||
|
||||
// Code based on
|
||||
// http://stackoverflow.com/questions/516200/relative-paths-not-working-in-xcode-c
|
||||
CFBundleRef main_bundle = CFBundleGetMainBundle();
|
||||
CFURLRef resources_url = CFBundleCopyResourcesDirectoryURL(main_bundle);
|
||||
char path[PATH_MAX];
|
||||
if(CFURLGetFileSystemRepresentation(resources_url, TRUE, (UInt8 *)path, PATH_MAX))
|
||||
{
|
||||
dstream<<"Bundle resource path: "<<path<<std::endl;
|
||||
//chdir(path);
|
||||
path_data = std::string(path) + "/share/" + PROJECT_NAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
// error!
|
||||
dstream<<"WARNING: Could not determine bundle resource path"<<std::endl;
|
||||
}
|
||||
CFRelease(resources_url);
|
||||
|
||||
path_userdata = std::string(getenv("HOME")) + "/Library/Application Support/" + PROJECT_NAME;
|
||||
path_configdata = std::string(getenv("HOME")) + "/Library/Application Support/" + PROJECT_NAME;
|
||||
|
||||
#elif defined(__FreeBSD__)
|
||||
|
||||
path_data = std::string(INSTALL_PREFIX) + "/share/" + PROJECT_NAME;
|
||||
|
||||
if (getenv("XDG_CONFIG_HOME") == NULL)
|
||||
{
|
||||
path_configdata = std::string(getenv("HOME"))
|
||||
+ "/.config/" + PROJECT_NAME;
|
||||
} else
|
||||
{
|
||||
path_configdata = std::string(getenv("XDG_CONFIG_HOME"))
|
||||
+ "/" + PROJECT_NAME;
|
||||
}
|
||||
if (getenv("XDG_DATA_HOME") == NULL)
|
||||
{
|
||||
path_userdata = std::string(getenv("HOME"))
|
||||
+ "/.local/share/" + PROJECT_NAME;
|
||||
} else
|
||||
{
|
||||
path_userdata = std::string(getenv("XDG_DATA_HOME"))
|
||||
+ "/" + PROJECT_NAME;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // RUN_IN_PLACE
|
||||
|
||||
dstream<<"path_data = "<<path_data<<std::endl;
|
||||
dstream<<"path_configdata = "<<path_configdata<<std::endl;
|
||||
dstream<<"path_userdata = "<<path_userdata<<std::endl;
|
||||
|
||||
#if defined(__FreeBSD__) || defined(linux)
|
||||
#ifndef RUN_IN_PLACE
|
||||
// Migrate to the new Directories
|
||||
std::string path_olddirectory = std::string(getenv("HOME")) + "/." + PROJECT_NAME;
|
||||
|
||||
if (fs::PathExists(path_olddirectory))
|
||||
{
|
||||
dstream<<"Old directory found, Migrating process will start now." << std::endl;
|
||||
|
||||
if (!fs::PathExists(path_configdata))
|
||||
{
|
||||
fs::CreateDir(path_configdata);
|
||||
std::string path_oldconfig = std::string(getenv("HOME"))
|
||||
+ "/.voxelands/voxelands.conf";
|
||||
std::string path_newconfig = path_configdata + "/voxelands.conf";
|
||||
|
||||
if (rename( path_oldconfig.c_str() , path_newconfig.c_str() ) == 0)
|
||||
{
|
||||
dstream<<"Config is successful migrated." << std::endl;
|
||||
} else
|
||||
{
|
||||
dstream<<"Error while moving the Config directory: " << std::endl;
|
||||
dstream<<strerror(errno) << std::endl;
|
||||
}
|
||||
} else
|
||||
{
|
||||
dstream<<"Warning: There is already a directory for the Config!" << std::endl;
|
||||
dstream<<"The Config directory will not be migrated." << std::endl;
|
||||
}
|
||||
if (!fs::PathExists(path_userdata))
|
||||
{
|
||||
if (rename( path_olddirectory.c_str() ,
|
||||
path_userdata.c_str() ) == 0)
|
||||
{
|
||||
dstream<<"Data Directory is successful migrated." << std::endl;
|
||||
} else
|
||||
{
|
||||
dstream<<"Error while move the Data directory: " << std::endl;
|
||||
dstream<<strerror(errno) << std::endl;
|
||||
}
|
||||
} else
|
||||
{
|
||||
dstream<<"Warning: There is already a Directory for the Data!" << std::endl;
|
||||
dstream<<"The Data directory will not be migrated. " << std::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string getUser()
|
||||
{
|
||||
std::string user("someone");
|
||||
|
|
|
@ -67,40 +67,6 @@ void signal_handler_init(void);
|
|||
// When the bool is true, program should quit.
|
||||
bool * signal_handler_killstatus(void);
|
||||
|
||||
/*
|
||||
Path of static data directory.
|
||||
*/
|
||||
extern std::string path_data;
|
||||
|
||||
/*
|
||||
Get full path of stuff in data directory.
|
||||
Example: "stone.png" -> "../data/textures/stone.png"
|
||||
*/
|
||||
|
||||
|
||||
extern std::string path_configdata;
|
||||
|
||||
/*
|
||||
Directory for storing user config. Examples:
|
||||
Windows: "C:\Documents and Settings\user\Application Data\<PROJECT_NAME>"
|
||||
Linux: "~/.config/<PROJECT_NAME>"
|
||||
Mac: "~/Library/Application Support/<PROJECT_NAME>"
|
||||
*/
|
||||
extern std::string path_userdata;
|
||||
|
||||
/*
|
||||
Directory for storing user data. Examples:
|
||||
Windows: "C:\Documents and Settings\user\Application Data\<PROJECT_NAME>"
|
||||
Linux: "~/.local/share/<PROJECT_NAME>"
|
||||
Mac: "~/Library/Application Support/<PROJECT_NAME>"
|
||||
*/
|
||||
std::string getDataPath(const char *subpath);
|
||||
|
||||
/*
|
||||
Initialize path_data and path_userdata.
|
||||
*/
|
||||
void initializePaths(char* argv0);
|
||||
|
||||
/*
|
||||
Resolution is 10-20ms.
|
||||
Remember to check for overflows.
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "sound.h"
|
||||
#include "http.h"
|
||||
#include "enchantment.h"
|
||||
#include "path.h"
|
||||
|
||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||
|
||||
|
@ -854,24 +855,19 @@ u32 PIChecksum(core::list<PlayerInfo> &l)
|
|||
Server
|
||||
*/
|
||||
|
||||
Server::Server(
|
||||
std::string mapsavedir,
|
||||
std::string configpath
|
||||
):
|
||||
m_env(new ServerMap(mapsavedir), this),
|
||||
Server::Server():
|
||||
m_env(new ServerMap(), this),
|
||||
m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this),
|
||||
m_banmanager(mapsavedir+DIR_DELIM+"ipban.txt"),
|
||||
m_thread(this),
|
||||
m_emergethread(this),
|
||||
m_time_of_day_send_timer(0),
|
||||
m_uptime(0),
|
||||
m_mapsavedir(mapsavedir),
|
||||
m_configpath(configpath),
|
||||
m_shutdown_requested(false),
|
||||
m_ignore_map_edit_events(false)
|
||||
{
|
||||
|
||||
auth_init((char*)"auth.txt");
|
||||
ban_init((char*)"ipban.txt");
|
||||
|
||||
m_liquid_transform_timer = 0.0;
|
||||
m_print_info_timer = 0.0;
|
||||
|
@ -888,15 +884,12 @@ Server::Server(
|
|||
// Register us to receive map edit events
|
||||
m_env.getMap().addEventReceiver(this);
|
||||
|
||||
// If file exists, load environment metadata
|
||||
if (fs::PathExists(m_mapsavedir+DIR_DELIM+"env_meta.txt")) {
|
||||
infostream<<"Server: Loading environment metadata"<<std::endl;
|
||||
m_env.loadMeta(m_mapsavedir);
|
||||
}
|
||||
infostream<<"Server: Loading environment metadata"<<std::endl;
|
||||
m_env.loadMeta();
|
||||
|
||||
// Load players
|
||||
infostream<<"Server: Loading players"<<std::endl;
|
||||
m_env.deSerializePlayers(m_mapsavedir);
|
||||
m_env.deSerializePlayers();
|
||||
}
|
||||
|
||||
Server::~Server()
|
||||
|
@ -939,13 +932,13 @@ Server::~Server()
|
|||
Save players
|
||||
*/
|
||||
infostream<<"Server: Saving players"<<std::endl;
|
||||
m_env.serializePlayers(m_mapsavedir);
|
||||
m_env.serializePlayers();
|
||||
|
||||
/*
|
||||
Save environment metadata
|
||||
*/
|
||||
infostream<<"Server: Saving environment metadata"<<std::endl;
|
||||
m_env.saveMeta(m_mapsavedir);
|
||||
m_env.saveMeta();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -975,6 +968,9 @@ Server::~Server()
|
|||
delete i.getNode()->getValue();
|
||||
}
|
||||
}
|
||||
|
||||
ban_exit();
|
||||
auth_exit();
|
||||
}
|
||||
|
||||
void Server::start(unsigned short port)
|
||||
|
@ -1637,8 +1633,7 @@ void Server::AsyncRunStep()
|
|||
auth_save();
|
||||
|
||||
//Bann stuff
|
||||
if(m_banmanager.isModified())
|
||||
m_banmanager.save();
|
||||
ban_save();
|
||||
|
||||
// Map
|
||||
JMutexAutoLock lock(m_env_mutex);
|
||||
|
@ -1661,10 +1656,10 @@ void Server::AsyncRunStep()
|
|||
}*/
|
||||
|
||||
// Save players
|
||||
m_env.serializePlayers(m_mapsavedir);
|
||||
m_env.serializePlayers();
|
||||
|
||||
// Save environment metadata
|
||||
m_env.saveMeta(m_mapsavedir);
|
||||
m_env.saveMeta();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1721,11 +1716,14 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
Address address = m_con.GetPeerAddress(peer_id);
|
||||
|
||||
// drop player if is ip is banned
|
||||
if(m_banmanager.isIpBanned(address.serializeString())){
|
||||
std::string add = address.serializeString();
|
||||
if (ban_ipbanned(const_cast<char*>(add.c_str()))) {
|
||||
char* name = ban_ip2name(const_cast<char*>(add.c_str()));
|
||||
if (!name)
|
||||
name = (char*)"???";
|
||||
SendAccessDenied(m_con, peer_id,
|
||||
L"Your ip is banned. Banned name was "
|
||||
+narrow_to_wide(m_banmanager.getBanName(
|
||||
address.serializeString())));
|
||||
+narrow_to_wide(name));
|
||||
m_con.DeletePeer(peer_id);
|
||||
return;
|
||||
}
|
||||
|
@ -5785,8 +5783,9 @@ std::wstring Server::getStatusString()
|
|||
// Saves g_settings to configpath given at initialization
|
||||
void Server::saveConfig()
|
||||
{
|
||||
if(m_configpath != "")
|
||||
g_settings->updateConfigFile(m_configpath.c_str());
|
||||
char buff[1024];
|
||||
if (path_get((char*)"config",(char*)"voxelands.conf",0,buff,1024))
|
||||
g_settings->updateConfigFile(buff);
|
||||
}
|
||||
|
||||
void Server::notifyPlayer(const char *name, const std::wstring msg)
|
||||
|
|
22
src/server.h
22
src/server.h
|
@ -363,10 +363,7 @@ public:
|
|||
NOTE: Every public method should be thread-safe
|
||||
*/
|
||||
|
||||
Server(
|
||||
std::string mapsavedir,
|
||||
std::string configpath
|
||||
);
|
||||
Server();
|
||||
~Server();
|
||||
void start(unsigned short port);
|
||||
void stop();
|
||||
|
@ -446,19 +443,21 @@ public:
|
|||
|
||||
void setIpBanned(const std::string &ip, const std::string &name)
|
||||
{
|
||||
m_banmanager.add(ip, name);
|
||||
ban_add(const_cast<char*>(ip.c_str()),const_cast<char*>(name.c_str()));
|
||||
return;
|
||||
}
|
||||
|
||||
void unsetIpBanned(const std::string &ip_or_name)
|
||||
{
|
||||
m_banmanager.remove(ip_or_name);
|
||||
ban_remove(const_cast<char*>(ip_or_name.c_str()));
|
||||
return;
|
||||
}
|
||||
|
||||
std::string getBanDescription(const std::string &ip_or_name)
|
||||
{
|
||||
return m_banmanager.getBanDescription(ip_or_name);
|
||||
char buff[256];
|
||||
ban_description(const_cast<char*>(ip_or_name.c_str()),buff,256);
|
||||
return std::string(buff);
|
||||
}
|
||||
|
||||
Address getPeerAddress(u16 peer_id)
|
||||
|
@ -601,9 +600,6 @@ private:
|
|||
// Connected clients (behind the con mutex)
|
||||
core::map<u16, RemoteClient*> m_clients;
|
||||
|
||||
// Bann checking
|
||||
BanManager m_banmanager;
|
||||
|
||||
/*
|
||||
Threads
|
||||
*/
|
||||
|
@ -651,12 +647,6 @@ private:
|
|||
Random stuff
|
||||
*/
|
||||
|
||||
// Map directory
|
||||
std::string m_mapsavedir;
|
||||
|
||||
// Configuration path ("" = no configuration file)
|
||||
std::string m_configpath;
|
||||
|
||||
bool m_shutdown_requested;
|
||||
|
||||
/*
|
||||
|
|
|
@ -81,6 +81,8 @@
|
|||
#include "content_toolitem.h"
|
||||
#include "content_mob.h"
|
||||
#include "http.h"
|
||||
#include "thread.h"
|
||||
#include "path.h"
|
||||
|
||||
/*
|
||||
Settings.
|
||||
|
@ -172,19 +174,17 @@ int main(int argc, char *argv[])
|
|||
porting::signal_handler_init();
|
||||
bool &kill = *porting::signal_handler_killstatus();
|
||||
|
||||
// Initialize porting::path_data and porting::path_userdata
|
||||
porting::initializePaths(argv[0]);
|
||||
|
||||
// Create user data directory
|
||||
fs::CreateDir(porting::path_userdata);
|
||||
thread_init();
|
||||
path_init();
|
||||
|
||||
// Initialize debug streams
|
||||
#ifdef RUN_IN_PLACE
|
||||
std::string debugfile = DEBUGFILE;
|
||||
#else
|
||||
std::string debugfile = porting::path_userdata+DIR_DELIM+DEBUGFILE;
|
||||
#endif
|
||||
debugstreams_init(disable_stderr, debugfile.c_str());
|
||||
{
|
||||
char buff[1024];
|
||||
if (!path_get(NULL,(char*)"debug.txt",0,buff,1024))
|
||||
return 1;
|
||||
debugstreams_init(disable_stderr, buff);
|
||||
}
|
||||
// Initialize debug stacks
|
||||
debug_stacks_init();
|
||||
|
||||
|
@ -269,39 +269,10 @@ int main(int argc, char *argv[])
|
|||
Read config file
|
||||
*/
|
||||
|
||||
// Path of configuration file in use
|
||||
std::string configpath = "";
|
||||
|
||||
if(cmd_args.exists("config"))
|
||||
{
|
||||
bool r = g_settings->readConfigFile(cmd_args.get("config").c_str());
|
||||
if(r == false)
|
||||
{
|
||||
errorstream<<"Could not read configuration from \""
|
||||
<<cmd_args.get("config")<<"\""<<std::endl;
|
||||
return 1;
|
||||
}
|
||||
configpath = cmd_args.get("config");
|
||||
}
|
||||
else
|
||||
{
|
||||
core::array<std::string> filenames;
|
||||
filenames.push_back(porting::path_userdata +
|
||||
DIR_DELIM + "voxelands.conf");
|
||||
#ifdef RUN_IN_PLACE
|
||||
filenames.push_back(porting::path_userdata +
|
||||
DIR_DELIM + ".." + DIR_DELIM + "voxelands.conf");
|
||||
#endif
|
||||
|
||||
for(u32 i=0; i<filenames.size(); i++)
|
||||
{
|
||||
bool r = g_settings->readConfigFile(filenames[i].c_str());
|
||||
if(r)
|
||||
{
|
||||
configpath = filenames[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
char buff[1024];
|
||||
if (path_get((char*)"config",(char*)"voxelands.conf",0,buff,1024))
|
||||
g_settings->readConfigFile(buff);
|
||||
}
|
||||
|
||||
// Initialize random seed
|
||||
|
@ -345,29 +316,20 @@ int main(int argc, char *argv[])
|
|||
|
||||
// Port?
|
||||
u16 port = 30000;
|
||||
if(cmd_args.exists("port") && cmd_args.getU16("port") != 0)
|
||||
{
|
||||
if (cmd_args.exists("port") && cmd_args.getU16("port") != 0) {
|
||||
port = cmd_args.getU16("port");
|
||||
}
|
||||
else if(g_settings->exists("port") && g_settings->getU16("port") != 0)
|
||||
{
|
||||
}else if (g_settings->exists("port") && g_settings->getU16("port") != 0) {
|
||||
port = g_settings->getU16("port");
|
||||
}
|
||||
else
|
||||
{
|
||||
}else{
|
||||
dstream<<"Please specify port (in config or on command line)"
|
||||
<<std::endl;
|
||||
}
|
||||
|
||||
// Figure out path to map
|
||||
std::string map_dir = porting::path_userdata+DIR_DELIM+"world";
|
||||
if(cmd_args.exists("map-dir"))
|
||||
map_dir = cmd_args.get("map-dir");
|
||||
else if(g_settings->exists("map-dir"))
|
||||
map_dir = g_settings->get("map-dir");
|
||||
/* TODO: configise this */
|
||||
path_world_setter((char*)"default");
|
||||
|
||||
// Create server
|
||||
Server server(map_dir.c_str(), configpath);
|
||||
Server server;
|
||||
server.start(port);
|
||||
HTTPServer http_server(server);
|
||||
if (g_settings->getBool("enable_http"))
|
||||
|
|
Loading…
Reference in New Issue