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
|
set(common_SRCS
|
||||||
auth.c
|
auth.c
|
||||||
array.c
|
array.c
|
||||||
|
ban.c
|
||||||
list.c
|
list.c
|
||||||
nvp.c
|
nvp.c
|
||||||
crypto.c
|
crypto.c
|
||||||
|
@ -224,7 +225,6 @@ set(common_SRCS
|
||||||
test.cpp
|
test.cpp
|
||||||
sha1.cpp
|
sha1.cpp
|
||||||
base64.cpp
|
base64.cpp
|
||||||
ban.cpp
|
|
||||||
http.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 @@
|
||||||
/************************************************************************
|
#ifndef _BAN_H_
|
||||||
* Minetest-c55
|
#define _BAN_H_
|
||||||
* 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_HEADER
|
#ifdef __cplusplus
|
||||||
#define BAN_HEADER
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <map>
|
/* defined in ban.c */
|
||||||
#include <string>
|
int ban_init(char* file);
|
||||||
#include <jthread.h>
|
void ban_exit(void);
|
||||||
#include <jmutex.h>
|
void ban_load(void);
|
||||||
#include "common_irrlicht.h"
|
void ban_save(void);
|
||||||
#include "exceptions.h"
|
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;
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
class BanManager
|
#endif
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
|
||||||
#include "nvp.h"
|
#include "nvp.h"
|
||||||
|
#include "path.h"
|
||||||
|
|
||||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||||
|
|
||||||
|
@ -331,30 +332,41 @@ ServerEnvironment::~ServerEnvironment()
|
||||||
m_map->drop();
|
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;
|
Player *player;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
dirlist_t *list;
|
||||||
|
dirlist_t *list_file;
|
||||||
nvp_t *saved_players = NULL;
|
nvp_t *saved_players = NULL;
|
||||||
|
char path[1024];
|
||||||
|
|
||||||
std::vector<fs::DirListNode> player_files = fs::GetDirListing(players_path);
|
if (path_create((char*)"player",NULL)) {
|
||||||
for (i=0; i<player_files.size(); i++) {
|
infostream<<"failed to open players path"<<std::endl;
|
||||||
if (player_files[i].dir)
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
list = path_dirlist((char*)"player",NULL);
|
||||||
|
list_file = list;
|
||||||
|
|
||||||
|
while (list_file) {
|
||||||
|
if (list_file->dir) {
|
||||||
|
list_file = list_file->next;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
// Full path to this file
|
|
||||||
std::string path = players_path + "/" + player_files[i].name;
|
|
||||||
|
|
||||||
// Load player to see what is its name
|
// Load player to see what is its name
|
||||||
ServerRemotePlayer testplayer;
|
ServerRemotePlayer testplayer;
|
||||||
{
|
{
|
||||||
|
if (!path_get((char*)"player",list_file->name,1,path,1024)) {
|
||||||
|
list_file = list_file->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// Open file and deserialize
|
// 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) {
|
if (is.good() == false) {
|
||||||
infostream<<"Failed to read "<<path<<std::endl;
|
infostream<<"Failed to read "<<path<<std::endl;
|
||||||
|
list_file = list_file->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
testplayer.deSerialize(is);
|
testplayer.deSerialize(is);
|
||||||
|
@ -366,7 +378,8 @@ void ServerEnvironment::serializePlayers(const std::string &savedir)
|
||||||
std::string playername = testplayer.getName();
|
std::string playername = testplayer.getName();
|
||||||
player = getPlayer(playername.c_str());
|
player = getPlayer(playername.c_str());
|
||||||
if (player == NULL) {
|
if (player == NULL) {
|
||||||
fs::RecursiveDelete(path);
|
path_remove(NULL,path);
|
||||||
|
list_file = list_file->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,14 +388,16 @@ void ServerEnvironment::serializePlayers(const std::string &savedir)
|
||||||
// OK, found. Save player there.
|
// OK, found. Save player there.
|
||||||
{
|
{
|
||||||
// Open file and serialize
|
// 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) {
|
if (os.good() == false) {
|
||||||
infostream<<"Failed to overwrite "<<path<<std::endl;
|
infostream<<"Failed to overwrite "<<path<<std::endl;
|
||||||
|
list_file = list_file->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
player->serialize(os);
|
player->serialize(os);
|
||||||
nvp_set(&saved_players, (char*)player->getName(), (char*)player->getName(), player);
|
nvp_set(&saved_players, (char*)player->getName(), (char*)player->getName(), player);
|
||||||
}
|
}
|
||||||
|
list_file = list_file->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<m_players->length; i++) {
|
for (i=0; i<m_players->length; i++) {
|
||||||
|
@ -391,34 +406,17 @@ void ServerEnvironment::serializePlayers(const std::string &savedir)
|
||||||
continue;
|
continue;
|
||||||
if (nvp_get(&saved_players, (char*)player->getName()) != NULL)
|
if (nvp_get(&saved_players, (char*)player->getName()) != NULL)
|
||||||
continue;
|
continue;
|
||||||
std::string playername = player->getName();
|
char* playername = const_cast<char*>(player->getName());
|
||||||
// Don't save unnamed player
|
/* don't save unnamed player */
|
||||||
if (playername == "")
|
if (!playername[0])
|
||||||
continue;
|
continue;
|
||||||
/*
|
/* ... or dodgy names */
|
||||||
Find a sane filename
|
|
||||||
*/
|
|
||||||
if (string_allowed(playername, PLAYERNAME_ALLOWED_CHARS) == false)
|
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;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
{
|
if (path_get((char*)"player",playername,0,path,1024)) {
|
||||||
/*infostream<<"Saving player "<<player->getName()<<" to "
|
|
||||||
<<path<<std::endl;*/
|
|
||||||
// Open file and serialize
|
// 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) {
|
if (os.good() == false) {
|
||||||
infostream<<"Failed to overwrite "<<path<<std::endl;
|
infostream<<"Failed to overwrite "<<path<<std::endl;
|
||||||
continue;
|
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);
|
if (!path_get((char*)"player",NULL,1,path,1024))
|
||||||
for (u32 i=0; i<player_files.size(); i++) {
|
return;
|
||||||
if (player_files[i].dir)
|
|
||||||
|
list = path_dirlist((char*)"player",NULL);
|
||||||
|
list_file = list;
|
||||||
|
|
||||||
|
while (list_file) {
|
||||||
|
if (list_file->dir) {
|
||||||
|
list_file = list_file->next;
|
||||||
continue;
|
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
|
// Load player to see what is its name
|
||||||
ServerRemotePlayer testplayer;
|
ServerRemotePlayer testplayer;
|
||||||
{
|
{
|
||||||
|
if (!path_get((char*)"player",list_file->name,1,path,1024)) {
|
||||||
|
list_file = list_file->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// Open file and deserialize
|
// 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) {
|
if (is.good() == false) {
|
||||||
infostream<<"Failed to read "<<path<<std::endl;
|
infostream<<"Failed to read "<<path<<std::endl;
|
||||||
|
list_file = list_file->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
testplayer.deSerialize(is);
|
testplayer.deSerialize(is);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string_allowed(testplayer.getName(), PLAYERNAME_ALLOWED_CHARS)) {
|
if (!string_allowed(testplayer.getName(), PLAYERNAME_ALLOWED_CHARS)) {
|
||||||
fs::RecursiveDelete(path);
|
path_remove(NULL,path);
|
||||||
|
list_file = list_file->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,9 +490,10 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir)
|
||||||
infostream<<"Reading player "<<testplayer.getName()<<" from "
|
infostream<<"Reading player "<<testplayer.getName()<<" from "
|
||||||
<<path<<std::endl;
|
<<path<<std::endl;
|
||||||
// Open file and deserialize
|
// 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) {
|
if (is.good() == false) {
|
||||||
infostream<<"Failed to read "<<path<<std::endl;
|
infostream<<"Failed to read "<<path<<std::endl;
|
||||||
|
list_file = list_file->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
player->deSerialize(is);
|
player->deSerialize(is);
|
||||||
|
@ -493,19 +501,21 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir)
|
||||||
|
|
||||||
if (newplayer)
|
if (newplayer)
|
||||||
addPlayer(player);
|
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
|
// Open file and serialize
|
||||||
std::ofstream os(path.c_str(), std::ios_base::binary);
|
std::ofstream os(buff, std::ios_base::binary);
|
||||||
if(os.good() == false)
|
if (os.good() == false) {
|
||||||
{
|
|
||||||
infostream<<"ServerEnvironment::saveMeta(): Failed to open "
|
infostream<<"ServerEnvironment::saveMeta(): Failed to open "
|
||||||
<<path<<std::endl;
|
<<buff<<std::endl;
|
||||||
throw SerializationError("Couldn't save env meta");
|
throw SerializationError("Couldn't save env meta");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,16 +527,17 @@ void ServerEnvironment::saveMeta(const std::string &savedir)
|
||||||
os<<"EnvArgsEnd\n";
|
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
|
// Open file and deserialize
|
||||||
std::ifstream is(path.c_str(), std::ios_base::binary);
|
std::ifstream is(buff, std::ios_base::binary);
|
||||||
if(is.good() == false)
|
if (is.good() == false) {
|
||||||
{
|
|
||||||
infostream<<"ServerEnvironment::loadMeta(): Failed to open "
|
infostream<<"ServerEnvironment::loadMeta(): Failed to open "
|
||||||
<<path<<std::endl;
|
<<buff<<std::endl;
|
||||||
throw SerializationError("Couldn't load env meta");
|
throw SerializationError("Couldn't load env meta");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -288,14 +288,14 @@ public:
|
||||||
/*
|
/*
|
||||||
Save players
|
Save players
|
||||||
*/
|
*/
|
||||||
void serializePlayers(const std::string &savedir);
|
void serializePlayers();
|
||||||
void deSerializePlayers(const std::string &savedir);
|
void deSerializePlayers();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Save and load time of day and game timer
|
Save and load time of day and game timer
|
||||||
*/
|
*/
|
||||||
void saveMeta(const std::string &savedir);
|
void saveMeta();
|
||||||
void loadMeta(const std::string &savedir);
|
void loadMeta();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
External ActiveObject interface
|
External ActiveObject interface
|
||||||
|
|
|
@ -637,13 +637,11 @@ void the_game(
|
||||||
InputHandler *input,
|
InputHandler *input,
|
||||||
IrrlichtDevice *device,
|
IrrlichtDevice *device,
|
||||||
gui::IGUIFont* font,
|
gui::IGUIFont* font,
|
||||||
std::string map_dir,
|
|
||||||
std::string playername,
|
std::string playername,
|
||||||
std::string password,
|
std::string password,
|
||||||
std::string address,
|
std::string address,
|
||||||
u16 port,
|
u16 port,
|
||||||
std::wstring &error_message,
|
std::wstring &error_message,
|
||||||
std::string configpath,
|
|
||||||
ISoundManager *sound
|
ISoundManager *sound
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -675,7 +673,7 @@ void the_game(
|
||||||
//draw_load_screen(L"Creating server...", driver, font);
|
//draw_load_screen(L"Creating server...", driver, font);
|
||||||
drawLoadingScreen(device,narrow_to_wide(gettext("Creating server...")));
|
drawLoadingScreen(device,narrow_to_wide(gettext("Creating server...")));
|
||||||
infostream<<"Creating server"<<std::endl;
|
infostream<<"Creating server"<<std::endl;
|
||||||
server = new Server(map_dir, configpath);
|
server = new Server();
|
||||||
server->start(port);
|
server->start(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -139,13 +139,11 @@ void the_game(
|
||||||
InputHandler *input,
|
InputHandler *input,
|
||||||
IrrlichtDevice *device,
|
IrrlichtDevice *device,
|
||||||
gui::IGUIFont* font,
|
gui::IGUIFont* font,
|
||||||
std::string map_dir,
|
|
||||||
std::string playername,
|
std::string playername,
|
||||||
std::string password,
|
std::string password,
|
||||||
std::string address,
|
std::string address,
|
||||||
u16 port,
|
u16 port,
|
||||||
std::wstring &error_message,
|
std::wstring &error_message,
|
||||||
std::string configpath,
|
|
||||||
ISoundManager *sound
|
ISoundManager *sound
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
90
src/main.cpp
90
src/main.cpp
|
@ -828,26 +828,17 @@ int main(int argc, char *argv[])
|
||||||
porting::signal_handler_init();
|
porting::signal_handler_init();
|
||||||
bool &kill = *porting::signal_handler_killstatus();
|
bool &kill = *porting::signal_handler_killstatus();
|
||||||
|
|
||||||
// Initialize porting::path_data, porting::path_userdata and porting::userconfig
|
thread_init();
|
||||||
porting::initializePaths(argv[0]);
|
path_init();
|
||||||
|
|
||||||
// Create user data directory
|
|
||||||
fs::CreateDir(porting::path_userdata);
|
|
||||||
|
|
||||||
#if defined(__FreeBSD__) || defined(linux)
|
|
||||||
// Create user config directory
|
|
||||||
fs::CreateDir(porting::path_configdata);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
intl_init();
|
intl_init();
|
||||||
|
|
||||||
// Initialize debug streams
|
// Initialize debug streams
|
||||||
#ifdef RUN_IN_PLACE
|
{
|
||||||
std::string debugfile = DEBUGFILE;
|
char buff[1024];
|
||||||
#else
|
if (!path_get(NULL,(char*)"debug.txt",0,buff,1024))
|
||||||
std::string debugfile = porting::path_userdata+DIR_DELIM+DEBUGFILE;
|
return 1;
|
||||||
#endif
|
debugstreams_init(disable_stderr, buff);
|
||||||
debugstreams_init(disable_stderr, debugfile.c_str());
|
}
|
||||||
// Initialize debug stacks
|
// Initialize debug stacks
|
||||||
debug_stacks_init();
|
debug_stacks_init();
|
||||||
|
|
||||||
|
@ -869,9 +860,6 @@ int main(int argc, char *argv[])
|
||||||
Basic initialization
|
Basic initialization
|
||||||
*/
|
*/
|
||||||
|
|
||||||
thread_init();
|
|
||||||
path_init();
|
|
||||||
|
|
||||||
// Initialize default settings
|
// Initialize default settings
|
||||||
set_default_settings(g_settings);
|
set_default_settings(g_settings);
|
||||||
|
|
||||||
|
@ -883,37 +871,10 @@ int main(int argc, char *argv[])
|
||||||
Read config file
|
Read config file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Path of configuration file in use
|
{
|
||||||
std::string configpath = "";
|
char buff[1024];
|
||||||
|
if (path_get((char*)"config",(char*)"voxelands.conf",0,buff,1024))
|
||||||
if (cmd_args.exists("config")) {
|
g_settings->readConfigFile(buff);
|
||||||
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];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize random seed
|
// Initialize random seed
|
||||||
|
@ -970,13 +931,8 @@ int main(int argc, char *argv[])
|
||||||
if (port == 0)
|
if (port == 0)
|
||||||
port = 30000;
|
port = 30000;
|
||||||
|
|
||||||
// Map directory
|
/* TODO: configise this */
|
||||||
std::string map_dir = porting::path_userdata+DIR_DELIM+"world";
|
path_world_setter((char*)"default");
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run dedicated server if asked to
|
// Run dedicated server if asked to
|
||||||
if (cmd_args.getFlag("server")) {
|
if (cmd_args.getFlag("server")) {
|
||||||
|
@ -986,7 +942,7 @@ int main(int argc, char *argv[])
|
||||||
g_timegetter = new SimpleTimeGetter();
|
g_timegetter = new SimpleTimeGetter();
|
||||||
|
|
||||||
// Create server
|
// Create server
|
||||||
Server server(map_dir.c_str(), configpath);
|
Server server;
|
||||||
server.start(port);
|
server.start(port);
|
||||||
|
|
||||||
// Run server
|
// Run server
|
||||||
|
@ -1341,8 +1297,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
// Delete map if requested
|
// Delete map if requested
|
||||||
if (menudata.delete_map) {
|
if (menudata.delete_map) {
|
||||||
bool r = fs::RecursiveDeleteContent(map_dir);
|
if (path_remove((char*)"world",NULL)) {
|
||||||
if(r == false) {
|
|
||||||
error_message = L"Map deletion failed";
|
error_message = L"Map deletion failed";
|
||||||
continue;
|
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("fixed_map_seed",wide_to_narrow(menudata.fixed_seed));
|
||||||
g_settings->set("mapgen_type",menudata.map_type);
|
g_settings->set("mapgen_type",menudata.map_type);
|
||||||
}else if (menudata.clear_map) {
|
}else if (menudata.clear_map) {
|
||||||
std::string map_file = map_dir+DIR_DELIM+"map.sqlite";
|
if (path_remove((char*)"world",(char*)"map.sqlite")) {
|
||||||
bool r = fs::RecursiveDelete(map_file);
|
|
||||||
if(r == false) {
|
|
||||||
error_message = L"Map clearing failed";
|
error_message = L"Map clearing failed";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1385,8 +1338,11 @@ int main(int argc, char *argv[])
|
||||||
g_settings->set("address", address);
|
g_settings->set("address", address);
|
||||||
g_settings->set("port", itos(port));
|
g_settings->set("port", itos(port));
|
||||||
// Update configuration file
|
// 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
|
// Continue to game
|
||||||
break;
|
break;
|
||||||
|
@ -1447,13 +1403,11 @@ int main(int argc, char *argv[])
|
||||||
input,
|
input,
|
||||||
device,
|
device,
|
||||||
font,
|
font,
|
||||||
map_dir,
|
|
||||||
playername,
|
playername,
|
||||||
password,
|
password,
|
||||||
address,
|
address,
|
||||||
port,
|
port,
|
||||||
error_message,
|
error_message,
|
||||||
configpath,
|
|
||||||
sound
|
sound
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
130
src/map.cpp
130
src/map.cpp
|
@ -45,6 +45,7 @@
|
||||||
#include "profiler.h"
|
#include "profiler.h"
|
||||||
#include "inventory.h"
|
#include "inventory.h"
|
||||||
#include "enchantment.h"
|
#include "enchantment.h"
|
||||||
|
#include "path.h"
|
||||||
|
|
||||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
#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::ServerMap(std::string savedir):
|
ServerMap::ServerMap():
|
||||||
Map(dout_server),
|
Map(dout_server),
|
||||||
m_seed(0),
|
m_seed(0),
|
||||||
m_map_metadata_changed(true),
|
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.
|
Try to load map; if not found, create a new one.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
m_savedir = savedir;
|
|
||||||
m_map_saving_enabled = false;
|
m_map_saving_enabled = false;
|
||||||
|
|
||||||
try
|
try{
|
||||||
{
|
|
||||||
// If directory exists, check contents and load if possible
|
// 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 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."
|
infostream<<"Server: Empty save directory is valid."
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
m_map_saving_enabled = true;
|
m_map_saving_enabled = true;
|
||||||
}
|
}else{
|
||||||
else
|
|
||||||
{
|
|
||||||
try{
|
try{
|
||||||
// Load map metadata (seed, type, chunksize)
|
// Load map metadata (seed, type, chunksize)
|
||||||
loadMapMeta();
|
loadMapMeta();
|
||||||
|
@ -1761,24 +1764,8 @@ ServerMap::ServerMap(std::string savedir):
|
||||||
//m_chunksize = 0;
|
//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 "
|
infostream<<"Server: Successfully loaded map "
|
||||||
<<"and chunk metadata from "<<savedir
|
<<"and chunk metadata from "<<buff
|
||||||
<<", assuming valid save directory."
|
<<", assuming valid save directory."
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
|
|
||||||
|
@ -1786,16 +1773,14 @@ ServerMap::ServerMap(std::string savedir):
|
||||||
// Map loaded, not creating new one
|
// Map loaded, not creating new one
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// If directory doesn't exist, it is safe to save to it
|
// If directory doesn't exist, it is safe to save to it
|
||||||
else{
|
}else{
|
||||||
m_map_saving_enabled = true;
|
m_map_saving_enabled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
{
|
{
|
||||||
infostream<<"WARNING: Server: Failed to load map from "<<savedir
|
infostream<<"WARNING: Server: Failed to load map, exception: "<<e.what()<<std::endl;
|
||||||
<<", exception: "<<e.what()<<std::endl;
|
|
||||||
infostream<<"Please remove the map or fix it."<<std::endl;
|
infostream<<"Please remove the map or fix it."<<std::endl;
|
||||||
infostream<<"WARNING: Map saving will be disabled."<<std::endl;
|
infostream<<"WARNING: Map saving will be disabled."<<std::endl;
|
||||||
}
|
}
|
||||||
|
@ -1813,23 +1798,18 @@ ServerMap::~ServerMap()
|
||||||
{
|
{
|
||||||
infostream<<__FUNCTION_NAME<<std::endl;
|
infostream<<__FUNCTION_NAME<<std::endl;
|
||||||
|
|
||||||
try
|
try{
|
||||||
{
|
if (m_map_saving_enabled) {
|
||||||
if(m_map_saving_enabled)
|
|
||||||
{
|
|
||||||
// Save only changed parts
|
// Save only changed parts
|
||||||
save(true);
|
save(true);
|
||||||
infostream<<"Server: saved map to "<<m_savedir<<std::endl;
|
infostream<<"Server: saved map"<<std::endl;
|
||||||
}
|
}else{
|
||||||
else
|
|
||||||
{
|
|
||||||
infostream<<"Server: map not saved"<<std::endl;
|
infostream<<"Server: map not saved"<<std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
{
|
{
|
||||||
infostream<<"Server: Failed to save map to "<<m_savedir
|
infostream<<"Server: Failed to save map, exception: "<<e.what()<<std::endl;
|
||||||
<<", exception: "<<e.what()<<std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2332,7 +2312,7 @@ void ServerMap::verifyDatabase() {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::string dbp = m_savedir + DIR_DELIM + "map.sqlite";
|
char buff[1024];
|
||||||
bool needs_create = false;
|
bool needs_create = false;
|
||||||
int d;
|
int d;
|
||||||
|
|
||||||
|
@ -2340,12 +2320,16 @@ void ServerMap::verifyDatabase() {
|
||||||
Open the database connection
|
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;
|
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) {
|
if(d != SQLITE_OK) {
|
||||||
infostream<<"WARNING: Database failed to open: "<<sqlite3_errmsg(m_database)<<std::endl;
|
infostream<<"WARNING: Database failed to open: "<<sqlite3_errmsg(m_database)<<std::endl;
|
||||||
throw FileNotGoodException("map.sqlite: Cannot open database file");
|
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)
|
v2s16 ServerMap::getSectorPos(std::string dirname)
|
||||||
{
|
{
|
||||||
unsigned int x, y;
|
unsigned int x, y;
|
||||||
|
@ -2568,14 +2530,17 @@ void ServerMap::saveMapMeta()
|
||||||
<<"seed="<<m_seed
|
<<"seed="<<m_seed
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
|
|
||||||
createDirs(m_savedir);
|
char buff[1024];
|
||||||
|
if (!path_get((char*)"world",(char*)"map_meta.txt",0,buff,1024)) {
|
||||||
std::string fullpath = m_savedir + DIR_DELIM + "map_meta.txt";
|
|
||||||
std::ofstream os(fullpath.c_str(), std::ios_base::binary);
|
|
||||||
if(os.good() == false)
|
|
||||||
{
|
|
||||||
infostream<<"ERROR: ServerMap::saveMapMeta(): "
|
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");
|
throw FileNotGoodException("Cannot open chunk metadata");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2618,14 +2583,19 @@ void ServerMap::loadMapMeta()
|
||||||
{
|
{
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
|
|
||||||
infostream<<"ServerMap::loadMapMeta(): Loading map metadata"
|
infostream<<"ServerMap::loadMapMeta(): Loading map metadata"<<std::endl;
|
||||||
<<std::endl;
|
|
||||||
|
|
||||||
std::string fullpath = m_savedir + DIR_DELIM + "map_meta.txt";
|
char buff[1024];
|
||||||
std::ifstream is(fullpath.c_str(), std::ios_base::binary);
|
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) {
|
if (is.good() == false) {
|
||||||
infostream<<"ERROR: ServerMap::loadMapMeta(): "
|
infostream<<"ERROR: ServerMap::loadMapMeta(): "
|
||||||
<<"could not open"<<fullpath<<std::endl;
|
<<"could not open map_meta.txt"<<std::endl;
|
||||||
throw FileNotGoodException("Cannot open map metadata");
|
throw FileNotGoodException("Cannot open map metadata");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -322,10 +322,7 @@ protected:
|
||||||
class ServerMap : public Map
|
class ServerMap : public Map
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/*
|
ServerMap();
|
||||||
savedir: directory to which map data should be saved
|
|
||||||
*/
|
|
||||||
ServerMap(std::string savedir);
|
|
||||||
~ServerMap();
|
~ServerMap();
|
||||||
|
|
||||||
s32 mapType() const
|
s32 mapType() const
|
||||||
|
@ -428,7 +425,6 @@ private:
|
||||||
uint64_t m_seed;
|
uint64_t m_seed;
|
||||||
MapGenType m_type;
|
MapGenType m_type;
|
||||||
|
|
||||||
std::string m_savedir;
|
|
||||||
bool m_map_saving_enabled;
|
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;
|
int l;
|
||||||
char path[2048];
|
char path[2048];
|
||||||
|
|
||||||
|
if (!base && !rel)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (base) {
|
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{
|
}else{
|
||||||
l = snprintf(path,2048,"%s",rel);
|
l = snprintf(path,2048,"%s",rel);
|
||||||
}
|
}
|
||||||
|
@ -195,6 +202,7 @@ static int dir_create(char* path)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
if ((dir_create(up) == 1) && (errno != EEXIST))
|
if ((dir_create(up) == 1) && (errno != EEXIST))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -251,6 +259,7 @@ int path_init()
|
||||||
}else{
|
}else{
|
||||||
path.data_user = path_set(path.cwd,"data",NULL,0);
|
path.data_user = path_set(path.cwd,"data",NULL,0);
|
||||||
}
|
}
|
||||||
|
path_create(NULL,path.data_user);
|
||||||
|
|
||||||
path.config = getenv("XDG_CONFIG_HOME");
|
path.config = getenv("XDG_CONFIG_HOME");
|
||||||
if (path.config) {
|
if (path.config) {
|
||||||
|
@ -260,6 +269,7 @@ int path_init()
|
||||||
}else{
|
}else{
|
||||||
path.config = strdup(path.cwd);
|
path.config = strdup(path.cwd);
|
||||||
}
|
}
|
||||||
|
path_create(NULL,path.config);
|
||||||
#else
|
#else
|
||||||
/* TODO: windows, and mac? */
|
/* TODO: windows, and mac? */
|
||||||
#endif
|
#endif
|
||||||
|
@ -392,10 +402,10 @@ char* path_get(char* type, char* file, int must_exist, char* buff, int size)
|
||||||
{
|
{
|
||||||
char rel_path[1024];
|
char rel_path[1024];
|
||||||
|
|
||||||
if (!file)
|
if (!file && !type)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (file[0] == '/') {
|
if (file && file[0] == '/') {
|
||||||
return path_set(NULL,file,buff,size);
|
return path_set(NULL,file,buff,size);
|
||||||
}else if (!type) {
|
}else if (!type) {
|
||||||
strcpy(rel_path,file);
|
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)))
|
if (path.world && (!must_exist || path_check(path.world,file)))
|
||||||
return path_set(path.world,file,buff,size);
|
return path_set(path.world,file,buff,size);
|
||||||
return NULL;
|
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")) {
|
}else if (!strcmp(type,"worlds")) {
|
||||||
char* base = path.data_user;
|
char* base = path.data_user;
|
||||||
if (!base)
|
if (!base)
|
||||||
|
@ -413,8 +442,12 @@ char* path_get(char* type, char* file, int must_exist, char* buff, int size)
|
||||||
base = path.cwd;
|
base = path.cwd;
|
||||||
if (!base)
|
if (!base)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (snprintf(rel_path,1024,"worlds/%s",file) >= 1024)
|
if (file) {
|
||||||
return NULL;
|
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)
|
if (!must_exist || path_check(base,rel_path) == 2)
|
||||||
return path_set(base,rel_path,buff,size);
|
return path_set(base,rel_path,buff,size);
|
||||||
return NULL;
|
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)))
|
if (path.config && (!must_exist || path_check(path.config,file)))
|
||||||
return path_set(path.config,file,buff,size);
|
return path_set(path.config,file,buff,size);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}else if (!file) {
|
||||||
|
return NULL;
|
||||||
}else if (!strcmp(type,"model")) {
|
}else if (!strcmp(type,"model")) {
|
||||||
snprintf(rel_path,1024,"models/%s",file);
|
snprintf(rel_path,1024,"models/%s",file);
|
||||||
}else if (!strcmp(type,"texture")) {
|
}else if (!strcmp(type,"texture")) {
|
||||||
|
|
347
src/porting.cpp
347
src/porting.cpp
|
@ -120,353 +120,6 @@ void signal_handler_init(void)
|
||||||
|
|
||||||
#endif
|
#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 getUser()
|
||||||
{
|
{
|
||||||
std::string user("someone");
|
std::string user("someone");
|
||||||
|
|
|
@ -67,40 +67,6 @@ void signal_handler_init(void);
|
||||||
// When the bool is true, program should quit.
|
// When the bool is true, program should quit.
|
||||||
bool * signal_handler_killstatus(void);
|
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.
|
Resolution is 10-20ms.
|
||||||
Remember to check for overflows.
|
Remember to check for overflows.
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
#include "enchantment.h"
|
#include "enchantment.h"
|
||||||
|
#include "path.h"
|
||||||
|
|
||||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||||
|
|
||||||
|
@ -854,24 +855,19 @@ u32 PIChecksum(core::list<PlayerInfo> &l)
|
||||||
Server
|
Server
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Server::Server(
|
Server::Server():
|
||||||
std::string mapsavedir,
|
m_env(new ServerMap(), this),
|
||||||
std::string configpath
|
|
||||||
):
|
|
||||||
m_env(new ServerMap(mapsavedir), this),
|
|
||||||
m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this),
|
m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this),
|
||||||
m_banmanager(mapsavedir+DIR_DELIM+"ipban.txt"),
|
|
||||||
m_thread(this),
|
m_thread(this),
|
||||||
m_emergethread(this),
|
m_emergethread(this),
|
||||||
m_time_of_day_send_timer(0),
|
m_time_of_day_send_timer(0),
|
||||||
m_uptime(0),
|
m_uptime(0),
|
||||||
m_mapsavedir(mapsavedir),
|
|
||||||
m_configpath(configpath),
|
|
||||||
m_shutdown_requested(false),
|
m_shutdown_requested(false),
|
||||||
m_ignore_map_edit_events(false)
|
m_ignore_map_edit_events(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
auth_init((char*)"auth.txt");
|
auth_init((char*)"auth.txt");
|
||||||
|
ban_init((char*)"ipban.txt");
|
||||||
|
|
||||||
m_liquid_transform_timer = 0.0;
|
m_liquid_transform_timer = 0.0;
|
||||||
m_print_info_timer = 0.0;
|
m_print_info_timer = 0.0;
|
||||||
|
@ -888,15 +884,12 @@ Server::Server(
|
||||||
// Register us to receive map edit events
|
// Register us to receive map edit events
|
||||||
m_env.getMap().addEventReceiver(this);
|
m_env.getMap().addEventReceiver(this);
|
||||||
|
|
||||||
// If file exists, load environment metadata
|
infostream<<"Server: Loading environment metadata"<<std::endl;
|
||||||
if (fs::PathExists(m_mapsavedir+DIR_DELIM+"env_meta.txt")) {
|
m_env.loadMeta();
|
||||||
infostream<<"Server: Loading environment metadata"<<std::endl;
|
|
||||||
m_env.loadMeta(m_mapsavedir);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load players
|
// Load players
|
||||||
infostream<<"Server: Loading players"<<std::endl;
|
infostream<<"Server: Loading players"<<std::endl;
|
||||||
m_env.deSerializePlayers(m_mapsavedir);
|
m_env.deSerializePlayers();
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::~Server()
|
Server::~Server()
|
||||||
|
@ -939,13 +932,13 @@ Server::~Server()
|
||||||
Save players
|
Save players
|
||||||
*/
|
*/
|
||||||
infostream<<"Server: Saving players"<<std::endl;
|
infostream<<"Server: Saving players"<<std::endl;
|
||||||
m_env.serializePlayers(m_mapsavedir);
|
m_env.serializePlayers();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Save environment metadata
|
Save environment metadata
|
||||||
*/
|
*/
|
||||||
infostream<<"Server: Saving environment metadata"<<std::endl;
|
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();
|
delete i.getNode()->getValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ban_exit();
|
||||||
|
auth_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::start(unsigned short port)
|
void Server::start(unsigned short port)
|
||||||
|
@ -1637,8 +1633,7 @@ void Server::AsyncRunStep()
|
||||||
auth_save();
|
auth_save();
|
||||||
|
|
||||||
//Bann stuff
|
//Bann stuff
|
||||||
if(m_banmanager.isModified())
|
ban_save();
|
||||||
m_banmanager.save();
|
|
||||||
|
|
||||||
// Map
|
// Map
|
||||||
JMutexAutoLock lock(m_env_mutex);
|
JMutexAutoLock lock(m_env_mutex);
|
||||||
|
@ -1661,10 +1656,10 @@ void Server::AsyncRunStep()
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
// Save players
|
// Save players
|
||||||
m_env.serializePlayers(m_mapsavedir);
|
m_env.serializePlayers();
|
||||||
|
|
||||||
// Save environment metadata
|
// 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);
|
Address address = m_con.GetPeerAddress(peer_id);
|
||||||
|
|
||||||
// drop player if is ip is banned
|
// 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,
|
SendAccessDenied(m_con, peer_id,
|
||||||
L"Your ip is banned. Banned name was "
|
L"Your ip is banned. Banned name was "
|
||||||
+narrow_to_wide(m_banmanager.getBanName(
|
+narrow_to_wide(name));
|
||||||
address.serializeString())));
|
|
||||||
m_con.DeletePeer(peer_id);
|
m_con.DeletePeer(peer_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -5785,8 +5783,9 @@ std::wstring Server::getStatusString()
|
||||||
// Saves g_settings to configpath given at initialization
|
// Saves g_settings to configpath given at initialization
|
||||||
void Server::saveConfig()
|
void Server::saveConfig()
|
||||||
{
|
{
|
||||||
if(m_configpath != "")
|
char buff[1024];
|
||||||
g_settings->updateConfigFile(m_configpath.c_str());
|
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)
|
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
|
NOTE: Every public method should be thread-safe
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Server(
|
Server();
|
||||||
std::string mapsavedir,
|
|
||||||
std::string configpath
|
|
||||||
);
|
|
||||||
~Server();
|
~Server();
|
||||||
void start(unsigned short port);
|
void start(unsigned short port);
|
||||||
void stop();
|
void stop();
|
||||||
|
@ -446,19 +443,21 @@ public:
|
||||||
|
|
||||||
void setIpBanned(const std::string &ip, const std::string &name)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unsetIpBanned(const std::string &ip_or_name)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getBanDescription(const std::string &ip_or_name)
|
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)
|
Address getPeerAddress(u16 peer_id)
|
||||||
|
@ -601,9 +600,6 @@ private:
|
||||||
// Connected clients (behind the con mutex)
|
// Connected clients (behind the con mutex)
|
||||||
core::map<u16, RemoteClient*> m_clients;
|
core::map<u16, RemoteClient*> m_clients;
|
||||||
|
|
||||||
// Bann checking
|
|
||||||
BanManager m_banmanager;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Threads
|
Threads
|
||||||
*/
|
*/
|
||||||
|
@ -651,12 +647,6 @@ private:
|
||||||
Random stuff
|
Random stuff
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Map directory
|
|
||||||
std::string m_mapsavedir;
|
|
||||||
|
|
||||||
// Configuration path ("" = no configuration file)
|
|
||||||
std::string m_configpath;
|
|
||||||
|
|
||||||
bool m_shutdown_requested;
|
bool m_shutdown_requested;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -81,6 +81,8 @@
|
||||||
#include "content_toolitem.h"
|
#include "content_toolitem.h"
|
||||||
#include "content_mob.h"
|
#include "content_mob.h"
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
|
#include "thread.h"
|
||||||
|
#include "path.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Settings.
|
Settings.
|
||||||
|
@ -172,19 +174,17 @@ int main(int argc, char *argv[])
|
||||||
porting::signal_handler_init();
|
porting::signal_handler_init();
|
||||||
bool &kill = *porting::signal_handler_killstatus();
|
bool &kill = *porting::signal_handler_killstatus();
|
||||||
|
|
||||||
// Initialize porting::path_data and porting::path_userdata
|
|
||||||
porting::initializePaths(argv[0]);
|
|
||||||
|
|
||||||
// Create user data directory
|
thread_init();
|
||||||
fs::CreateDir(porting::path_userdata);
|
path_init();
|
||||||
|
|
||||||
// Initialize debug streams
|
// Initialize debug streams
|
||||||
#ifdef RUN_IN_PLACE
|
{
|
||||||
std::string debugfile = DEBUGFILE;
|
char buff[1024];
|
||||||
#else
|
if (!path_get(NULL,(char*)"debug.txt",0,buff,1024))
|
||||||
std::string debugfile = porting::path_userdata+DIR_DELIM+DEBUGFILE;
|
return 1;
|
||||||
#endif
|
debugstreams_init(disable_stderr, buff);
|
||||||
debugstreams_init(disable_stderr, debugfile.c_str());
|
}
|
||||||
// Initialize debug stacks
|
// Initialize debug stacks
|
||||||
debug_stacks_init();
|
debug_stacks_init();
|
||||||
|
|
||||||
|
@ -269,39 +269,10 @@ int main(int argc, char *argv[])
|
||||||
Read config file
|
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());
|
char buff[1024];
|
||||||
if(r == false)
|
if (path_get((char*)"config",(char*)"voxelands.conf",0,buff,1024))
|
||||||
{
|
g_settings->readConfigFile(buff);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize random seed
|
// Initialize random seed
|
||||||
|
@ -345,29 +316,20 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
// Port?
|
// Port?
|
||||||
u16 port = 30000;
|
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");
|
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");
|
port = g_settings->getU16("port");
|
||||||
}
|
}else{
|
||||||
else
|
|
||||||
{
|
|
||||||
dstream<<"Please specify port (in config or on command line)"
|
dstream<<"Please specify port (in config or on command line)"
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Figure out path to map
|
/* TODO: configise this */
|
||||||
std::string map_dir = porting::path_userdata+DIR_DELIM+"world";
|
path_world_setter((char*)"default");
|
||||||
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");
|
|
||||||
|
|
||||||
// Create server
|
// Create server
|
||||||
Server server(map_dir.c_str(), configpath);
|
Server server;
|
||||||
server.start(port);
|
server.start(port);
|
||||||
HTTPServer http_server(server);
|
HTTPServer http_server(server);
|
||||||
if (g_settings->getBool("enable_http"))
|
if (g_settings->getBool("enable_http"))
|
||||||
|
|
Loading…
Reference in New Issue