new config and command system pt1

master
darkrose 2017-05-21 20:16:45 +10:00
parent 62d033da29
commit 02462fe854
64 changed files with 3566 additions and 3793 deletions

View File

@ -167,13 +167,21 @@ set(common_SRCS
auth.c
array.c
ban.c
command.c
intl.c
list.c
log.c
nvp.c
config.c
config_default.c
crypto.c
crypto_base64.c
file.c
thread.c
path.c
string.c
bridge_temp.cpp
servercommand.c
log.cpp
content_sao.cpp
mapgen.cpp
@ -195,7 +203,6 @@ set(common_SRCS
content_mapnode_util.cpp
content_list.c
content_nodebox.cpp
intl.c
collision.cpp
nodemetadata.cpp
serverobject.cpp
@ -203,7 +210,6 @@ set(common_SRCS
mineral.cpp
enchantment.cpp
porting.cpp
defaultsettings.cpp
mapnode.cpp
voxel.cpp
inventory.cpp
@ -214,7 +220,6 @@ set(common_SRCS
environment.cpp
plantgrowth.cpp
server.cpp
servercommand.cpp
socket.cpp
mapblock.cpp
mapsector.cpp
@ -409,9 +414,9 @@ else()
set(CMAKE_CXX_FLAGS_RELEASE "${OPT_FLAGS} ${SAFETY_FLAGS} -Wall -DNDEBUG -pipe -fpermissive")
set(CMAKE_CXX_FLAGS_RELEASE "${OPT_FLAGS} ${SAFETY_FLAGS} -Wall -DNDEBUG -pipe -fpermissive -Wno-write-strings")
set(CMAKE_C_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
set(CMAKE_CXX_FLAGS_DEBUG "${SAFETY_FLAGS} -Wall -O0 -g3 -ggdb -fpermissive")
set(CMAKE_CXX_FLAGS_DEBUG "${SAFETY_FLAGS} -Wall -O0 -g3 -ggdb -fpermissive -Wno-write-strings")
set(CMAKE_C_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${OPT_LDFLAGS} ${SAFETY_LDFLAGS}")

View File

@ -17,6 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
************************************************************************/
#include "common.h"
#include "auth.h"
#include "thread.h"
@ -68,13 +69,13 @@ int auth_privs2str(uint64_t privs, char* buff, int size)
if ((privs&p) != p)
continue;
l = strlen(auth.privstr[i]);
if ((o+l+2) < size)
if ((o+l+2) >= size)
continue;
if (r) {
strcat(buff,",");
strcpy(buff+o,",");
o++;
}
strcat(buff,auth.privstr[i]);
strcpy(buff+o,auth.privstr[i]);
o += l;
r++;
}
@ -87,33 +88,32 @@ uint64_t auth_str2privs(char* str)
{
uint64_t privs = 0;
char buff[256];
char* b;
char* e;
int i;
int j;
int o = 0;
char* n;
if (!str)
return 0;
if (!strcpy(buff,str))
return 0;
b = buff;
while (1) {
e = strchr(b,',');
if (e)
*e = 0;
for (i=0; i<PRIV_COUNT; i++) {
if (strcmp(auth.privstr[i],b))
continue;
privs |= (1<<i);
break;
for (i=0; ; i++) {
if (!str[i] || str[i] == ',') {
buff[o] = 0;
o = 0;
n = trim(buff);
for (j=0; j<PRIV_COUNT; j++) {
if (strcmp(auth.privstr[j],n))
continue;
privs |= (1<<j);
break;
}
if (j == PRIV_COUNT)
return PRIV_INVALID;
if (!str[i])
break;
}else if (o<255) {
buff[o++] = str[i];
}
if (i == PRIV_COUNT)
return PRIV_INVALID;
if (e) {
b = e+1;
continue;
}
break;
}
return privs;

237
src/bridge_temp.cpp Normal file
View File

@ -0,0 +1,237 @@
#include "common.h"
#include <stdarg.h>
#include "server.h"
#include "environment.h"
#include "player.h"
#include "sha1.h"
int bridge_server_get_status(command_context_t *ctx, char* buff, int size)
{
if (!ctx)
return 1;
Server *server = static_cast<Server*>(ctx->bridge_server);
if (!server)
return -1;
std::string status = wide_to_narrow(server->getStatusString());
if (snprintf(buff,size,"%s",status.c_str()) >= size)
return 1;
return 0;
}
int bridge_server_notify_player(command_context_t *ctx, char* name, char* str, ...)
{
int l;
char buff[1024];
va_list ap;
if (!ctx)
return 1;
Server *server = static_cast<Server*>(ctx->bridge_server);
if (!server)
return -1;
va_start(ap, str);
l = vsnprintf(buff,1024,str,ap);
va_end(ap);
if (l >= 1024)
return 1;
std::wstring msg(narrow_to_wide(buff));
if (name) {
server->notifyPlayer(name,msg);
}else{
server->notifyPlayers(msg);
}
return 0;
}
int bridge_server_settime(command_context_t *ctx, uint32_t time)
{
if (!ctx)
return 1;
Server *server = static_cast<Server*>(ctx->bridge_server);
if (!server)
return -1;
server->setTimeOfDay(time);
return 0;
}
int bridge_server_shutdown(command_context_t *ctx)
{
if (!ctx)
return -1;
Server *server = static_cast<Server*>(ctx->bridge_server);
if (!server)
return -1;
server->requestShutdown();
return 0;
}
int bridge_server_get_player_ip_or_name(command_context_t *ctx, char* name, char* buff, int size)
{
if (!ctx)
return -1;
Server *server = static_cast<Server*>(ctx->bridge_server);
if (!server)
return -1;
ServerEnvironment *env = static_cast<ServerEnvironment*>(ctx->bridge_env);
if (!env)
return -1;
Player *player = env->getPlayer(name);
if (player == NULL)
return -1;
try{
Address address = server->getPeerAddress(player->peer_id);
std::string ip_string = address.serializeString();
if (ip_string.size() >= (uint32_t)size)
return -1;
strcpy(buff,ip_string.c_str());
} catch(con::PeerNotFoundException) {
std::string ip_string = ((ServerRemotePlayer*)player)->getAddress();
if (ip_string == "")
return -1;
if (ip_string.size() >= (uint32_t)size)
return -1;
strcpy(buff,ip_string.c_str());
}
return 0;
}
int bridge_server_add_player(command_context_t *ctx, char* name, char* pass)
{
if (!ctx)
return -1;
Server *server = static_cast<Server*>(ctx->bridge_server);
if (!server)
return -1;
server->addUser(name,pass);
return 0;
}
int bridge_set_player_password(command_context_t *ctx, char* name, char* pass)
{
if (!ctx)
return -1;
Server *server = static_cast<Server*>(ctx->bridge_server);
if (!server)
return -1;
server->setPlayerPassword(name, pass);
return 0;
}
int bridge_env_check_player(command_context_t *ctx, char* name)
{
if (!ctx)
return -1;
ServerEnvironment *env = static_cast<ServerEnvironment*>(ctx->bridge_env);
if (!env)
return -1;
Player *tp = env->getPlayer(name);
if (tp == NULL)
return 0;
return 1;
}
int bridge_env_player_pos(command_context_t *ctx, char* name, v3_t *pos)
{
if (!ctx)
return -1;
ServerEnvironment *env = static_cast<ServerEnvironment*>(ctx->bridge_env);
if (!env)
return -1;
Player *tp = env->getPlayer(name);
if (tp == NULL)
return 1;
v3f pp = tp->getPosition();
pos->x = pp.X;
pos->y = pp.Y;
pos->z = pp.Z;
return 0;
}
int bridge_env_clear_objects(command_context_t *ctx)
{
if (!ctx)
return -1;
ServerEnvironment *env = static_cast<ServerEnvironment*>(ctx->bridge_env);
if (!env)
return -1;
env->clearAllObjects();
return 0;
}
int bridge_move_player(command_context_t *ctx, v3_t *pos)
{
if (!ctx)
return -1;
Server *server = static_cast<Server*>(ctx->bridge_server);
if (!server)
return -1;
Player *player = static_cast<Player*>(ctx->bridge_player);
if (!player)
return 0;
v3f dest(pos->x,pos->y,pos->z);
player->setPosition(dest);
server->SendMovePlayer(player);
return 0;
}
unsigned char* bridge_sha1(char *str)
{
int l;
if (!str || !str[0])
return NULL;
l = strlen(str);
SHA1 sha1;
sha1.addBytes(str, l);
return sha1.getDigest();
}
std::string bridge_config_get(char* name)
{
char* v = config_get(name);
if (!v)
return "";
return std::string(v);
}

View File

@ -23,6 +23,8 @@
* for Voxelands.
************************************************************************/
#include "common.h"
#include "camera.h"
#include "debug.h"
#include "client.h"
@ -33,7 +35,6 @@
#include "tile.h"
#include <cmath>
#include <SAnimatedMesh.h>
#include "settings.h"
#include "path.h"
#include "constants.h"
#include "content_mapblock.h"
@ -90,13 +91,13 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control, Client
m_wieldnode = new ExtrudedSpriteSceneNode(m_wieldmgr->getRootSceneNode(), m_wieldmgr);
// Get FOV setting
m_fov = g_settings->getFloat("fov");
m_fov = config_get_float("client.graphics.fov");
m_fov = MYMAX(m_fov, 10.0);
m_fov = MYMIN(m_fov, 170.0);
m_view_bobbing_amount = g_settings->getFloat("view_bobbing_amount");
m_view_bobbing_amount = config_get_float("client.graphics.bobbing.amount");
f32 wanted_fps = g_settings->getFloat("wanted_fps");
f32 wanted_fps = config_get_float("client.graphics.fps.min");
wanted_fps = MYMAX(wanted_fps, 1.0);
m_wanted_frametime = 1.0 / wanted_fps;
}
@ -331,10 +332,10 @@ void Camera::updateViewingRange(f32 frametime_in)
m_frametime_counter = 0.2;
// Get current viewing range and FPS settings
f32 viewing_range_min = g_settings->getS16("viewing_range_nodes_min");
float viewing_range_min = config_get_float("client.graphics.range.min");
viewing_range_min = MYMAX(5.0, viewing_range_min);
f32 viewing_range_max = g_settings->getS16("viewing_range_nodes_max");
float viewing_range_max = config_get_float("client.graphics.range.max");
viewing_range_max = MYMAX(viewing_range_min, viewing_range_max);
m_draw_control.wanted_min_range = viewing_range_min;

View File

@ -20,9 +20,9 @@
* for Voxelands.
************************************************************************/
#include "common.h"
#include "character_creator.h"
#include "settings.h"
#include "defaultsettings.h"
#include "debug.h"
#include "serialization.h"
#include <string>
@ -813,9 +813,11 @@ void GUICharDefMenu::fetchPlayerSkin()
{
char buff[1024];
char buf[256];
char* v;
std::string chardef = std::string(PLAYER_DEFAULT_CHARDEF);
if (g_settings->exists("character_definition"))
chardef = g_settings->get("character_definition");
v = config_get("client.character");
if (v)
chardef = v;
Strfnd f(chardef);
m_parts["gender"] = f.next(":");
@ -903,5 +905,5 @@ void GUICharDefMenu::savePlayerSkin()
chardef += std::string(":")+m_parts["pants"];
chardef += std::string(":")+m_parts["shoes"];
g_settings->set("character_definition",chardef);
config_set("client.character",(char*)chardef.c_str());
}

View File

@ -23,6 +23,7 @@
* for Voxelands.
************************************************************************/
#include "common.h"
#include "client.h"
#include "utility.h"
@ -35,7 +36,6 @@
#include "mapsector.h"
#include "mapblock_mesh.h"
#include "mapblock.h"
#include "settings.h"
#include "profiler.h"
#include "log.h"
#include "http.h"
@ -201,7 +201,6 @@ void * MeshUpdateThread::Thread()
Client::Client(
IrrlichtDevice *device,
const char *playername,
std::string password,
MapDrawControl &control,
ISoundManager *sound):
@ -257,7 +256,12 @@ Client::Client(
Player *player = new LocalPlayer();
player->updateName(playername);
char* v = config_get("client.name");
if (v) {
player->updateName(v);
}else{
player->updateName(porting::getUser().c_str());
}
m_env.addPlayer(player);
@ -415,9 +419,11 @@ void Client::step(float dtime)
if (m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime)) {
ScopeProfiler sp(g_profiler, "Client: map timer and unload");
core::list<v3s16> deleted_blocks;
m_env.getMap().timerUpdate(map_timer_and_unload_dtime,
g_settings->getFloat("client_unload_unused_data_timeout"),
&deleted_blocks);
m_env.getMap().timerUpdate(
map_timer_and_unload_dtime,
config_get_float("client.chunk.timeout"),
&deleted_blocks
);
/*if(deleted_blocks.size() > 0)
infostream<<"Client: Unloaded "<<deleted_blocks.size()
@ -750,9 +756,11 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
{
// Reply to server
char *v;
std::string chardef = std::string(PLAYER_DEFAULT_CHARDEF);
if (g_settings->exists("character_definition"))
chardef = g_settings->get("character_definition");
v = config_get("client.character");
if (v)
chardef = v;
std::ostringstream os(std::ios_base::binary);
u8 buf[12];
@ -1730,10 +1738,11 @@ void Client::sendInventoryAction(InventoryAction *a)
Send(0, data, true);
}
void Client::sendChatMessage(const std::wstring &message)
void Client::sendChatMessage(const std::wstring &msg)
{
std::ostringstream os(std::ios_base::binary);
u8 buf[12];
std::ostringstream os(std::ios_base::binary);
std::string message = wide_to_narrow(msg);
// Write command
writeU16(buf, TOSERVER_CHAT_MESSAGE);
@ -1743,13 +1752,8 @@ void Client::sendChatMessage(const std::wstring &message)
writeU16(buf, message.size());
os.write((char*)buf, 2);
// Write string
for(u32 i=0; i<message.size(); i++)
{
u16 w = message[i];
writeU16(buf, w);
os.write((char*)buf, 2);
}
// write string
os.write(message.c_str(),message.size());
// Make data buffer
std::string s = os.str();

View File

@ -169,7 +169,6 @@ public:
Client(
IrrlichtDevice *device,
const char *playername,
std::string password,
MapDrawControl &control,
ISoundManager *sound

View File

@ -342,7 +342,7 @@ enum ToServerCommand
/*
u16 command
u16 length
wstring message
string message
*/
TOSERVER_CLICK_ACTIVEOBJECT = 0x34,

View File

@ -23,13 +23,14 @@
* for Voxelands.
************************************************************************/
#include "common.h"
#include "clouds.h"
#include "noise.h"
#include "constants.h"
#include "debug.h"
#include "main.h" // For g_profiler and g_settings
#include "profiler.h"
#include "settings.h"
Clouds::Clouds(
scene::ISceneNode* parent,
@ -56,7 +57,7 @@ Clouds::Clouds(
m_box = core::aabbox3d<f32>(-BS*1000000,m_cloud_y-BS,-BS*1000000, BS*1000000,m_cloud_y+BS,BS*1000000);
m_face_count = 1;
if (g_settings->getU16("mesh_detail") > 1)
if (config_get_int("client.graphics.mesh.lod") > 1)
m_face_count = 6;
}

439
src/command.c Normal file
View File

@ -0,0 +1,439 @@
/************************************************************************
* command.c
* voxelands - 3d voxel world sandbox game
* Copyright (C) Lisa 'darkrose' Milne 2016 <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/>
************************************************************************/
#include "common.h"
#include "nvp.h"
#include "array.h"
#include "thread.h"
#include "file.h"
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
typedef struct setter_s {
int (*func)(command_context_t *ctx, array_t *args);
int (*help)();
uint8_t client;
} setter_t;
static struct {
nvp_t *list;
mutex_t *mutex;
} command_data = {
NULL,
NULL
};
static int command_alias(command_context_t *ctx, array_t *args)
{
char* a;
char* c;
nvp_t *n;
if (!args) {
n = command_data.list;
while (n) {
if (n->value)
command_print(ctx, 0, CN_INFO, "alias: %s %s",n->name,n->value);
n = n->next;
}
return 0;
}
a = array_get_string(args,0);
c = array_join(args," ",1);
n = nvp_get(&command_data.list,a);
if (!n) {
if (c)
nvp_set(&command_data.list,a,c,NULL);
return 0;
}
if (!n->value) {
command_print(ctx, 0, CN_WARN, "alias: Cannot unalias built-in command '%s'",a);
return 1;
}
nvp_set(&command_data.list,a,c,NULL);
return 0;
}
static int command_help(command_context_t *ctx, array_t *args)
{
nvp_t *n;
setter_t *s;
if (args) {
char* c = array_get_string(args,0);
if (!c)
return 1;
n = nvp_get(&command_data.list,c);
if (!n)
return 1;
s = n->data;
if (s && s->help) {
/* TODO: implement the help() functionality */
s->help();
return 0;
}
command_print(ctx, 0, CN_INFO, "%s [arguments]",c);
return 0;
}
return 0;
}
/*
global - settings that are used by the server and client, and aren't per-world
log - settings related to logging
path - settings related to file paths
server - settings used soley by the server, and aren't per-world
client - settings used soley by the client (never per-world)
debug - debug related settings used by client and/or server
world - per-world settings
*/
/* returns 0 for client, 1 for server, and -1 for both */
static int command_set_detect(char* name)
{
if (!name)
return 0;
if (!strncmp(name,"client.",7))
return 0;
if (!strncmp(name,"path.",5))
return 0;
if (!strncmp(name,"debug.",6))
return -1;
if (!strncmp(name,"log.",4))
return -1;
if (!strncmp(name,"global.",7))
return -1;
return 1;
}
static int command_send(char* name, array_t *args)
{
command_print(NULL, 0, CN_WARN, "Server-side command not sent: '%s'",name);
return 1;
}
static int command_set(command_context_t *ctx, array_t *args)
{
char* n;
int v;
n = array_get_string(args,0);
if (!n)
return 1;
if (!ctx) {
v = command_set_detect(n);
if (v) {
command_send("set",args);
if (v == 1)
return 0;
}
}
config_set_command(ctx,args);
return 0;
}
static int command_toggle(command_context_t *ctx, array_t *args)
{
char* n;
int v;
n = array_get_string(args,0);
if (!n)
return 1;
if (!ctx) {
v = command_set_detect(n);
if (v) {
command_send("toggle",args);
if (v == 1)
return 0;
}
}
v = config_get_bool(n);
config_set_int(n,!v);
return 0;
}
static int command_unset(command_context_t *ctx, array_t *args)
{
char* n;
int v;
n = array_get_string(args,0);
if (!n)
return 1;
if (!ctx) {
v = command_set_detect(n);
if (v) {
command_send("unset",args);
if (v == 1)
return 0;
}
}
config_set_command(ctx,args);
return 0;
}
void command_print(command_context_t *ctx, uint16_t flags, uint8_t type, char* str, ...)
{
int l;
char buff[1024];
va_list ap;
va_start(ap, str);
l = vsnprintf(buff,1024,str,ap);
va_end(ap);
if (l >= 1024) {
if (ctx)
ctx->flags = 0;
return;
}
if (ctx) {
if (type < CN_ACTION || !flags) {
ctx->flags = SEND_TO_SENDER;
}else{
ctx->flags = flags;
}
strcpy(ctx->reply,buff);
}
vlprint(type,buff);
}
/* initialise commands */
int command_init()
{
command_data.mutex = mutex_create();
command_add("help",command_help,1);
command_add("set",command_set,1);
command_add("toggle",command_toggle,1);
command_add("unset",command_unset,1);
command_add("exec",config_load_command,1);
command_add("ignore",config_ignore_command,1);
command_add("alias",command_alias,1);
command_add("status",command_status,0);
command_add("me",command_me,0);
command_add("privs",command_privs,0);
command_add("grant",command_grant,0);
command_add("revoke",command_revoke,0);
command_add("time",command_time,0);
command_add("shutdown",command_shutdown,0);
command_add("teleport",command_teleport,0);
command_add("ban",command_ban,0);
command_add("unban",command_unban,0);
command_add("adduser",command_adduser,0);
command_add("clearobjects",command_clearobjects,0);
command_add("setpassword",command_setpassword,0);
/* command_add("bind",event_bind);
command_add("jump",control_jump);
command_add("sneak",control_sneak);
command_add("inventory",control_inventory);
command_add("examine",control_examine);
command_add("use",control_use);
command_add("chat",control_chat);
command_add("fly",control_fly);
command_add("up",control_up);
command_add("down",control_down);
command_add("run",control_run);
command_add("dig",control_dig);
command_add("place",control_place);
command_add("wield0",control_wield0);
command_add("wield1",control_wield1);
command_add("wield2",control_wield2);
command_add("wield3",control_wield3);
command_add("wield4",control_wield4);
command_add("wield5",control_wield5);
command_add("wield6",control_wield6);
command_add("wield7",control_wield7);
command_add("wieldnext",control_wieldnext);
command_add("wieldprev",control_wieldprev);
command_add("console",control_console);
command_add("capture",control_capture);
*/
return 0;
}
/* register a new command function */
int command_add(char* name, int (*func)(command_context_t *ctx, array_t *args), uint8_t clientside)
{
nvp_t *n;
setter_t *s;
n = nvp_get(&command_data.list,name);
if (n && n->data) {
s = n->data;
if (s->func)
return 1;
}
s = malloc(sizeof(setter_t));
if (!s)
return 1;
s->func = func;
s->help = NULL;
s->client = clientside;
nvp_set(&command_data.list,name,NULL,s);
return 0;
}
/* apply a command */
int command_apply(command_context_t *ctx, char* name, char* value)
{
int r;
setter_t *s;
nvp_t *n;
array_t *args;
int (*func)(command_context_t *ctx, array_t *args);
mutex_lock(command_data.mutex);
n = nvp_get(&command_data.list,name);
if (!n) {
mutex_unlock(command_data.mutex);
command_print(ctx, 0, CN_WARN, "Unknown command: '%s'",name);
return 1;
}
if (n->value) {
char buff[256];
strcpy(buff,n->value);
mutex_unlock(command_data.mutex);
if (value) {
return command_execf(ctx,"%s %s",buff,value);
}else{
return command_exec(ctx,buff);
}
}
if (!n->data) {
mutex_unlock(command_data.mutex);
command_print(ctx, 0, CN_WARN, "Invalid command: '%s'",name);
return 1;
}
s = n->data;
if (!s->func) {
mutex_unlock(command_data.mutex);
command_print(ctx, 0, CN_WARN, "Invalid command: '%s'",name);
return 1;
}
if (!s->client && !ctx) {
command_send(name,args);
return 0;
}
func = s->func;
mutex_unlock(command_data.mutex);
args = array_split(value," ",1);
r = func(ctx,args);
array_free(args,1);
return r;
}
/* execute a command */
int command_exec(command_context_t *ctx, char* str)
{
int r;
char* cmd = str;
char* spc;
if (!cmd || !cmd[0])
return 1;
spc = strchr(cmd,' ');
if (cmd[0] == '/')
cmd++;
vlprintf(CN_INFO, "%s",cmd);
if (spc && spc[0]) {
char* args = spc+1;
*spc = 0;
r = command_apply(ctx,cmd,args);
*spc = ' ';
}else{
r = command_apply(ctx,cmd,NULL);
}
return r;
}
/* execute a command from a formatted string */
int command_execf(command_context_t *ctx, char* str, ...)
{
int l;
char buff[1024];
va_list ap;
va_start(ap, str);
l = vsnprintf(buff,1024,str,ap);
va_end(ap);
if (l >= 1024)
return 1;
return command_exec(ctx,buff);
}
/* save alias to file */
void command_save(file_t *f)
{
nvp_t *n = command_data.list;
while (n) {
if (!n->data)
file_writef(f,"alias %s %s\n",n->name,n->value);
n = n->next;
}
}

198
src/common.h Normal file
View File

@ -0,0 +1,198 @@
#ifndef _COMMON_H_
#define _COMMON_H_
#ifdef __cplusplus
extern "C" {
#endif
#ifndef LINUX
#ifdef __linux__
#define LINUX
#endif
#endif
#ifdef LINUX
#ifdef _POSIX_C_SOURCE
#undef _POSIX_C_SOURCE
#endif
#define _POSIX_C_SOURCE 200112L
#ifdef _XOPEN_SOURCE
#undef _XOPEN_SOURCE
#endif
#define _XOPEN_SOURCE 700
#ifdef _DEFAULT_SOURCE
#undef _DEFAULT_SOURCE
#endif
#define _DEFAULT_SOURCE
#endif
#include <stdlib.h>
#include <stdint.h>
#include "array.h"
#include "file.h"
#ifndef _HAVE_V3_TYPE
#define _HAVE_V3_TYPE
typedef struct v3_s {
float x;
float y;
float z;
} __attribute__((packed)) v3_t;
#endif
#ifndef _HAVE_COMMAND_CONTEXT_TYPE
#define _HAVE_COMMAND_CONTEXT_TYPE
typedef struct command_context_s {
char player[256];
uint64_t privs;
uint32_t flags;
char reply[2048];
/* bridge stuff TODO: remove */
void* bridge_server;
void* bridge_env;
void* bridge_player;
} command_context_t;
#endif
#define CN_ERROR 0x01
#define CN_WARN 0x02
#define CN_ACTION 0x03
#define CN_CHAT 0x04
#define CN_INFO 0x05
#define CN_DEBUG 0x06
#define SEND_TO_SENDER (1<<0)
#define SEND_TO_OTHERS (1<<1)
#define SEND_NO_PREFIX (1<<2)
/* defined in string.c */
char* trim(char* str);
/*char* strdup(const char* str);*/
int str_sanitise(char* dest, int size, char* str);
int strappend(char* dest, int size, char* str);
int parse_bool(char* str);
int str_tov3t(char* str, v3_t *v);
int str_topwd(char* name, char* pass, char* buff, int size);
/* defined in config.c */
char* config_get(char* name);
int config_get_int(char* name);
int64_t config_get_int64(char* name);
float config_get_float(char* name);
int config_get_bool(char* name);
int config_get_v3t(char* name, v3_t *value);
void config_set(char* name, char* value);
int config_set_command(command_context_t *ctx, array_t *args);
void config_set_int(char* name, int value);
void config_set_int64(char* name, int64_t value);
void config_set_float(char* name, float value);
void config_set_default(char* name, char* value, int (*setter)(char* v));
void config_set_default_int(char* name, int value, int (*setter)(char* v));
void config_set_default_float(char* name, float value, int (*setter)(char* v));
void config_load(char* file);
int config_load_command(command_context_t *ctx, array_t *args);
int config_ignore_command(command_context_t *ctx, array_t *args);
void config_init(int argc, char** argv);
void config_save(char* section, char* type, char* file);
/* defined in config_default.c */
void config_default_init(void);
void config_default_creative(void);
void config_default_survival(void);
int config_default_gamemode(char* mode);
/* defined in log.c */
int log_minlevel_setter(char* v);
int log_maxlevel_setter(char* v);
int log_sminlevel_setter(char* v);
int log_smaxlevel_setter(char* v);
int log_cminlevel_setter(char* v);
int log_cmaxlevel_setter(char* v);
int log_file_setter(char* v);
void vlprint(uint8_t type, char* str);
void vlprintf(uint8_t type, char* fmt,...);
/* defined in utf8.c */
int utf8_seqlen(char* str);
uint32_t utf8_nextchar(char* str, int *i);
uint32_t utf8_toutf32(char* src, int size);
int utf8_fromutf32(char *dest, int sz, uint32_t ch);
uint32_t utf16_toutf32(uint16_t *str);
int utf8_offset(char* str, int i);
int utf8_charindex(char* str, int o);
int utf8_strlen(char* str);
void utf8_inc(char* str, int *i);
void utf8_dec(char* str, int *i);
char* utf8_strchr(char* str, uint32_t ch, int *charn);
char* utf8_memchr(char* str, uint32_t ch, size_t sz, int *charn);
/* defined in sys_console.c */
void sys_console_print(char* str, int newline);
void sys_console_printf(char* fmt, ...);
void sys_console_init(void);
void sys_console_exit(void);
/* defined in time.c */
void time_init(void);
uint32_t time_ticks(void);
void delay(uint32_t ms);
float time_dtime(uint32_t last);
uint32_t interval_delay(uint32_t last, uint32_t hz);
uint32_t calc_fps(uint32_t prev, uint32_t current);
/* defined in command.c */
int command_init(void);
void command_print(command_context_t *ctx, uint16_t flags, uint8_t type, char* str, ...);
int command_add(char* name, int (*func)(command_context_t *ctx, array_t *args), uint8_t clientside);
int command_apply(command_context_t *ctx, char* name, char* value);
int command_exec(command_context_t *ctx, char* str);
int command_execf(command_context_t *ctx, char* str, ...);
void command_save(file_t *f);
/* defined in servercommand.c */
int command_status(command_context_t *ctx, array_t *args);
int command_me(command_context_t *ctx, array_t *args);
int command_privs(command_context_t *ctx, array_t *args);
int command_grant(command_context_t *ctx, array_t *args);
int command_revoke(command_context_t *ctx, array_t *args);
int command_time(command_context_t *ctx, array_t *args);
int command_shutdown(command_context_t *ctx, array_t *args);
int command_teleport(command_context_t *ctx, array_t *args);
int command_ban(command_context_t *ctx, array_t *args);
int command_unban(command_context_t *ctx, array_t *args);
int command_adduser(command_context_t *ctx, array_t *args);
int command_clearobjects(command_context_t *ctx, array_t *args);
int command_setpassword(command_context_t *ctx, array_t *args);
#ifdef __cplusplus
}
#include <string>
std::string bridge_config_get(char* name);
#endif
/* bridge stuff TODO: remove */
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
EXTERNC int bridge_server_get_status(command_context_t *ctx, char* buff, int size);
EXTERNC int bridge_server_notify_player(command_context_t *ctx, char* name, char* str, ...);
EXTERNC int bridge_server_settime(command_context_t *ctx, uint32_t time);
EXTERNC int bridge_server_shutdown(command_context_t *ctx);
EXTERNC int bridge_server_get_player_ip_or_name(command_context_t *ctx, char* name, char* buff, int size);
EXTERNC int bridge_server_add_player(command_context_t *ctx, char* name, char* pass);
EXTERNC int bridge_set_player_password(command_context_t *ctx, char* name, char* pass);
EXTERNC int bridge_env_check_player(command_context_t *ctx, char* name);
EXTERNC int bridge_env_player_pos(command_context_t *ctx, char* name, v3_t *pos);
EXTERNC int bridge_env_clear_objects(command_context_t *ctx);
EXTERNC int bridge_move_player(command_context_t *ctx, v3_t *pos);
EXTERNC unsigned char* bridge_sha1(char *str);
#endif

406
src/config.c Normal file
View File

@ -0,0 +1,406 @@
/************************************************************************
* config.c
* voxelands - 3d voxel world sandbox game
* Copyright (C) Lisa 'darkrose' Milne 2016 <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/>
************************************************************************/
#include "common.h"
#include "auth.h"
#include "nvp.h"
#include "crypto.h"
#include "file.h"
#include "array.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static struct {
nvp_t *items;
nvp_t *files;
int isinit;
} config = {
NULL,
NULL,
0
};
typedef struct config_s {
char* default_value;
int (*setter)(char* v);
} config_t;
/* get the value of a config setting */
char* config_get(char* name)
{
nvp_t *n = nvp_get(&config.items,name);
if (!n)
return NULL;
if (!n->value)
return ((config_t*)n->data)->default_value;
return n->value;
}
/* get a config setting as an int value */
int config_get_int(char* name)
{
char* v = config_get(name);
if (v)
return strtol(v,NULL,10);
return 0;
}
/* get a config setting as an int value */
int64_t config_get_int64(char* name)
{
char* v = config_get(name);
if (v)
return strtoll(v,NULL,10);
return 0;
}
/* get a config setting as a float value */
float config_get_float(char* name)
{
char* v = config_get(name);
if (v)
return strtof(v,NULL);
return 0.0;
}
/* get a config setting as a boolean value */
int config_get_bool(char* name)
{
char* v = config_get(name);
return parse_bool(v);
}
/* get a config setting as a v3_t value */
int config_get_v3t(char* name, v3_t *value)
{
char* v = config_get(name);
if (!v)
return 1;
return str_tov3t(v,value);
}
/* set the value of a config setting */
void config_set(char* name, char* value)
{
config_t *c;
nvp_t *n;
if (!name)
return;
n = nvp_get(&config.items,name);
if (!n) {
if (!value)
return;
c = malloc(sizeof(config_t));
c->default_value = NULL;
c->setter = NULL;
nvp_set(&config.items,name,value,c);
return;
}
if (n->value)
free(n->value);
n->value = NULL;
if (value)
n->value = strdup(value);
c = n->data;
if (c->setter) {
if (!n->value && c->default_value) {
c->setter(c->default_value);
}else{
c->setter(n->value);
}
}
}
/* set a config setting from a command */
int config_set_command(command_context_t *ctx, array_t *args)
{
char* n;
char* v;
if (!args)
return 1;
if (ctx && (ctx->privs&PRIV_SERVER) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
n = array_get_string(args,0);
v = array_join(args," ",1);
config_set(n,v);
return 0;
}
/* set a config setting to an int value */
void config_set_int(char* name, int value)
{
char str[20];
sprintf(str,"%d",value);
config_set(name,str);
}
/* set a config setting to a 64bit int value */
void config_set_int64(char* name, int64_t value)
{
char str[50];
sprintf(str,"%ld",value);
config_set(name,str);
}
/* set a config setting to a float value */
void config_set_float(char* name, float value)
{
char str[50];
sprintf(str,"%f",value);
config_set(name,str);
}
/* set the default value of a config setting */
void config_set_default(char* name, char* value, int (*setter)(char* v))
{
config_t *c;
nvp_t *n = nvp_get(&config.items,name);
if (!n) {
if (!value && !setter)
return;
c = malloc(sizeof(config_t));
if (value) {
c->default_value = strdup(value);
}else{
c->default_value = NULL;
}
c->setter = setter;
nvp_set(&config.items,name,NULL,c);
if (setter)
setter(value);
return;
}
c = n->data;
if (c->default_value)
free(c->default_value);
c->default_value = NULL;
if (value)
c->default_value = strdup(value);
}
/* set the default of a config setting to an int value */
void config_set_default_int(char* name, int value, int (*setter)(char* v))
{
char str[20];
sprintf(str,"%d",value);
config_set_default(name,str,setter);
}
/* set the default of a config setting to a float value */
void config_set_default_float(char* name, float value, int (*setter)(char* v))
{
char str[50];
sprintf(str,"%f",value);
config_set_default(name,str,setter);
}
/* load a config file */
void config_load(char* file)
{
char buff[2048];
int s;
char* l;
command_context_t ctx;
file_t *f = file_load("config",file);
if (!f)
return;
ctx.player[0] = 0;
ctx.privs = PRIV_ALL;
ctx.flags = 0;
ctx.bridge_server = NULL;
ctx.bridge_env = NULL;
ctx.bridge_player = NULL;
while ((s = file_readline(f,buff,2048)) > -1) {
if (!s || buff[0] == '#')
continue;
l = trim(buff);
if (l && l[0])
command_exec(&ctx,l);
}
file_free(f);
}
/* load a config file from a command */
int config_load_command(command_context_t *ctx, array_t *args)
{
char* f;
if (!args)
return 1;
if (ctx && (ctx->privs&PRIV_SERVER) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
f = array_get_string(args,0);
nvp_set(&config.files,f,"true",NULL);
config_load(f);
return 0;
}
/* set the ignore flag for a config file from a command */
int config_ignore_command(command_context_t *ctx, array_t *args)
{
char* f;
if (!args)
return 1;
if (ctx && (ctx->privs&PRIV_SERVER) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
f = array_get_string(args,0);
nvp_set(&config.files,f,"false",NULL);
return 0;
}
/* initialise configuration, load config files and defaults, etc */
void config_init(int argc, char** argv)
{
int i;
nvp_t *n;
config_default_init();
/* add the default config file to the to-exec list */
nvp_set(&config.files,"default.cfg","true",NULL);
for (i=1; i<(argc-1); i++) {
if (!strcmp(argv[i],"exec")) {
i += 1;
nvp_set(&config.files,argv[i],"true",NULL);
}else if (!strcmp(argv[i],"ignore")) {
i += 1;
nvp_set(&config.files,argv[i],"false",NULL);
}
}
n = config.files;
while (n) {
if (n->value && !strcmp(n->value,"true"))
config_load(n->name);
n = n->next;
}
for (i=0; i<argc; i++) {
if (!strcmp(argv[i],"set") && i+2 < argc) {
config_set(argv[i+1],argv[i+2]);
i+=2;
}else if (!strcmp(argv[i],"unset") && i+1 < argc) {
i+=1;
config_set(argv[i],NULL);
}else if (!strcmp(argv[i],"exec")) {
i += 1;
}else if (!strcmp(argv[i],"ignore")) {
i += 1;
}
}
config.isinit = 1;
}
/* save the current config */
void config_save(char* section, char* type, char* file)
{
file_t *f;
nvp_t *n;
if (!type && !file) {
n = config.files;
while (n) {
if (n->value && !strcmp(n->value,"true"))
break;
n = n->next;
}
/* TODO: should probably force saving to somewhere, custom.cfg? */
if (!n)
return;
f = file_create("config",n->name);
}else{
f = file_create(type,file);
}
if (!f)
return;
if (section) {
int l;
l = strlen(section);
n = config.items;
while (n) {
if (n->value && !strncmp(n->name,section,l))
file_writef(f,"set %s %s\n",n->name,n->value);
n = n->next;
}
}else{
n = config.items;
while (n) {
if (n->value)
file_writef(f,"set %s %s\n",n->name,n->value);
n = n->next;
}
/*
events_save(f);
*/
command_save(f);
}
file_flush(f);
file_free(f);
}

226
src/config_default.c Normal file
View File

@ -0,0 +1,226 @@
/************************************************************************
* config_default.c
* voxelands - 3d voxel world sandbox game
* Copyright (C) Lisa 'darkrose' Milne 2016 <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/>
************************************************************************/
#include "common.h"
#include "path.h"
#include <string.h>
void config_default_init()
{
config_set_default("log.min_level","error",log_minlevel_setter);
config_set_default("log.max_level","info",log_maxlevel_setter);
config_set_default("log.system.min_level","chat",log_sminlevel_setter);
config_set_default("log.system.max_level","info",log_smaxlevel_setter);
config_set_default("log.console.min_level","chat",log_cminlevel_setter);
config_set_default("log.console.max_level","info",log_cmaxlevel_setter);
config_set_default("path.log",NULL,log_file_setter);
config_set_default("path.data.custom",NULL,path_custom_setter);
config_set_default("path.screenshot",NULL,path_screenshot_setter);
config_set_default("world.path",NULL,path_world_setter);
config_set_default("debug.profiler.interval","0",NULL);
config_set_default("debug.show","false",NULL);
#ifndef SERVER
config_set_default("client.video.anisotropic","true",NULL);
config_set_default("client.video.bilinear","true",NULL);
config_set_default("client.video.trilinear","true",NULL);
config_set_default("client.video.mipmaps","true",NULL);
config_set_default("client.video.fullscreen","false",NULL);
config_set_default("client.video.fullscreen.bpp","24",NULL);
config_set_default("client.video.fullscreen.fsaa","0",NULL);
config_set_default("client.video.vsync","false",NULL);
config_set_default("client.video.size.width","1024",NULL);
config_set_default("client.video.size.height","600",NULL);
config_set_default("client.video.driver","opengl",NULL);
config_set_default("client.video.hpfpu","true",NULL);
config_set_default("client.sound.volume","50",NULL);
config_set_default("client.graphics.mesh.lod","3",NULL);
config_set_default("client.graphics.texture.animations","true",NULL);
config_set_default("client.graphics.texture.atlas","true",NULL);
config_set_default("client.graphics.texture.lod","3",NULL);
config_set_default("client.graphics.light.lod","3",NULL);
config_set_default("client.graphics.light.fog","true",NULL);
config_set_default("client.graphics.fov","72",NULL);
config_set_default("client.graphics.fps.min","30",NULL);
config_set_default("client.graphics.fps.max","60",NULL);
config_set_default("client.graphics.bobbing","true",NULL);
config_set_default("client.graphics.bobbing.amount","1.0",NULL);
config_set_default("client.graphics.range.min","15",NULL);
config_set_default("client.graphics.range.max","300",NULL);
config_set_default("client.graphics.particles","true",NULL);
config_set_default("client.graphics.clouds","true",NULL);
config_set_default("client.graphics.water.opaque","false",NULL);
config_set_default("client.graphics.selection","highlight",NULL);
config_set_default("client.ui.mainmenu.tab","singleplayer",NULL);
config_set_default("client.ui.hud.old","false",NULL);
config_set_default("client.ui.hud.wieldindex","false",NULL);
config_set_default("client.ui.mouse.invert","false",NULL);
config_set_default("client.ui.mouse.sensitivity","0.2",NULL);
config_set_default("client.ui.font","unifont.ttf",NULL);
config_set_default("client.ui.font.size","14",NULL);
config_set_default("client.chunk.timeout","600",NULL);
config_set_default("keymap_forward","KEY_KEY_W",NULL);
config_set_default("keymap_backward","KEY_KEY_S",NULL);
config_set_default("keymap_left","KEY_KEY_A",NULL);
config_set_default("keymap_right","KEY_KEY_D",NULL);
config_set_default("keymap_jump","KEY_SPACE",NULL);
config_set_default("keymap_sneak","KEY_LSHIFT",NULL);
config_set_default("keymap_inventory","KEY_KEY_I",NULL);
config_set_default("keymap_examine","KEY_KEY_Q",NULL);
config_set_default("keymap_use","KEY_KEY_H",NULL);
config_set_default("keymap_chat","KEY_KEY_T",NULL);
config_set_default("keymap_cmd","/",NULL);
config_set_default("keymap_rangeselect","KEY_KEY_O",NULL);
config_set_default("keymap_freemove","KEY_KEY_K",NULL);
config_set_default("keymap_up","KEY_KEY_R",NULL);
config_set_default("keymap_down","KEY_KEY_F",NULL);
config_set_default("keymap_run","KEY_KEY_E",NULL);
config_set_default("keymap_screenshot","KEY_F12",NULL);
config_set_default("keymap_toggle_hud","KEY_F1",NULL);
config_set_default("keymap_toggle_chat","KEY_F2",NULL);
config_set_default("keymap_toggle_force_fog_off","KEY_F3",NULL);
config_set_default("keymap_toggle_update_camera","KEY_F4",NULL);
config_set_default("keymap_toggle_debug","KEY_F5",NULL);
config_set_default("keymap_toggle_profiler","KEY_F6",NULL);
config_set_default("keymap_increase_viewing_range_min","KEY_PRIOR",NULL);
config_set_default("keymap_decrease_viewing_range_min","KEY_NEXT",NULL);
config_set_default("keymap_select_prev",",",NULL);
config_set_default("keymap_select_next",".",NULL);
/* some (temporary) keys for debugging o.0 */
config_set_default("keymap_print_debug_stacks","KEY_KEY_P",NULL);
config_set_default("new_style_water","false",NULL);
config_set_default("new_style_leaves","true",NULL);
config_set_default("continuous_forward","false",NULL);
config_set_default("invisible_stone","false",NULL);
#endif
/* game/world */
config_set_default("world.player.inventory.starter","false",NULL);
config_set_default("world.player.inventory.creative","false",NULL);
config_set_default("world.player.inventory.droppable","true",NULL);
config_set_default("world.player.inventory.keep","false",NULL);
config_set_default("world.player.tool.wear","true",NULL);
config_set_default("world.player.damage","true",NULL);
config_set_default("world.player.suffocation","true",NULL);
config_set_default("world.player.hunger","true",NULL);
config_set_default("world.game.mob.spawn.level","destructive",NULL);
#ifndef SERVER
config_set_default("world.player.lava","true",NULL);
config_set_default("world.game.environment.tnt","true",NULL);
#else
config_set_default("world.player.lava","false",NULL);
config_set_default("world.game.environment.tnt","false",NULL);
#endif
config_set_default("world.game.mode","survival",config_default_gamemode);
config_set_default("world.game.borderstone.radius","5",NULL);
config_set_default("world.game.mob.spawn.natural","true",NULL);
config_set_default("world.game.environment.footprints","true",NULL);
config_set_default("world.game.environment.fire.spread","false",NULL);
config_set_default("world.game.environment.time.speed","96",NULL);
config_set_default("world.game.motd","",NULL);
config_set_default("world.map.type","default",NULL);
/* server */
config_set_default("world.server.chunk.range.active","2",NULL);
config_set_default("world.server.chunk.range.send","7",NULL);
config_set_default("world.server.chunk.range.generate","5",NULL);
config_set_default("world.server.mob.range","3",NULL);
config_set_default("world.server.client.version.strict","false",NULL);
config_set_default("world.server.client.private","false",NULL);
config_set_default("world.server.client.emptypwd","false",NULL);
config_set_default("world.server.client.default.password","",NULL);
config_set_default("world.server.client.default.privs","build, shout",NULL);
config_set_default("world.server.client.max","20",NULL);
config_set_default("world.server.admin","",NULL);
config_set_default("server.net.client.queue.size","4",NULL);
config_set_default("server.net.client.queue.delay","2.0",NULL);
config_set_default("server.net.client.time.interval","5",NULL);
config_set_default("server.net.client.object.interval","0.2",NULL);
/* only enable http on the server, singleplayer doesn't need it */
#ifndef SERVER
config_set_default("server.net.http","false",NULL);
#else
config_set_default("server.net.http","true",NULL);
#endif
config_set_default("server.net.chunk.max","20",NULL);
config_set_default("server.chunk.timeout","19",NULL);
config_set_default("server.save.interval","300",NULL);
config_set_default("global.api.address","servers.voxelands.com",NULL);
#ifdef SERVER
config_set_default("world.server.api.announce","true",NULL);
#else
config_set_default("world.server.api.announce","false",NULL);
#endif
config_set_default("world.server.name","Voxelands Server",NULL);
config_set_default("world.server.address","",NULL);
config_set_default("world.server.port","30000",NULL);
config_default_survival();
}
void config_default_creative()
{
config_set_default("world.player.inventory.creative","true",NULL);
config_set_default("world.player.inventory.droppable","false",NULL);
config_set_default("world.player.inventory.keep","true",NULL);
config_set_default("world.player.tool.wear","false",NULL);
config_set_default("world.player.damage","false",NULL);
config_set_default("world.player.suffocation","false",NULL);
config_set_default("world.player.hunger","false",NULL);
config_set_default("world.game.mob.spawn.level","passive",NULL);
}
void config_default_survival()
{
config_set_default("world.player.inventory.creative","false",NULL);
config_set_default("world.player.inventory.droppable","true",NULL);
config_set_default("world.player.inventory.keep","false",NULL);
config_set_default("world.player.tool.wear","true",NULL);
config_set_default("world.player.damage","true",NULL);
config_set_default("world.player.suffocation","true",NULL);
config_set_default("world.player.hunger","true",NULL);
config_set_default("world.game.mob.spawn.level","destructive",NULL);
}
int config_default_gamemode(char* mode)
{
if (mode && !strcmp(mode,"creative")) {
config_default_creative();
}else{
config_default_survival();
}
return 0;
}

View File

@ -23,11 +23,12 @@
* for Voxelands.
************************************************************************/
#include "common.h"
#include "content_cao.h"
#include "content_mob.h"
#include "path.h"
#include "environment.h"
#include "settings.h"
#include "mesh.h"
#include <ICameraSceneNode.h>
#include "sound.h"
@ -98,9 +99,9 @@ void MobCAO::addToScene(scene::ISceneManager *smgr)
node->setFrameLoop(s,e);
node->setScale(m.model_scale);
setMeshColor(node->getMesh(), video::SColor(255,255,255,255));
bool use_trilinear_filter = g_settings->getBool("trilinear_filter");
bool use_bilinear_filter = g_settings->getBool("bilinear_filter");
bool use_anisotropic_filter = g_settings->getBool("anisotropic_filter");
bool use_trilinear_filter = config_get_bool("client.video.trilinear");
bool use_bilinear_filter = config_get_bool("client.video.bilinear");
bool use_anisotropic_filter = config_get_bool("client.video.anisotropic");
// Set material flags and texture
if (path_get((char*)"texture",const_cast<char*>(m.texture.c_str()),1,buff,1024))
@ -122,9 +123,9 @@ void MobCAO::addToScene(scene::ISceneManager *smgr)
updateNodePos();
}else if (m.texture != "") {
char buff[1024];
bool use_trilinear_filter = g_settings->getBool("trilinear_filter");
bool use_bilinear_filter = g_settings->getBool("bilinear_filter");
bool use_anisotropic_filter = g_settings->getBool("anisotropic_filter");
bool use_trilinear_filter = config_get_bool("client.video.trilinear");
bool use_bilinear_filter = config_get_bool("client.video.bilinear");
bool use_anisotropic_filter = config_get_bool("client.video.anisotropic");
scene::IBillboardSceneNode *bill = smgr->addBillboardSceneNode(NULL, v2f(1, 1), v3f(0,0,0), -1);
if (path_get((char*)"texture",const_cast<char*>(m.texture.c_str()),1,buff,1024))
bill->setMaterialTexture( 0, driver->getTexture(buff));
@ -238,12 +239,8 @@ void MobCAO::step(float dtime, ClientEnvironment *env)
/* Run timers */
m_player_hit_timer -= dtime;
if (m_damage_visual_timer >= 0) {
if (m_damage_visual_timer >= 0)
m_damage_visual_timer -= dtime;
if (m_damage_visual_timer <= 0) {
infostream<<"id="<<m_id<<" damage visual ended"<<std::endl;
}
}
m_walking_unset_timer += dtime;
if (m_walking_unset_timer >= 1.0) {

View File

@ -33,7 +33,6 @@
#include "player.h"
#include "server.h"
#include "mapnode.h" // For content_t
#include "settings.h" // for g_settings
#include <algorithm>
#include <set>

View File

@ -28,7 +28,6 @@
#include "main.h" // For g_settings and g_texturesource
#include "mineral.h"
#include "mapblock_mesh.h" // For MapBlock_LightColor()
#include "settings.h"
#include "environment.h"
#include "nodemetadata.h"
#include "content_nodemeta.h"

View File

@ -23,13 +23,12 @@
* for Voxelands.
************************************************************************/
// For g_settings
#include "common.h"
#include "main.h"
#include "content_mapnode.h"
#include "mapnode.h"
#include "content_nodemeta.h"
#include "settings.h"
#include "content_craftitem.h"
#include "content_toolitem.h"
#include "content_craft.h"
@ -208,7 +207,7 @@ void content_mapnode_init(bool repeat)
{
// Read some settings
#ifndef SERVER
bool opaque_water = g_settings->getBool("opaque_water");
bool opaque_water = config_get_bool("client.graphics.water.opaque");
#endif
content_t i;

View File

@ -25,7 +25,6 @@
#include "content_craft.h"
#include "content_craftitem.h"
#include "content_nodemeta.h"
#include "settings.h"
#include "intl.h"
void content_mapnode_farm(bool repeat)
@ -315,30 +314,18 @@ void content_mapnode_farm(bool repeat)
i = CONTENT_FARM_PUMPKIN_JACK;
f = &content_features(i);
if (g_settings->getBool("enable_supernatural")) {
f->description = gettext("Jack' O Lantern");
f->setAllTextures("farm_pumpkin.png");
f->setTexture(0,"farm_pumpkin_top.png");
f->setTexture(1,"farm_pumpkin_top.png");
f->setTexture(5, "farm_pumpkin_jack.png"); // Z-
f->setInventoryTextureCube("farm_pumpkin_top.png","farm_pumpkin_jack.png","farm_pumpkin.png");
f->draw_type = CDT_NODEBOX;
content_nodebox_jackolantern(f);
f->setInventoryTextureNodeBox(i,"farm_pumpkin_top.png","farm_pumpkin_jack.png","farm_pumpkin.png");
}else{
f->description = gettext("Glass Light");
f->light_propagates = true;
f->sunlight_propagates = true;
f->param_type = CPT_LIGHT;
f->draw_type = CDT_GLASSLIKE;
f->is_ground_content = true;
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
f->setAllTextures("glasslight.png");
f->description = gettext("Glass Light");
f->light_propagates = true;
f->sunlight_propagates = true;
f->param_type = CPT_LIGHT;
f->draw_type = CDT_GLASSLIKE;
f->is_ground_content = true;
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
f->setAllTextures("glasslight.png");
#ifndef SERVER
f->setAllTextureTypes(MATERIAL_ALPHA_BLEND);
f->setAllTextureTypes(MATERIAL_ALPHA_BLEND);
#endif
f->setInventoryTextureCube("glasslight.png", "glasslight.png", "glasslight.png");
}
f->setInventoryTextureCube("glasslight.png", "glasslight.png", "glasslight.png");
f->param2_type = CPT_FACEDIR_SIMPLE;
f->flammable = 1;
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";

View File

@ -27,7 +27,6 @@
#include "content_list.h"
#include "content_craft.h"
#include "content_nodemeta.h"
#include "settings.h"
#include "intl.h"
void content_mapnode_plants(bool repeat)

View File

@ -4,7 +4,6 @@
#include "content_mapnode.h"
#include "mapnode.h"
#include "content_nodemeta.h"
#include "settings.h"
#include "content_craftitem.h"
#include "content_toolitem.h"
#include "content_craft.h"

View File

@ -19,13 +19,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
************************************************************************/
#include "common.h"
#include "serverobject.h"
#include "content_sao.h"
#include "content_mob.h"
#include "content_list.h"
#include "content_craftitem.h"
#include "main.h"
#include "settings.h"
#include "environment.h"
#include "map.h"
#include "profiler.h"
@ -158,11 +158,11 @@ bool content_mob_spawn(ServerEnvironment *env, v3s16 pos, u32 active_object_coun
return false;
v3f p = intToFloat(pos+v3s16(0,1,0), BS);
actionstream<<"A mob of type "<<m.content<<" spawns at "<<PP(floatToInt(p,BS))<<std::endl;
vlprintf(CN_ACTION,"spawning mob (%u) at (%f,%f,%f)",m.content,pos.X,pos.Y+1,pos.Z);
ServerActiveObject *obj = new MobSAO(env, 0, p, m.content);
u16 id = env->addActiveObject(obj);
if (!id) {
actionstream<<"A mob of type "<<m.content<<" didn't spawn at "<<PP(floatToInt(p,BS))<<std::endl;
vlprintf(CN_ACTION,"I lied, it didn't spawn");
return false;
}
@ -179,15 +179,15 @@ void mob_spawn(v3s16 pos, content_t mob, ServerEnvironment *env)
if (m.content == CONTENT_IGNORE)
return;
if (!g_settings->getBool("enable_mob_spawning"))
if (!config_get_bool("world.game.mob.spawn.natural"))
return;
v3f p = intToFloat(pos+v3s16(0,1,0), BS);
actionstream<<"A "<<m.description<<" ("<<m.content<<") mob spawns at "<<PP(floatToInt(p,BS))<<std::endl;
vlprintf(CN_ACTION,"spawning mob (%u) at (%f,%f,%f)",m.content,pos.X,pos.Y+1,pos.Z);
ServerActiveObject *obj = new MobSAO(env, 0, p, m.content);
u16 id = env->addActiveObject(obj);
if (!id) {
actionstream<<"A mob of type "<<m.content<<" didn't spawn at "<<PP(floatToInt(p,BS))<<std::endl;
vlprintf(CN_ACTION,"I lied, it didn't spawn");
return;
}
@ -275,7 +275,7 @@ void mob_spawn_passive(v3s16 pos, bool water, ServerEnvironment *env)
void mob_spawn_hostile(v3s16 pos, bool water, ServerEnvironment *env)
{
std::vector<content_t> can;
u8 level = mobLevelI(g_settings->get("max_mob_level"));
u8 level = mobLevelI(config_get("world.game.mob.spawn.level"));
if (level < MOB_AGGRESSIVE)
return;
for (u16 i=0; i<CONTENT_MOB_COUNT; i++) {

View File

@ -23,6 +23,7 @@
* for Voxelands.
************************************************************************/
#include "common.h"
#include "content_nodemeta.h"
#include "inventory.h"
#include "content_mapnode.h"
@ -31,7 +32,6 @@
#include "log.h"
#include "player.h"
#include "environment.h"
#include "settings.h"
#include "main.h"
#include "mapblock.h"
#include "enchantment.h"
@ -5261,7 +5261,7 @@ bool PistonNodeMetadata::extend(v3s16 pos, v3s16 dir, content_t arm, MapNode pis
{
bool can_extend = false;
v3s16 epos = pos;
s16 max_d = g_settings->getS16("borderstone_radius");
s16 max_d = config_get_int("world.game.borderstone.radius");
for (int i=0; i<17; i++) {
epos += dir;
v3s16 test_p;
@ -5327,7 +5327,7 @@ bool PistonNodeMetadata::contract(v3s16 pos, v3s16 dir, bool sticky, MapNode pis
if (dir.Y == 1)
dropping = true;
if (sticky || dropping) {
s16 max_d = g_settings->getS16("borderstone_radius");
s16 max_d = config_get_int("world.game.borderstone.radius");
v3s16 p_cur = pos+dir;
v3s16 p_next = p_cur+dir;
bool walk = true;

View File

@ -23,11 +23,11 @@
* for Voxelands.
************************************************************************/
#include "common.h"
#include "content_sao.h"
#include "content_mob.h"
#include "collision.h"
#include "environment.h"
#include "settings.h"
#include "profiler.h"
#include "nodemetadata.h"
#include "mapblock.h"
@ -310,10 +310,15 @@ void MobSAO::step(float dtime, bool send_recommended)
f32 dist = m_base_position.getDistanceFrom(playerpos);
if (dist < BS*16) {
if (dist < BS*8 || myrand_range(0,2) == 0) {
actionstream<<"Mob id="<<m_id<<" at "
<<PP(m_base_position/BS)
<<" got randomly disturbed by "
<<player->getName()<<std::endl;
vlprintf(
CN_ACTION,
(char*)"mob (%u) at (%f,%f,%f) was randomly disturbed by %s",
m_id,
m_base_position.X/BS,
m_base_position.Y/BS,
m_base_position.Z/BS,
player->getName()
);
m_disturbing_player = player->getName();
m_disturb_timer = 0;
break;
@ -379,9 +384,6 @@ void MobSAO::step(float dtime, bool send_recommended)
dir.normalize();
v3f speed = dir * BS * 10.0;
v3f pos = m_base_position + shoot_pos;
infostream<<__FUNCTION_NAME<<": Mob id="<<m_id
<<" shooting from "<<PP(pos)
<<" at speed "<<PP(speed)<<std::endl;
ServerActiveObject *obj = new MobSAO(m_env, 0, pos, speed, m.attack_throw_object);
m_env->addActiveObject(obj);
}
@ -1380,9 +1382,16 @@ u16 MobSAO::punch(content_t punch_item, v3f dir, const std::string &playername)
ToolItemFeatures f = content_toolitem_features(punch_item);
u16 wear = 655;
actionstream<<playername<<" punches mob id="<<m_id
<<" with a \""<<f.description<<"\" at "
<<PP(m_base_position/BS)<<std::endl;
vlprintf(
CN_ACTION,
(char*)"%s punches mod (%u) with a '%s' at (%f,%f,%f)",
playername.c_str(),
m_id,
f.description,
m_base_position.X/BS,
m_base_position.Y/BS,
m_base_position.Z/BS
);
if (m.special_dropped_item != CONTENT_IGNORE && (m.special_punch_item == TT_NONE || f.type == m.special_punch_item))
return 0;
@ -1453,7 +1462,7 @@ bool MobSAO::rightClick(Player *player)
return false;
// feed the mob
// after this always return true as inventory has been modified
if (g_settings->getBool("infinite_inventory") == false && ilist) {
if (!config_get_bool((char*)"world.player.inventory.creative") && ilist) {
// Remove from inventory
if (item->getCount() == 1) {
ilist->deleteItem(item_i);
@ -1501,11 +1510,16 @@ void MobSAO::sendPosition()
}
void MobSAO::doDamage(u16 d)
{
infostream<<"Mob hp="<<((int)m_hp)<<" damage="<<((int)d)<<std::endl;
if (d >= m_hp) {
actionstream<<"A "<<mobLevelS(content_mob_features(m_content).level)
<<" mob id="<<m_id<<" dies at "<<PP(m_base_position)<<std::endl;
vlprintf(
CN_ACTION,
(char*)"mob (%u) dies at (%f,%f,%f)",
m_id,
m_base_position.X/BS,
m_base_position.Y/BS,
m_base_position.Z/BS
);
// Die
m_hp = 0;
m_removed = true;

View File

@ -17,15 +17,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
************************************************************************/
#include "common.h"
#define VLCRYPTO_EXPOSE_LIBRARY_FUNCTIONS
#include "crypto.h"
#include <stdlib.h>
#include <string.h>
/* defined in base64.c */
int base64_lencode(const char* source, size_t sourcelen, char *target, size_t targetlen);
size_t base64_ldecode(const char* source, char *target, size_t targetlen);
uint32_t hash(const char *str_param)
{
uint32_t hval = 0;
@ -96,3 +94,20 @@ char* base64_decode(const char* str)
return ret;
}
int sha1(char* str, unsigned char buff[20])
{
unsigned char* digest;
if (!str)
return 1;
digest = bridge_sha1(str);
if (!digest)
return 1;
memcpy(buff,digest,20);
free(digest);
return 0;
}

View File

@ -10,6 +10,13 @@ extern "C" {
uint32_t hash(const char* str);
char* base64_encode(const char* str);
char* base64_decode(const char* str);
int sha1(char* str, unsigned char buff[20]);
#ifdef VLCRYPTO_EXPOSE_LIBRARY_FUNCTIONS
/* defined in base64.c */
int base64_lencode(const char* source, size_t sourcelen, char *target, size_t targetlen);
size_t base64_ldecode(const char* source, char *target, size_t targetlen);
#endif
#ifdef __cplusplus
}

View File

@ -1,226 +0,0 @@
/************************************************************************
* Minetest-c55
* Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
*
* defaultsettings.cpp
* voxelands - 3d voxel world sandbox game
* Copyright (C) Lisa 'darkrose' Milne 2013-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 "settings.h"
#include "defaultsettings.h"
void set_default_settings(Settings *settings)
{
// Client and server
settings->setDefault("port", "");
settings->setDefault("name", "");
settings->setDefault("enable_supernatural","true");
// Client stuff
settings->setDefault("keymap_forward", "KEY_KEY_W");
settings->setDefault("keymap_backward", "KEY_KEY_S");
settings->setDefault("keymap_left", "KEY_KEY_A");
settings->setDefault("keymap_right", "KEY_KEY_D");
settings->setDefault("keymap_jump", "KEY_SPACE");
settings->setDefault("keymap_sneak", "KEY_LSHIFT");
settings->setDefault("keymap_inventory", "KEY_KEY_I");
settings->setDefault("keymap_examine", "KEY_KEY_Q");
settings->setDefault("keymap_use", "KEY_KEY_H");
settings->setDefault("keymap_chat", "KEY_KEY_T");
settings->setDefault("keymap_cmd", "/");
settings->setDefault("keymap_rangeselect", "KEY_KEY_O");
settings->setDefault("keymap_freemove", "KEY_KEY_K");
settings->setDefault("keymap_up", "KEY_KEY_R");
settings->setDefault("keymap_down", "KEY_KEY_F");
settings->setDefault("keymap_run", "KEY_KEY_E");
settings->setDefault("keymap_screenshot", "KEY_F12");
settings->setDefault("keymap_toggle_hud", "KEY_F1");
settings->setDefault("keymap_toggle_chat", "KEY_F2");
settings->setDefault("keymap_toggle_force_fog_off", "KEY_F3");
settings->setDefault("keymap_toggle_update_camera", "KEY_F4");
settings->setDefault("keymap_toggle_debug", "KEY_F5");
settings->setDefault("keymap_toggle_profiler", "KEY_F6");
settings->setDefault("keymap_increase_viewing_range_min", "KEY_PRIOR");
settings->setDefault("keymap_decrease_viewing_range_min", "KEY_NEXT");
settings->setDefault("keymap_select_prev",",");
settings->setDefault("keymap_select_next",".");
// Some (temporary) keys for debugging
settings->setDefault("keymap_print_debug_stacks", "KEY_KEY_P");
// Show debug info by default?
#ifdef NDEBUG
settings->setDefault("show_debug", "false");
#else
settings->setDefault("show_debug", "true");
#endif
settings->setDefault("mouse_sensitivity", "0.2");
settings->setDefault("mainmenu_tab","singleplayer");
settings->setDefault("wanted_fps", "30");
settings->setDefault("fps_max", "60");
settings->setDefault("viewing_range_nodes_max", "300");
settings->setDefault("viewing_range_nodes_min", "15");
settings->setDefault("screenW", "1024");
settings->setDefault("screenH", "600");
settings->setDefault("fullscreen","false");
settings->setDefault("fullscreen_bpp", "24");
settings->setDefault("fsaa", "0");
settings->setDefault("vsync", "false");
settings->setDefault("high_precision_fpu","true");
settings->setDefault("address", "");
settings->setDefault("random_input", "false");
settings->setDefault("client_unload_unused_data_timeout", "600");
settings->setDefault("enable_fog", "true");
settings->setDefault("fov", "72");
settings->setDefault("view_bobbing", "true");
settings->setDefault("new_style_water", "false");
settings->setDefault("new_style_leaves", "true");
settings->setDefault("mesh_detail", "3");
settings->setDefault("texture_detail", "3");
settings->setDefault("light_detail", "3");
settings->setDefault("enable_texture_atlas", "false");
settings->setDefault("data_path", "");
settings->setDefault("video_driver", "opengl");
settings->setDefault("continuous_forward", "false");
settings->setDefault("invert_mouse", "false");
settings->setDefault("enable_clouds", "true");
settings->setDefault("invisible_stone", "false");
settings->setDefault("screenshot_path", ".");
settings->setDefault("view_bobbing_amount", "1.0");
settings->setDefault("enable_3d_clouds", "true");
settings->setDefault("opaque_water", "false");
settings->setDefault("enable_particles", "true");
settings->setDefault("enable_animated_textures", "true");
settings->setDefault("mip_map", "true");
settings->setDefault("anisotropic_filter", "true");
settings->setDefault("bilinear_filter", "false");
settings->setDefault("trilinear_filter", "false");
settings->setDefault("sound_volume", "50");
settings->setDefault("font_size","14");
settings->setDefault("old_hotbar","false");
settings->setDefault("enable_wieldindex","false");
// Server stuff
// "map-dir" doesn't exist by default.
settings->setDefault("motd", "");
settings->setDefault("max_users", "20");
settings->setDefault("strict_protocol_version_checking", "false");
settings->setDefault("disallow_empty_passwords","false");
settings->setDefault("disallow_unknown_users","false");
settings->setDefault("fixed_map_seed", "");
settings->setDefault("default_password", "");
settings->setDefault("default_privs", "build, shout");
settings->setDefault("borderstone_radius","5");
settings->setDefault("enable_footprints","true");
settings->setDefault("game_mode","adventure");
set_adventure_defaults(settings);
settings->setDefault("enable_mob_spawning","true");
// only enable http on the server, singleplayer doesn't need it
#ifndef SERVER
settings->setDefault("enable_http","false");
#else
settings->setDefault("enable_http","true");
#endif
settings->setDefault("profiler_print_interval", "0");
settings->setDefault("enable_mapgen_debug_info", "false");
settings->setDefault("objectdata_interval", "0.2");
settings->setDefault("active_object_send_range_blocks", "3");
settings->setDefault("active_block_range", "2");
//settings->setDefault("max_simultaneous_block_sends_per_client", "1");
// This causes frametime jitter on client side, or does it?
settings->setDefault("max_simultaneous_block_sends_per_client", "4");
settings->setDefault("max_simultaneous_block_sends_server_total", "20");
settings->setDefault("max_block_send_distance", "7");
settings->setDefault("max_block_generate_distance", "5");
settings->setDefault("time_send_interval", "5");
settings->setDefault("time_speed", "96");
settings->setDefault("server_unload_unused_data_timeout", "19");
settings->setDefault("server_map_save_interval", "1.238");
settings->setDefault("full_block_send_enable_min_time_from_building", "2.0");
settings->setDefault("onload_ignore_objects","false");
settings->setDefault("enable_experimental", "false");
settings->setDefault("enable_lavabuckets", "true");
settings->setDefault("enable_tnt", "true");
settings->setDefault("unsafe_fire", "false");
settings->setDefault("api_server", "servers.voxelands.com");
#ifdef SERVER
settings->setDefault("api_announce","true");
#else
settings->setDefault("api_announce","false");
#endif
settings->setDefault("api_auth","true");
settings->setDefault("server_name", "");
settings->setDefault("server_address", "");
}
void set_creative_defaults(Settings *settings)
{
settings->setDefault("infinite_inventory", "true");
settings->setDefault("droppable_inventory", "false");
settings->setDefault("enable_damage", "false");
settings->setDefault("enable_suffocation", "false");
settings->setDefault("enable_hunger", "false");
settings->setDefault("max_mob_level", "passive");
settings->setDefault("initial_inventory", "false");
settings->setDefault("death_drops_inv", "false");
settings->setDefault("tool_wear","false");
}
void set_adventure_defaults(Settings *settings)
{
settings->setDefault("infinite_inventory", "false");
settings->setDefault("droppable_inventory", "true");
settings->setDefault("enable_damage", "true");
settings->setDefault("enable_suffocation", "false");
settings->setDefault("enable_hunger", "false");
settings->setDefault("max_mob_level", "aggressive");
settings->setDefault("initial_inventory", "true");
settings->setDefault("death_drops_inv", "false");
settings->setDefault("tool_wear","true");
}
void set_survival_defaults(Settings *settings)
{
settings->setDefault("infinite_inventory", "false");
settings->setDefault("droppable_inventory", "true");
settings->setDefault("enable_damage", "true");
settings->setDefault("enable_suffocation", "true");
settings->setDefault("enable_hunger", "true");
settings->setDefault("max_mob_level", "destructive");
settings->setDefault("initial_inventory", "false");
settings->setDefault("death_drops_inv", "true");
settings->setDefault("tool_wear","true");
}
void GameSettings::setGameDefaults(std::string mode)
{
if (mode == "creative") {
set_creative_defaults(this);
}else if (mode == "survival") {
set_survival_defaults(this);
}else{
set_adventure_defaults(this);
}
}

View File

@ -1,37 +0,0 @@
/************************************************************************
* Minetest-c55
* Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
*
* defaultsettings.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 DEFAULTSETTINGS_HEADER
#define DEFAULTSETTINGS_HEADER
class Settings;
void set_default_settings(Settings *settings);
void set_creative_defaults(Settings *settings);
void set_adventure_defaults(Settings *settings);
void set_survival_defaults(Settings *settings);
#endif

View File

@ -23,6 +23,8 @@
* for Voxelands.
************************************************************************/
#include "common.h"
#include "environment.h"
#include "porting.h"
#include "collision.h"
@ -34,7 +36,6 @@
#include "content_sao.h"
#include "content_mob.h"
#include "plantgrowth.h"
#include "settings.h"
#include "log.h"
#include "profiler.h"
#include "server.h"
@ -506,75 +507,56 @@ void ServerEnvironment::deSerializePlayers()
void ServerEnvironment::saveMeta()
{
char buff[1024];
if (!path_get((char*)"world",(char*)"env_meta.txt",0,buff,1024))
file_t *f;
f = file_load("world","env_meta.txt");
if (!f)
return;
// Open file and serialize
std::ofstream os(buff, std::ios_base::binary);
if (os.good() == false) {
infostream<<"ServerEnvironment::saveMeta(): Failed to open "
<<buff<<std::endl;
throw SerializationError("Couldn't save env meta");
}
f->len = 0;
f->pos = 0;
Settings args;
args.setU64("game_time", m_game_time);
args.setU64("time_of_day", getTimeOfDay());
args.setU64("world_time",m_time);
args.writeLines(os);
os<<"EnvArgsEnd\n";
file_writef(f,"game_time = %u\n",m_game_time);
file_writef(f,"time_of_day = %u\n",getTimeOfDay());
file_writef(f,"world_time = %u\n",m_time);
file_flush(f);
file_free(f);
}
void ServerEnvironment::loadMeta()
{
file_t *f;
char buff[1024];
if (!path_get((char*)"world",(char*)"env_meta.txt",1,buff,1024))
char* n;
char* v;
f = file_load("world","env_meta.txt");
if (!f)
return;
// Open file and deserialize
std::ifstream is(buff, std::ios_base::binary);
if (is.good() == false) {
infostream<<"ServerEnvironment::loadMeta(): Failed to open "
<<buff<<std::endl;
throw SerializationError("Couldn't load env meta");
while (file_readline(f,buff,1024) > 0) {
n = buff;
v = strchr(n,'=');
if (!v)
continue;
*v = 0;
v++;
n = trim(n);
v = trim(v);
if (!n[0] || !v[0])
continue;
if (!strcmp(n,"game_time")) {
m_game_time = strtoll(v,NULL,10);
}else if (!strcmp(n,"time_of_day")) {
m_time_of_day = strtoll(v,NULL,10);
}else if (!strcmp(n,"world_time")) {
m_time = strtoll(v,NULL,10);
}
}
Settings args;
for(;;)
{
if(is.eof())
throw SerializationError
("ServerEnvironment::loadMeta(): EnvArgsEnd not found");
std::string line;
std::getline(is, line);
std::string trimmedline = trim(line);
if(trimmedline == "EnvArgsEnd")
break;
args.parseConfigLine(line);
}
try{
m_game_time = args.getU64("game_time");
}catch(SettingNotFoundException &e){
// Getting this is crucial, otherwise timestamps are useless
throw SerializationError("Couldn't load env meta game_time");
}
try{
m_time_of_day = args.getU64("time_of_day");
}catch(SettingNotFoundException &e){
// This is not as important
m_time_of_day = 9000;
}
try{
m_time = args.getU64("world_time");
}catch(SettingNotFoundException &e){
// This is not as important
m_time = 0;
}
file_free(f);
}
void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
@ -1040,7 +1022,7 @@ void ServerEnvironment::step(float dtime)
time_diff *= 24000.0;
// Get some settings
bool footprints = g_settings->getBool("enable_footprints");
bool footprints = config_get_bool("world.game.environment.footprints");
/*
Increment game time
@ -1182,7 +1164,7 @@ void ServerEnvironment::step(float dtime)
/*
Update list of active blocks, collecting changes
*/
const s16 active_block_range = g_settings->getS16("active_block_range");
const s16 active_block_range = config_get_int("world.server.chunk.range.active");
std::set<v3s16> blocks_removed;
std::set<v3s16> blocks_added;
m_active_blocks.update(players_blockpos, active_block_range, blocks_removed, blocks_added);
@ -1236,21 +1218,17 @@ void ServerEnvironment::step(float dtime)
if (circuitstep || metastep || nodestep) {
float circuit_dtime = 0.5;
float meta_dtime = 1.0;
bool can_daylight = false;
if (getTimeOfDay() >= 10000 && getTimeOfDay() < 14000)
can_daylight = true;
u16 season = getSeason();
s16 coldzone = 60;
if (season == ENV_SEASON_WINTER)
coldzone = 5;
bool unsafe_fire = g_settings->getBool("unsafe_fire");
bool unsafe_fire = config_get_bool("world.game.environment.fire.spread");
for (std::set<v3s16>::iterator i = m_active_blocks.m_list.begin(); i != m_active_blocks.m_list.end(); i++) {
v3s16 bp = *i;
MapBlock *block = m_map->getBlockNoCreateNoEx(bp);
if (block == NULL)
continue;
bool daylight = can_daylight && !block->getIsUnderground();
std::list<u16> new_list;
for (std::list<u16>::iterator oi = block->m_active_objects.begin(); oi != block->m_active_objects.end(); oi++) {
@ -2050,7 +2028,7 @@ void ServerEnvironment::step(float dtime)
{
if (unsafe_fire) {
if (n.envticks > 2) {
s16 bs_rad = g_settings->getS16("borderstone_radius");
s16 bs_rad = config_get_int("world.game.borderstone.radius");
bs_rad += 2;
// if any node is border stone protected, don't spread
if (!searchNear(p,v3s16(bs_rad,bs_rad,bs_rad),CONTENT_BORDERSTONE,NULL)) {
@ -2094,7 +2072,7 @@ void ServerEnvironment::step(float dtime)
if (!content_features(n_below).flammable) {
m_map->removeNodeWithEvent(p);
}else{
s16 bs_rad = g_settings->getS16("borderstone_radius");
s16 bs_rad = config_get_int("world.game.borderstone.radius");
bs_rad += 2;
// if any node is border stone protected, don't spread
if (!searchNear(p,v3s16(bs_rad,bs_rad,bs_rad),CONTENT_BORDERSTONE,NULL)) {
@ -2131,8 +2109,8 @@ void ServerEnvironment::step(float dtime)
{
NodeMetadata *meta = m_map->getNodeMetadata(p);
if (meta && meta->getEnergy() == ENERGY_MAX) {
if (g_settings->getBool("enable_tnt")) {
s16 bs_rad = g_settings->getS16("borderstone_radius");
if (config_get_bool("world.game.environment.tnt")) {
s16 bs_rad = config_get_int("world.game.borderstone.radius");
bs_rad += 3;
// if any node is border stone protected, don't destroy anything
if (!searchNear(p,v3s16(bs_rad,bs_rad,bs_rad),CONTENT_BORDERSTONE,NULL)) {
@ -2867,27 +2845,6 @@ void ServerEnvironment::step(float dtime)
if (p.Y >= 1024 && n.envticks > 1 && !searchNear(p,v3s16(5,5,5),CONTENT_LIFE_SUPPORT,NULL)) {
n.setContent(CONTENT_VACUUM);
m_map->addNodeWithEvent(p,n);
}else if (
daylight
&& p0.Y > 8
&& g_settings->exists("fix_light_bug")
&& g_settings->getBool("fix_light_bug") == true
&& n.getLightBlend(getDayNightRatio()) < 10
) {
// CHECK AND FIX!
core::map<v3s16, MapBlock*> modified_blocks;
m_map->propagateSunlight(p,modified_blocks);
// Send a MEET_OTHER event
MapEditEvent event;
event.type = MEET_OTHER;
for(core::map<v3s16, MapBlock*>::Iterator
i = modified_blocks.getIterator();
i.atEnd() == false; i++)
{
v3s16 p = i.getNode()->getKey();
event.modified_blocks.insert(p, true);
}
m_map->dispatchEvent(&event);
}
break;
}
@ -2970,7 +2927,7 @@ void ServerEnvironment::step(float dtime)
// This helps the objects to send data at the same time
bool send_recommended = false;
u8 mob_level = mobLevelI(g_settings->get("max_mob_level"));
u8 mob_level = mobLevelI(config_get("world.game.mob.spawn.level"));
m_send_recommended_timer += dtime;
if (m_send_recommended_timer > 0.10) {
m_send_recommended_timer = 0;
@ -3883,7 +3840,7 @@ void ClientEnvironment::step(float dtime)
stepTimeOfDay(dtime);
// Get some settings
bool footprints = g_settings->getBool("enable_footprints");
bool footprints = config_get_bool("world.game.environment.footprints");
// Get local player
LocalPlayer *lplayer = getLocalPlayer();

View File

@ -59,7 +59,7 @@ file_t *file_load(char* type, char* name)
fn = name;
path = path_get(type,name,1,NULL,0);
}else{
path = name;
path = strdup(name);
fn = strrchr(name,'/');
if (!fn)
return NULL;

View File

@ -23,6 +23,8 @@
* for Voxelands.
************************************************************************/
#include "common.h"
#include "game.h"
#include "common_irrlicht.h"
#include <IGUICheckBox.h>
@ -41,7 +43,6 @@
#include "clouds.h"
#include "camera.h"
#include "mapblock.h"
#include "settings.h"
#include "profiler.h"
#include "mainmenumanager.h"
#include "intl.h"
@ -632,14 +633,10 @@ void update_profiler_gui(gui::IGUIStaticText *guitext_profiler,
void the_game(
bool &kill,
bool random_input,
InputHandler *input,
IrrlichtDevice *device,
gui::IGUIFont* font,
std::string playername,
std::string password,
std::string address,
u16 port,
std::wstring &error_message,
ISoundManager *sound
)
@ -668,12 +665,15 @@ void the_game(
SharedPtr will delete it when it goes out of scope.
*/
SharedPtr<Server> server;
if(address == ""){
//draw_load_screen(L"Creating server...", driver, font);
drawLoadingScreen(device,narrow_to_wide(gettext("Creating server...")));
infostream<<"Creating server"<<std::endl;
server = new Server();
server->start(port);
{
char* v = config_get("world.server.address");
if (!v || !v[0]) {
//draw_load_screen(L"Creating server...", driver, font);
drawLoadingScreen(device,narrow_to_wide(gettext("Creating server...")));
infostream<<"Creating server"<<std::endl;
server = new Server();
server->start();
}
}
/*
@ -684,15 +684,20 @@ void the_game(
drawLoadingScreen(device,narrow_to_wide(gettext("Creating client...")));
infostream<<"Creating client"<<std::endl;
MapDrawControl draw_control;
Client client(device, playername.c_str(), password, draw_control, sound);
Client client(device, password, draw_control, sound);
drawLoadingScreen(device,narrow_to_wide(gettext("Resolving address...")));
uint16_t port = config_get_int("world.server.port");
if (!port)
port = 30000;
Address connect_address(0,0,0,0, port);
try{
if(address == "")
char* v = config_get("world.server.address");
if (!v || !v[0]) {
connect_address.setAddress(127,0,0,1);
else
connect_address.Resolve(address.c_str());
}else{
connect_address.Resolve(v);
}
}
catch(ResolveError &e)
{
@ -794,7 +799,7 @@ void the_game(
*/
Clouds *clouds = NULL;
if (g_settings->getBool("enable_clouds"))
if (config_get_bool("client.graphics.clouds"))
clouds = new Clouds(smgr->getRootSceneNode(), smgr, -1, time(0));
/*
@ -868,7 +873,7 @@ void the_game(
float damage_flash_timer = 0;
bool invert_mouse = g_settings->getBool("invert_mouse");
bool invert_mouse = config_get_bool("client.ui.mouse.invert");
bool respawn_menu_active = false;
@ -876,22 +881,25 @@ void the_game(
bool show_chat = true;
bool force_fog_off = false;
bool disable_camera_update = false;
bool show_debug = g_settings->getBool("show_debug");
bool show_debug = config_get_bool("debug.show");
bool show_debug_frametime = false;
u32 show_profiler = 0;
u32 show_profiler_max = 3; // Number of pages
float fps_max = g_settings->getFloat("fps_max");
float profiler_print_interval = g_settings->getFloat("profiler_print_interval");
float fps_max = config_get_float("client.graphics.fps.max");
float profiler_print_interval = config_get_float("debug.profiler.interval");
bool free_move = false;
f32 mouse_sensitivity = g_settings->getFloat("mouse_sensitivity");
f32 mouse_sensitivity = config_get_float("client.ui.mouse.sensitivity");
bool highlight_selected_node = true;
if (g_settings->exists("selected_node") && g_settings->get("selected_node") == "outline")
highlight_selected_node = false;
bool enable_particles = g_settings->getBool("enable_particles");
bool enable_fog = g_settings->getBool("enable_fog");
bool old_hotbar = g_settings->getBool("old_hotbar");
bool show_index = g_settings->getBool("enable_wieldindex");
{
char* v = config_get("client.graphics.selection");
if (v && !strcmp(v,"outline"))
highlight_selected_node = false;
}
bool enable_particles = config_get_bool("client.graphics.particles");
bool enable_fog = config_get_bool("client.graphics.light.fog");
bool old_hotbar = config_get_bool("client.ui.hud.old");
bool show_index = config_get_bool("client.ui.hud.wieldindex");
bool has_selected_node = false;
v3s16 selected_node_pos = v3s16(0,0,0);
@ -1250,22 +1258,21 @@ void the_game(
statustext_time = 0;
}
}else if (input->wasKeyDown(getKeySetting(VLKC_RANGE_PLUS))) {
s16 range = g_settings->getS16("viewing_range_nodes_min");
s16 range_new = range + 10;
g_settings->set("viewing_range_nodes_min", itos(range_new));
char buff[512];
snprintf(buff,512,gettext("Minimum viewing range changed to %d"),range_new);
int range = config_get_int("client.graphics.range.min");
range += 10;
config_set_int("client.graphics.range.min",range);
snprintf(buff,512,gettext("Minimum viewing range changed to %d"),range);
statustext = narrow_to_wide(buff);
statustext_time = 0;
}else if (input->wasKeyDown(getKeySetting(VLKC_RANGE_MINUS))) {
s16 range = g_settings->getS16("viewing_range_nodes_min");
s16 range_new = range - 10;
if (range_new < 0)
range_new = range;
g_settings->set("viewing_range_nodes_min",
itos(range_new));
char buff[512];
snprintf(buff,512,gettext("Minimum viewing range changed to %d"),range_new);
int range = config_get_int("client.graphics.range.min");
range -= 10;
if (range < 10)
range = 10;
config_set_int("client.graphics.range.min",range);
snprintf(buff,512,gettext("Minimum viewing range changed to %d"),range);
statustext = narrow_to_wide(buff);
statustext_time = 0;
}
@ -1359,12 +1366,9 @@ void the_game(
*/
float turn_amount = 0.0;
if ((device->isWindowActive() && noMenuActive()) || random_input) {
if (!random_input) {
// Mac OSX gets upset if this is set every frame
if (device->getCursorControl()->isVisible())
device->getCursorControl()->setVisible(false);
}
if ((device->isWindowActive() && noMenuActive())) {
if (device->getCursorControl()->isVisible())
device->getCursorControl()->setVisible(false);
if (first_loop_after_window_activation) {
//infostream<<"window active, first loop"<<std::endl;
@ -1485,9 +1489,11 @@ void the_game(
damage_flash_timer += 0.05 * event.player_damage.amount;
}
if (g_sound) {
std::string ch = g_settings->get("character_definition");
if (ch == "")
ch = std::string(PLAYER_DEFAULT_CHARDEF);
char* v;
std::string ch = std::string(PLAYER_DEFAULT_CHARDEF);
v = config_get("client.character");
if (v)
ch = v;
Strfnd f(ch);
std::string gender = f.next(":");
std::string snd("player-hurt-");
@ -1751,7 +1757,7 @@ void the_game(
}
if (input->wasKeyDown(getKeySetting(VLKC_EXAMINE)) && !random_input) {
if (input->wasKeyDown(getKeySetting(VLKC_EXAMINE))) {
// If metadata provides an inventory view, activate it
if (meta && meta->getDrawSpecString(client.getLocalPlayer()) != "") {
infostream<<"Launching custom inventory view"<<std::endl;

View File

@ -135,14 +135,10 @@ class ISoundManager;
void the_game(
bool &kill,
bool random_input,
InputHandler *input,
IrrlichtDevice *device,
gui::IGUIFont* font,
std::string playername,
std::string password,
std::string address,
u16 port,
std::wstring &error_message,
ISoundManager *sound
);

View File

@ -23,10 +23,10 @@
* for Voxelands.
************************************************************************/
#include "common.h"
#include "guiMainMenu.h"
#include "settings.h"
#include "main.h"
#include "defaultsettings.h"
#include "guiSettingsMenu.h"
#include "guiMultiplayerMenu.h"
#include "debug.h"
@ -91,208 +91,8 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
{
std::wstring game_mode;
std::wstring max_mob_level;
bool initial_inventory;
bool infinite_inventory;
bool droppable_inventory;
bool death_drops_inventory;
bool enable_damage;
bool suffocation;
bool hunger;
bool tool_wear;
bool unsafe_fire;
bool delete_map;
bool clear_map;
bool use_fixed_seed;
std::wstring fixed_seed;
std::string map_type;
m_screensize = screensize;
// Server options
{
gui::IGUIElement *e = getElementFromId(GUI_ID_GAME_MODE_COMBO);
if (e != NULL && e->getType() == gui::EGUIET_COMBO_BOX) {
gui::IGUIComboBox *c = (gui::IGUIComboBox*)e;
switch (c->getItemData(c->getSelected())) {
case GUI_ID_GAME_MODE_CREATIVE:
game_mode = L"creative";
break;
case GUI_ID_GAME_MODE_ADVENTURE:
game_mode = L"adventure";
break;
case GUI_ID_GAME_MODE_SURVIVAL:
game_mode = L"survival";
break;
default:
game_mode = L"adventure";
}
}else{
game_mode = m_data->game_mode;
}
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_MOBS_COMBO);
if (e != NULL && e->getType() == gui::EGUIET_COMBO_BOX) {
gui::IGUIComboBox *c = (gui::IGUIComboBox*)e;
switch (c->getItemData(c->getSelected())) {
case GUI_ID_MOBS_PASSIVE:
max_mob_level = L"passive";
break;
case GUI_ID_MOBS_AGGRESSIVE:
max_mob_level = L"aggressive";
break;
case GUI_ID_MOBS_DESTRUCTIVE:
max_mob_level = L"destructive";
break;
case GUI_ID_MOBS_NONE:
max_mob_level = L"none";
break;
default:
max_mob_level = L"aggressive";
}
}else{
max_mob_level = m_data->max_mob_level;
}
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_DAMAGE_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
enable_damage = ((gui::IGUICheckBox*)e)->isChecked();
else
enable_damage = m_data->enable_damage;
}
if (enable_damage) {
{
gui::IGUIElement *e = getElementFromId(GUI_ID_SUFFOCATE_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
suffocation = ((gui::IGUICheckBox*)e)->isChecked();
else
suffocation = m_data->suffocation;
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_HUNGER_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
hunger = ((gui::IGUICheckBox*)e)->isChecked();
else
hunger = m_data->hunger;
}
}else{
suffocation = false;
m_data->suffocation = false;
hunger = false;
m_data->hunger = false;
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_INFINITE_INV_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
infinite_inventory = ((gui::IGUICheckBox*)e)->isChecked();
else
infinite_inventory = m_data->infinite_inventory;
}
if (!infinite_inventory) {
gui::IGUIElement *e = getElementFromId(GUI_ID_INITIAL_INV_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
initial_inventory = ((gui::IGUICheckBox*)e)->isChecked();
else
initial_inventory = m_data->initial_inventory;
}else{
initial_inventory = false;
m_data->initial_inventory = false;
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_DROPPABLE_INV_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
droppable_inventory = ((gui::IGUICheckBox*)e)->isChecked();
else
droppable_inventory = m_data->droppable_inventory;
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_LOSE_INV_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
death_drops_inventory = ((gui::IGUICheckBox*)e)->isChecked();
else
death_drops_inventory = m_data->death_drops_inventory;
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_TOOL_WEAR_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
tool_wear = ((gui::IGUICheckBox*)e)->isChecked();
else
tool_wear = m_data->tool_wear;
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_FIRE_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
unsafe_fire = ((gui::IGUICheckBox*)e)->isChecked();
else
unsafe_fire = m_data->unsafe_fire;
}
// Map options
{
gui::IGUIElement *e = getElementFromId(GUI_ID_MAP_DELETE_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
delete_map = ((gui::IGUICheckBox*)e)->isChecked();
else
delete_map = m_data->delete_map;
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_MAP_CLEAR_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
clear_map = ((gui::IGUICheckBox*)e)->isChecked();
else
clear_map = m_data->clear_map;
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_MAP_SEED_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
use_fixed_seed = ((gui::IGUICheckBox*)e)->isChecked();
else
use_fixed_seed = m_data->use_fixed_seed;
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_MAP_SEED_INPUT);
if(e != NULL)
fixed_seed = e->getText();
else
fixed_seed = m_data->fixed_seed;
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_MAP_TYPE_COMBO);
if (e != NULL && e->getType() == gui::EGUIET_COMBO_BOX) {
gui::IGUIComboBox *c = (gui::IGUIComboBox*)e;
switch (c->getItemData(c->getSelected())) {
case GUI_ID_MAP_TYPE_FLAT:
map_type = "flat";
break;
case GUI_ID_MAP_TYPE_FLATTER:
map_type = "flatter";
break;
case GUI_ID_MAP_TYPE_SMOOTHER:
map_type = "smoother";
break;
case GUI_ID_MAP_TYPE_HILLY:
map_type = "hilly";
break;
case GUI_ID_MAP_TYPE_MOUNTAINS:
map_type = "mountains";
break;
case GUI_ID_MAP_TYPE_CRAZY:
map_type = "crazy";
break;
case GUI_ID_MAP_TYPE_CRAZYHILLS:
map_type = "crazyhills";
break;
default:
map_type = "default";
}
}else{
map_type = m_data->map_type;
}
}
/*
Remove stuff
*/
@ -362,17 +162,15 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
/*
Client section
*/
std::string selected_tab = g_settings->get("mainmenu_tab");
if (selected_tab == "multiplayer") {
char* selected_tab = config_get("client.ui.mainmenu.tab");
if (!selected_tab) {
m_data->selected_tab = TAB_SINGLEPLAYER;
}else if (!strcmp(selected_tab,"multiplayer")) {
m_data->selected_tab = TAB_MULTIPLAYER;
}else if (selected_tab == "settings") {
}else if (!strcmp(selected_tab,"settings")) {
m_data->selected_tab = TAB_SETTINGS;
}else if (selected_tab == "credits") {
}else if (!strcmp(selected_tab,"credits")) {
m_data->selected_tab = TAB_CREDITS;
}else if (selected_tab == "singleadvanced") {
m_data->selected_tab = TAB_SINGLEPLAYER_ADVANCED;
}else if (selected_tab == "singlemap") {
m_data->selected_tab = TAB_SINGLEPLAYER_MAP;
}else{
m_data->selected_tab = TAB_SINGLEPLAYER;
}
@ -388,277 +186,12 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
gui::IGUIStaticText *t = Environment->addStaticText(narrow_to_wide(gettext("Single Player")).c_str(), rect, false, true, this, -1);
t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
// Server parameters
{
core::rect<s32> rect(0, 0, 200, 30);
rect += topleft_content + v2s32(175, 60);
gui::IGUIComboBox *c = Environment->addComboBox(rect, this, GUI_ID_GAME_MODE_COMBO);
u32 cm = c->addItem(narrow_to_wide(gettext("Creative Mode")).c_str(),GUI_ID_GAME_MODE_CREATIVE);
u32 am = c->addItem(narrow_to_wide(gettext("Adventure Mode")).c_str(),GUI_ID_GAME_MODE_ADVENTURE);
u32 sm = c->addItem(narrow_to_wide(gettext("Survival Mode")).c_str(),GUI_ID_GAME_MODE_SURVIVAL);
if (game_mode == L"creative") {
c->setSelected(cm);
}else if (game_mode == L"adventure") {
c->setSelected(am);
}else if (game_mode == L"survival") {
c->setSelected(sm);
}
}
// Advanced settings button
{
core::rect<s32> rect(0, 0, 220, 30);
rect += topleft_content + v2s32(50, 100);
Environment->addButton(rect, this, GUI_ID_GAME_SETTINGS_ADV, narrow_to_wide(gettext("Advanced Settings")).c_str());
}
// Map options button
{
core::rect<s32> rect(0, 0, 220, 30);
rect += topleft_content + v2s32(280, 100);
Environment->addButton(rect, this, GUI_ID_MAP_OPTIONS_BUTTON, narrow_to_wide(gettext("Map Options")).c_str());
}
// Start game button
{
core::rect<s32> rect(0, 0, 180, 30);
rect += topleft_content + v2s32(185, 170);
Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON, narrow_to_wide(gettext("Start Game")).c_str());
}
}else if (m_data->selected_tab == TAB_SINGLEPLAYER_ADVANCED) {
{
core::rect<s32> rect(0, 0, 550, 20);
rect += topleft_content + v2s32(0, 20);
gui::IGUIStaticText *t = Environment->addStaticText(narrow_to_wide(gettext("Single Player")).c_str(), rect, false, true, this, -1);
t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
// Server parameters
{
core::rect<s32> rect(0, 0, 200, 30);
rect += topleft_content + v2s32(175, 60);
gui::IGUIComboBox *c = Environment->addComboBox(rect, this, GUI_ID_GAME_MODE_COMBO);
u32 cm = c->addItem(narrow_to_wide(gettext("Creative Mode")).c_str(),GUI_ID_GAME_MODE_CREATIVE);
u32 am = c->addItem(narrow_to_wide(gettext("Adventure Mode")).c_str(),GUI_ID_GAME_MODE_ADVENTURE);
u32 sm = c->addItem(narrow_to_wide(gettext("Survival Mode")).c_str(),GUI_ID_GAME_MODE_SURVIVAL);
if (game_mode == L"creative") {
c->setSelected(cm);
}else if (game_mode == L"adventure") {
c->setSelected(am);
}else if (game_mode == L"survival") {
c->setSelected(sm);
}
}
// Basic settings button
{
core::rect<s32> rect(0, 0, 220, 30);
rect += topleft_content + v2s32(50, 100);
Environment->addButton(rect, this, GUI_ID_GAME_SETTINGS_BASIC, narrow_to_wide(gettext("Hide Advanced Settings")).c_str());
}
// Map options button
{
core::rect<s32> rect(0, 0, 220, 30);
rect += topleft_content + v2s32(280, 100);
Environment->addButton(rect, this, GUI_ID_MAP_OPTIONS_BUTTON, narrow_to_wide(gettext("Map Options")).c_str());
}
{
core::rect<s32> rect(0, 0, 125, 20);
rect += topleft_content + v2s32(40, 160);
gui::IGUIStaticText *t = Environment->addStaticText(narrow_to_wide(gettext("Creatures")).c_str(), rect, false, true, this, -1);
t->setTextAlignment(gui::EGUIA_LOWERRIGHT, gui::EGUIA_UPPERLEFT);
}
{
core::rect<s32> rect(0, 0, 240, 30);
rect += topleft_content + v2s32(170, 155);
gui::IGUIComboBox *c = Environment->addComboBox(rect, this, GUI_ID_MOBS_COMBO);
u32 nm = c->addItem(narrow_to_wide(gettext("None")).c_str(),GUI_ID_MOBS_NONE);
u32 pm = c->addItem(narrow_to_wide(gettext("Passive")).c_str(),GUI_ID_MOBS_PASSIVE);
u32 am = c->addItem(narrow_to_wide(gettext("Passive & Aggressive")).c_str(),GUI_ID_MOBS_AGGRESSIVE);
u32 dm = c->addItem(narrow_to_wide(gettext("Passive, Aggressive, & Destructive")).c_str(),GUI_ID_MOBS_DESTRUCTIVE);
if (max_mob_level == L"passive") {
c->setSelected(pm);
}else if (max_mob_level == L"destructive") {
c->setSelected(dm);
}else if (max_mob_level == L"none") {
c->setSelected(nm);
}else{
c->setSelected(am);
}
}
{
core::rect<s32> rect(0, 0, 200, 30);
rect += topleft_content + v2s32(70, 200);
Environment->addCheckBox(enable_damage, rect, this, GUI_ID_DAMAGE_CB, narrow_to_wide(gettext("Player Damage")).c_str());
}
{
core::rect<s32> rect(0, 0, 200, 30);
rect += topleft_content + v2s32(80, 230);
Environment->addCheckBox(suffocation, rect, this, GUI_ID_SUFFOCATE_CB, narrow_to_wide(gettext("Suffocation/Drowning")).c_str());
}
{
core::rect<s32> rect(0, 0, 200, 30);
rect += topleft_content + v2s32(80, 260);
Environment->addCheckBox(hunger, rect, this, GUI_ID_HUNGER_CB, narrow_to_wide(gettext("Hunger")).c_str());
}
{
core::rect<s32> rect(0, 0, 200, 30);
rect += topleft_content + v2s32(70, 290);
Environment->addCheckBox(tool_wear, rect, this, GUI_ID_TOOL_WEAR_CB, narrow_to_wide(gettext("Tool Wear")).c_str());
}
{
core::rect<s32> rect(0, 0, 200, 30);
rect += topleft_content + v2s32(70, 320);
Environment->addCheckBox(unsafe_fire, rect, this, GUI_ID_FIRE_CB, narrow_to_wide(gettext("Dangerous Fire")).c_str());
}
{
core::rect<s32> rect(0, 0, 200, 30);
rect += topleft_content + v2s32(300, 200);
Environment->addCheckBox(infinite_inventory, rect, this, GUI_ID_INFINITE_INV_CB, narrow_to_wide(gettext("Infinite Inventory")).c_str());
}
{
core::rect<s32> rect(0, 0, 200, 30);
rect += topleft_content + v2s32(310, 230);
Environment->addCheckBox(initial_inventory, rect, this, GUI_ID_INITIAL_INV_CB, narrow_to_wide(gettext("Initial Inventory")).c_str());
}
{
core::rect<s32> rect(0, 0, 200, 30);
rect += topleft_content + v2s32(300, 260);
Environment->addCheckBox(droppable_inventory, rect, this, GUI_ID_DROPPABLE_INV_CB, narrow_to_wide(gettext("Droppable Inventory")).c_str());
}
{
core::rect<s32> rect(0, 0, 200, 30);
rect += topleft_content + v2s32(300, 290);
Environment->addCheckBox(death_drops_inventory, rect, this, GUI_ID_LOSE_INV_CB, narrow_to_wide(gettext("Death drops Inventory")).c_str());
}
// Start game button
{
core::rect<s32> rect(0, 0, 180, 30);
rect += topleft_content + v2s32(185, 370);
Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON, narrow_to_wide(gettext("Start Game")).c_str());
}
}else if (m_data->selected_tab == TAB_SINGLEPLAYER_MAP) {
{
core::rect<s32> rect(0, 0, 550, 20);
rect += topleft_content + v2s32(0, 20);
gui::IGUIStaticText *t = Environment->addStaticText(narrow_to_wide(gettext("Single Player")).c_str(), rect, false, true, this, -1);
t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
// Server parameters
{
core::rect<s32> rect(0, 0, 200, 30);
rect += topleft_content + v2s32(175, 60);
gui::IGUIComboBox *c = Environment->addComboBox(rect, this, GUI_ID_GAME_MODE_COMBO);
u32 cm = c->addItem(narrow_to_wide(gettext("Creative Mode")).c_str(),GUI_ID_GAME_MODE_CREATIVE);
u32 am = c->addItem(narrow_to_wide(gettext("Adventure Mode")).c_str(),GUI_ID_GAME_MODE_ADVENTURE);
u32 sm = c->addItem(narrow_to_wide(gettext("Survival Mode")).c_str(),GUI_ID_GAME_MODE_SURVIVAL);
if (game_mode == L"creative") {
c->setSelected(cm);
}else if (game_mode == L"adventure") {
c->setSelected(am);
}else if (game_mode == L"survival") {
c->setSelected(sm);
}
}
// Advanced settings button
{
core::rect<s32> rect(0, 0, 220, 30);
rect += topleft_content + v2s32(50, 100);
Environment->addButton(rect, this, GUI_ID_GAME_SETTINGS_ADV, narrow_to_wide(gettext("Advanced Settings")).c_str());
}
// Basic settings button
{
core::rect<s32> rect(0, 0, 220, 30);
rect += topleft_content + v2s32(280, 100);
Environment->addButton(rect, this, GUI_ID_GAME_SETTINGS_BASIC, narrow_to_wide(gettext("Hide Map Options")).c_str());
}
{
core::rect<s32> rect(0, 0, 200, 30);
rect += topleft_content + v2s32(150, 130);
Environment->addCheckBox(delete_map, rect, this, GUI_ID_MAP_DELETE_CB, narrow_to_wide(gettext("Create New Map")).c_str());
}
if (delete_map) {
{
core::rect<s32> rect(0, 0, 300, 20);
rect += topleft_content + v2s32(120, 160);
Environment->addStaticText(narrow_to_wide(gettext("Warning! Your old map will be deleted!")).c_str(),
rect, false, true, this, -1);
}
{
core::rect<s32> rect(0, 0, 120, 20);
rect += topleft_content + v2s32(45, 195);
gui::IGUIStaticText *t = Environment->addStaticText(narrow_to_wide(gettext("Map Type")).c_str(), rect, false, true, this, -1);
t->setTextAlignment(gui::EGUIA_LOWERRIGHT, gui::EGUIA_UPPERLEFT);
}
{
core::rect<s32> rect(0, 0, 240, 30);
rect += topleft_content + v2s32(170, 190);
gui::IGUIComboBox *c = Environment->addComboBox(rect, this, GUI_ID_MAP_TYPE_COMBO);
u32 m1 = c->addItem(narrow_to_wide(gettext("Flat")).c_str(),GUI_ID_MAP_TYPE_FLAT);
u32 m2 = c->addItem(narrow_to_wide(gettext("Flatter")).c_str(),GUI_ID_MAP_TYPE_FLATTER);
u32 m3 = c->addItem(narrow_to_wide(gettext("Smoother")).c_str(),GUI_ID_MAP_TYPE_SMOOTHER);
u32 m4 = c->addItem(narrow_to_wide(gettext("Default")).c_str(),GUI_ID_MAP_TYPE_DEFAULT);
u32 m5 = c->addItem(narrow_to_wide(gettext("Hilly")).c_str(),GUI_ID_MAP_TYPE_HILLY);
u32 m6 = c->addItem(narrow_to_wide(gettext("Mountains")).c_str(),GUI_ID_MAP_TYPE_MOUNTAINS);
u32 m7 = c->addItem(narrow_to_wide(gettext("Crazy")).c_str(),GUI_ID_MAP_TYPE_CRAZY);
u32 m8 = c->addItem(narrow_to_wide(gettext("Crazy Hills")).c_str(),GUI_ID_MAP_TYPE_CRAZYHILLS);
if (map_type == "flat") {
c->setSelected(m1);
}else if (map_type == "flatter") {
c->setSelected(m2);
}else if (map_type == "smoother") {
c->setSelected(m3);
}else if (map_type == "hilly") {
c->setSelected(m5);
}else if (map_type == "mountains") {
c->setSelected(m6);
}else if (map_type == "crazy") {
c->setSelected(m7);
}else if (map_type == "crazyhills") {
c->setSelected(m8);
}else{
c->setSelected(m4);
}
}
{
core::rect<s32> rect(0, 0, 200, 30);
rect += topleft_content + v2s32(150, 230);
Environment->addCheckBox(use_fixed_seed, rect, this, GUI_ID_MAP_SEED_CB, narrow_to_wide(gettext("Use Fixed Seed")).c_str());
}
if (use_fixed_seed) {
{
core::rect<s32> rect(0, 0, 120, 20);
rect += topleft_content + v2s32(65, 265);
gui::IGUIStaticText *t = Environment->addStaticText(narrow_to_wide(gettext("Map Seed")).c_str(), rect, false, true, this, -1);
t->setTextAlignment(gui::EGUIA_LOWERRIGHT, gui::EGUIA_UPPERLEFT);
}
{
core::rect<s32> rect(0, 0, 190, 30);
rect += topleft_content + v2s32(190, 260);
#if USE_FREETYPE
new gui::intlGUIEditBox(fixed_seed.c_str(), true, Environment, this, GUI_ID_MAP_SEED_INPUT, rect);
#else
Environment->addEditBox(fixed_seed.c_str(), rect, false, this, GUI_ID_MAP_SEED_INPUT);
#endif
}
}
}else{
{
core::rect<s32> rect(0, 0, 200, 30);
rect += topleft_content + v2s32(150, 160);
Environment->addCheckBox(clear_map, rect, this, GUI_ID_MAP_CLEAR_CB, narrow_to_wide(gettext("Clear Map")).c_str());
}
if (clear_map) {
core::rect<s32> rect(0, 0, 300, 40);
rect += topleft_content + v2s32(120, 190);
Environment->addStaticText(narrow_to_wide(gettext("Warning! This will delete all construction from your map!")).c_str(),
rect, false, true, this, -1);
}
}
// Start game button
{
core::rect<s32> rect(0, 0, 180, 30);
rect += topleft_content + v2s32(185, 310);
Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON, narrow_to_wide(gettext("Start Game")).c_str());
}
}else if(m_data->selected_tab == TAB_CREDITS) {
// CREDITS
{
@ -756,245 +289,6 @@ void GUIMainMenu::acceptInput()
m_data->name = std::wstring(L"singleplayer");
m_data->password = L"";
m_data->address = L"";
std::wstring o_mode = m_data->game_mode;
{
gui::IGUIElement *e = getElementFromId(GUI_ID_GAME_MODE_COMBO);
if (e != NULL && e->getType() == gui::EGUIET_COMBO_BOX) {
gui::IGUIComboBox *c = (gui::IGUIComboBox*)e;
switch (c->getItemData(c->getSelected())) {
case GUI_ID_GAME_MODE_CREATIVE:
m_data->game_mode = L"creative";
break;
case GUI_ID_GAME_MODE_ADVENTURE:
m_data->game_mode = L"adventure";
break;
case GUI_ID_GAME_MODE_SURVIVAL:
m_data->game_mode = L"survival";
break;
default:
m_data->game_mode = L"adventure";
}
}
}
if (m_data->selected_tab == TAB_SINGLEPLAYER_ADVANCED && o_mode != m_data->game_mode) {
GameSettings t_settings;
if (m_data->game_mode == L"creative") {
set_creative_defaults(&t_settings);
}else if (m_data->game_mode == L"survival") {
set_survival_defaults(&t_settings);
}else{
set_adventure_defaults(&t_settings);
}
m_data->max_mob_level = narrow_to_wide(t_settings.get("max_mob_level"));
m_data->initial_inventory = t_settings.getBool("initial_inventory");
m_data->infinite_inventory = t_settings.getBool("infinite_inventory");
m_data->droppable_inventory = t_settings.getBool("droppable_inventory");
m_data->enable_damage = t_settings.getBool("enable_damage");
m_data->suffocation = t_settings.getBool("enable_suffocation");
m_data->hunger = t_settings.getBool("enable_hunger");
m_data->tool_wear = t_settings.getBool("tool_wear");
{
gui::IGUIElement *e = getElementFromId(GUI_ID_DAMAGE_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
((gui::IGUICheckBox*)e)->setChecked(m_data->enable_damage);
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_SUFFOCATE_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
((gui::IGUICheckBox*)e)->setChecked(m_data->suffocation);
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_HUNGER_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
((gui::IGUICheckBox*)e)->setChecked(m_data->hunger);
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_MOBS_COMBO);
if(e != NULL && e->getType() == gui::EGUIET_COMBO_BOX) {
gui::IGUIComboBox *c = (gui::IGUIComboBox*)e;
s32 i;
if (m_data->max_mob_level == L"passive") {
i = c->getIndexForItemData(GUI_ID_MOBS_PASSIVE);
}else if (m_data->max_mob_level == L"destructive") {
i = c->getIndexForItemData(GUI_ID_MOBS_DESTRUCTIVE);
}else{
i = c->getIndexForItemData(GUI_ID_MOBS_AGGRESSIVE);
}
c->setSelected(i);
}
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_INITIAL_INV_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
((gui::IGUICheckBox*)e)->setChecked(m_data->initial_inventory);
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_INFINITE_INV_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
((gui::IGUICheckBox*)e)->setChecked(m_data->infinite_inventory);
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_DROPPABLE_INV_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
((gui::IGUICheckBox*)e)->setChecked(m_data->droppable_inventory);
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_LOSE_INV_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
((gui::IGUICheckBox*)e)->setChecked(m_data->death_drops_inventory);
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_TOOL_WEAR_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
((gui::IGUICheckBox*)e)->setChecked(m_data->tool_wear);
}
}else{
{
gui::IGUIElement *e = getElementFromId(GUI_ID_MOBS_COMBO);
if (e != NULL && e->getType() == gui::EGUIET_COMBO_BOX) {
gui::IGUIComboBox *c = (gui::IGUIComboBox*)e;
switch (c->getItemData(c->getSelected())) {
case GUI_ID_MOBS_PASSIVE:
m_data->max_mob_level = L"passive";
break;
case GUI_ID_MOBS_AGGRESSIVE:
m_data->max_mob_level = L"aggressive";
break;
case GUI_ID_MOBS_DESTRUCTIVE:
m_data->max_mob_level = L"destructive";
break;
default:
m_data->max_mob_level = L"aggressive";
}
}
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_DAMAGE_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
m_data->enable_damage = ((gui::IGUICheckBox*)e)->isChecked();
}
if (m_data->enable_damage) {
{
gui::IGUIElement *e = getElementFromId(GUI_ID_SUFFOCATE_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
m_data->suffocation = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_HUNGER_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
m_data->hunger = ((gui::IGUICheckBox*)e)->isChecked();
}
}else{
{
m_data->suffocation = false;
gui::IGUIElement *e = getElementFromId(GUI_ID_SUFFOCATE_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
((gui::IGUICheckBox*)e)->setChecked(false);
}
{
m_data->hunger = false;
gui::IGUIElement *e = getElementFromId(GUI_ID_HUNGER_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
((gui::IGUICheckBox*)e)->setChecked(false);
}
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_INFINITE_INV_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
m_data->infinite_inventory = ((gui::IGUICheckBox*)e)->isChecked();
}
if (!m_data->infinite_inventory) {
{
gui::IGUIElement *e = getElementFromId(GUI_ID_INITIAL_INV_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
m_data->initial_inventory = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_LOSE_INV_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
m_data->death_drops_inventory = ((gui::IGUICheckBox*)e)->isChecked();
}
}else{
{
m_data->initial_inventory = false;
gui::IGUIElement *e = getElementFromId(GUI_ID_INITIAL_INV_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
((gui::IGUICheckBox*)e)->setChecked(false);
}
{
m_data->death_drops_inventory = false;
gui::IGUIElement *e = getElementFromId(GUI_ID_LOSE_INV_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
((gui::IGUICheckBox*)e)->setChecked(false);
}
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_DROPPABLE_INV_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
m_data->droppable_inventory = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_TOOL_WEAR_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
m_data->tool_wear = ((gui::IGUICheckBox*)e)->isChecked();
}
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_FIRE_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
m_data->unsafe_fire = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_MAP_DELETE_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
m_data->delete_map = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_MAP_CLEAR_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
m_data->clear_map = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_MAP_SEED_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
m_data->use_fixed_seed = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_MAP_SEED_INPUT);
if(e != NULL)
m_data->fixed_seed = e->getText();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_MAP_TYPE_COMBO);
if (e != NULL && e->getType() == gui::EGUIET_COMBO_BOX) {
gui::IGUIComboBox *c = (gui::IGUIComboBox*)e;
switch (c->getItemData(c->getSelected())) {
case GUI_ID_MAP_TYPE_FLAT:
m_data->map_type = "flat";
break;
case GUI_ID_MAP_TYPE_FLATTER:
m_data->map_type = "flatter";
break;
case GUI_ID_MAP_TYPE_SMOOTHER:
m_data->map_type = "smoother";
break;
case GUI_ID_MAP_TYPE_HILLY:
m_data->map_type = "hilly";
break;
case GUI_ID_MAP_TYPE_MOUNTAINS:
m_data->map_type = "mountains";
break;
case GUI_ID_MAP_TYPE_CRAZY:
m_data->map_type = "crazy";
break;
case GUI_ID_MAP_TYPE_CRAZYHILLS:
m_data->map_type = "crazyhills";
break;
default:
m_data->map_type = "default";
}
}
}
m_accepted = true;
}
@ -1025,27 +319,6 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
return true;
}
}
if (event.GUIEvent.EventType==gui::EGET_CHECKBOX_CHANGED) {
switch (event.GUIEvent.Caller->getID()) {
case GUI_ID_SUFFOCATE_CB:
case GUI_ID_HUNGER_CB:
case GUI_ID_INITIAL_INV_CB:
case GUI_ID_DROPPABLE_INV_CB:
case GUI_ID_TOOL_WEAR_CB:
acceptInput();
m_accepted = false;
break;
case GUI_ID_INFINITE_INV_CB:
case GUI_ID_MAP_DELETE_CB: // Delete map
case GUI_ID_MAP_CLEAR_CB:
case GUI_ID_MAP_SEED_CB:
case GUI_ID_DAMAGE_CB:
acceptInput();
m_accepted = false;
regenerateGui(m_screensize);
break;
}
}
if (event.GUIEvent.EventType==gui::EGET_BUTTON_CLICKED) {
switch (event.GUIEvent.Caller->getID()) {
case GUI_ID_JOIN_GAME_BUTTON: // Start game
@ -1060,29 +333,12 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
quitMenu();
return true;
}
case GUI_ID_GAME_SETTINGS_BASIC:
case GUI_ID_TAB_SINGLEPLAYER:
if (m_data->selected_tab == TAB_SETTINGS)
acceptInput();
m_accepted = false;
m_data->selected_tab = TAB_SINGLEPLAYER;
g_settings->set("mainmenu_tab","singleplayer");
regenerateGui(m_screensize);
return true;
case GUI_ID_GAME_SETTINGS_ADV:
if (m_data->selected_tab == TAB_SETTINGS)
acceptInput();
m_accepted = false;
m_data->selected_tab = TAB_SINGLEPLAYER_ADVANCED;
g_settings->set("mainmenu_tab","singleadvanced");
regenerateGui(m_screensize);
return true;
case GUI_ID_MAP_OPTIONS_BUTTON:
if (m_data->selected_tab == TAB_SETTINGS)
acceptInput();
m_accepted = false;
m_data->selected_tab = TAB_SINGLEPLAYER_MAP;
g_settings->set("mainmenu_tab","singlemap");
config_set("client.ui.mainmenu.tab","singleplayer");
regenerateGui(m_screensize);
return true;
case GUI_ID_TAB_MULTIPLAYER:
@ -1092,7 +348,7 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
GUIMultiplayerMenu *mmenu = new GUIMultiplayerMenu(env, parent, -1,m_data,menumgr,m_gamecallback);
mmenu->drop();
m_data->selected_tab = TAB_MULTIPLAYER;
g_settings->set("mainmenu_tab","multiplayer");
config_set("client.ui.mainmenu.tab","multiplayer");
return true;
}
case GUI_ID_TAB_SETTINGS:
@ -1106,7 +362,6 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
acceptInput();
m_accepted = false;
m_data->selected_tab = TAB_CREDITS;
g_settings->set("mainmenu_tab","credits");
regenerateGui(m_screensize);
return true;
case GUI_ID_TAB_QUIT:
@ -1115,19 +370,6 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
return true;
}
}
if (event.GUIEvent.EventType == gui::EGET_COMBO_BOX_CHANGED) {
switch (event.GUIEvent.Caller->getID()) {
case GUI_ID_GAME_MODE_COMBO:
acceptInput();
m_accepted = false;
regenerateGui(m_screensize);
return true;
case GUI_ID_MOBS_COMBO:
acceptInput();
m_accepted = false;
return true;
}
}
if (event.GUIEvent.EventType==gui::EGET_EDITBOX_ENTER) {
switch (event.GUIEvent.Caller->getID()) {
case GUI_ID_ADDRESS_INPUT:

View File

@ -35,42 +35,8 @@
enum {
GUI_ID_QUIT_BUTTON = 101,
GUI_ID_GAME_MODE_COMBO,
GUI_ID_GAME_MODE_CREATIVE,
GUI_ID_GAME_MODE_ADVENTURE,
GUI_ID_GAME_MODE_SURVIVAL,
GUI_ID_GAME_SETTINGS_ADV,
GUI_ID_GAME_SETTINGS_BASIC,
GUI_ID_MOBS_COMBO,
GUI_ID_MOBS_NONE,
GUI_ID_MOBS_PASSIVE,
GUI_ID_MOBS_AGGRESSIVE,
GUI_ID_MOBS_DESTRUCTIVE,
GUI_ID_INITIAL_INV_CB,
GUI_ID_INFINITE_INV_CB,
GUI_ID_DROPPABLE_INV_CB,
GUI_ID_LOSE_INV_CB,
GUI_ID_DAMAGE_CB,
GUI_ID_TOOL_WEAR_CB,
GUI_ID_FIRE_CB,
GUI_ID_SUFFOCATE_CB,
GUI_ID_HUNGER_CB,
GUI_ID_JOIN_GAME_BUTTON,
GUI_ID_CHANGE_KEYS_BUTTON,
GUI_ID_MAP_OPTIONS_BUTTON,
GUI_ID_MAP_DELETE_CB,
GUI_ID_MAP_CLEAR_CB,
GUI_ID_MAP_SEED_CB,
GUI_ID_MAP_SEED_INPUT,
GUI_ID_MAP_TYPE_COMBO,
GUI_ID_MAP_TYPE_FLAT,
GUI_ID_MAP_TYPE_FLATTER,
GUI_ID_MAP_TYPE_SMOOTHER,
GUI_ID_MAP_TYPE_DEFAULT,
GUI_ID_MAP_TYPE_HILLY,
GUI_ID_MAP_TYPE_MOUNTAINS,
GUI_ID_MAP_TYPE_CRAZY,
GUI_ID_MAP_TYPE_CRAZYHILLS,
GUI_ID_CHARACTER_CREATOR,
GUI_ID_TAB_SINGLEPLAYER,
GUI_ID_TAB_MULTIPLAYER,
@ -81,8 +47,6 @@ enum {
enum {
TAB_SINGLEPLAYER=0,
TAB_SINGLEPLAYER_ADVANCED,
TAB_SINGLEPLAYER_MAP,
TAB_MULTIPLAYER,
TAB_SETTINGS,
TAB_CREDITS

View File

@ -32,7 +32,6 @@
#include <IGUIListBox.h>
#include <IGUIFont.h>
#include <IGUIScrollBar.h>
#include "settings.h"
#include "gui_colours.h"
#include "http.h"

View File

@ -25,6 +25,8 @@
* for Voxelands.
************************************************************************/
#include "common.h"
#include "guiSettingsMenu.h"
#include "debug.h"
#include "serialization.h"
@ -37,7 +39,6 @@
#include <IGUIFont.h>
#include <IGUIScrollBar.h>
#include <IGUIComboBox.h>
#include "settings.h"
#include "gui_colours.h"
GUISettingsMenu::GUISettingsMenu(
@ -54,19 +55,19 @@ GUISettingsMenu::GUISettingsMenu(
{
activeKey = -1;
init_keys();
m_data.mesh_detail = g_settings->getU16("mesh_detail");
m_data.texture_detail = g_settings->getU16("texture_detail");
m_data.light_detail = g_settings->getU16("light_detail");
m_data.fullscreen = g_settings->getBool("fullscreen");
m_data.particles = g_settings->getBool("enable_particles");
m_data.mip_map = g_settings->getBool("mip_map");
m_data.anisotropic_filter = g_settings->getBool("anisotropic_filter");
m_data.bilinear_filter = g_settings->getBool("bilinear_filter");
m_data.trilinear_filter = g_settings->getBool("trilinear_filter");
m_data.hotbar = g_settings->getBool("old_hotbar");
m_data.wield_index = g_settings->getBool("enable_wieldindex");
m_data.volume = g_settings->getFloat("sound_volume");
m_data.texture_animation = g_settings->getBool("enable_animated_textures");
m_data.mesh_detail = config_get_int("client.graphics.mesh.lod");
m_data.texture_detail = config_get_int("client.graphics.texture.lod");
m_data.light_detail = config_get_int("client.graphics.light.lod");
m_data.fullscreen = config_get_bool("client.video.fullscreen");
m_data.particles = config_get_bool("client.graphics.particles");
m_data.mip_map = config_get_bool("client.video.mipmaps");
m_data.anisotropic_filter = config_get_bool("client.video.anisotropic");
m_data.bilinear_filter = config_get_bool("client.video.bilinear");
m_data.trilinear_filter = config_get_bool("client.video.trilinear");
m_data.hotbar = config_get_bool("client.ui.hud.old");
m_data.wield_index = config_get_bool("client.ui.hud.wieldindex");
m_data.volume = config_get_float("client.sound.volume");
m_data.texture_animation = config_get_bool("client.graphics.texture.animations");
keynames[VLKC_FORWARD] = narrow_to_wide(gettext("Forward"));
keynames[VLKC_BACKWARD] = narrow_to_wide(gettext("Backward"));
@ -122,23 +123,21 @@ void GUISettingsMenu::save()
for (int i=0; i<m; i++) {
saveKeySetting(keys[i],(KeyCode)i);
}
// graphics
g_settings->set("mesh_detail", itos(m_data.mesh_detail));
g_settings->set("texture_detail", itos(m_data.texture_detail));
g_settings->set("light_detail", itos(m_data.light_detail));
g_settings->set("old_hotbar", itos(m_data.hotbar));
g_settings->set("enable_wieldindex", itos(m_data.wield_index));
g_settings->set("enable_animated_textures", itos(m_data.texture_animation));
// video
g_settings->set("mip_map", itos(m_data.mip_map));
g_settings->set("anisotropic_filter", itos(m_data.anisotropic_filter));
g_settings->set("bilinear_filter", itos(m_data.bilinear_filter));
g_settings->set("trilinear_filter", itos(m_data.trilinear_filter));
g_settings->set("fullscreen", itos(m_data.fullscreen));
g_settings->set("enable_particles", itos(m_data.particles));
config_set_int("client.graphics.mesh.lod",m_data.mesh_detail);
config_set_int("client.graphics.texture.lod",m_data.texture_detail);
config_set_int("client.graphics.light.lod",m_data.light_detail);
config_set_int("client.video.fullscreen",m_data.fullscreen);
config_set_int("client.graphics.particles",m_data.particles);
config_set_int("client.video.mipmaps",m_data.mip_map);
config_set_int("client.video.anisotropic",m_data.anisotropic_filter);
config_set_int("client.video.bilinear",m_data.bilinear_filter);
config_set_int("client.video.trilinear",m_data.trilinear_filter);
config_set_int("client.ui.hud.old",m_data.hotbar);
config_set_int("client.ui.hud.wieldindex",m_data.wield_index);
config_set_float("client.sound.volume",m_data.volume);
config_set_int("client.graphics.texture.animations",m_data.texture_animation);
Environment->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, m_data.mip_map);
// sound
g_settings->set("sound_volume",ftos(m_data.volume));
}
void GUISettingsMenu::regenerateGui(v2u32 screensize)

View File

@ -19,10 +19,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
************************************************************************/
#include "common.h"
#include "socket.h"
#include "http.h"
#include "main.h"
#include "settings.h"
#include "debug.h"
#include <stdio.h>
#include <iostream>
@ -108,12 +109,16 @@ HTTPServer::~HTTPServer()
}
/* start the server running */
void HTTPServer::start(u16 port)
void HTTPServer::start()
{
DSTACK(__FUNCTION_NAME);
// Stop thread if already running
m_thread.stop();
uint16_t port = config_get_int("world.server.port");
if (!port)
port = 30000;
m_socket = new TCPSocket();
m_socket->setTimeoutMs(30);
m_socket->Bind(port);
@ -288,54 +293,90 @@ int HTTPRemoteClient::handleMap()
/* handle /api/xxx url's */
int HTTPRemoteClient::handleAPI()
{
char* v;
std::string u1 = m_recv_headers.getUrl(1);
if (u1 == "summary" || u1 == "") {
std::string txt(VERSION_STRING);
txt += "\n";
std::string n = g_settings->get("server_name");
if (n == "")
n = g_settings->get("server_address");
txt += n+"\n";
txt += g_settings->get("motd")+"\n";
txt += g_settings->get("server_address")+"\n";
txt += g_settings->get("port")+"\n";
txt += g_settings->get("game_mode")+"\n";
if (g_settings->get("default_password") == "") {
txt += "public\n";
}else{
v = config_get("world.server.name");
if (!v || !v[0])
v = "Voxelands Server";
txt += v;
txt += "\n";
v = config_get("world.game.motd");
if (!v)
v = "";
txt += v;
txt += "\n";
v = config_get("world.server.address");
if (!v)
v = "127.0.0.1";
txt += v;
txt += "\n";
v = config_get("world.server.port");
if (!v)
v = "";
txt += v;
txt += "\n";
v = config_get("world.game.mode");
if (!v)
v = "";
txt += v;
txt += "\n";
v = config_get("world.server.client.default.password");
if (v || config_get_bool("world.server.client.private")) {
txt += "private\n";
}else{
txt += "public\n";
}
txt += g_settings->get("default_privs")+"\n";
v = config_get("world.server.client.default.privs");
if (!v)
v = "";
txt += v;
txt += "\n";
txt += "summary,motd,mode,name,players,public,version,privs,features";
send((char*)txt.c_str());
return 1;
}else if (u1 == "motd") {
std::string txt = g_settings->get("motd");
send((char*)txt.c_str());
v = config_get("world.game.motd");
if (!v)
v = "";
send(v);
return 1;
}else if (u1 == "mode") {
std::string txt = g_settings->get("game_mode");
send((char*)txt.c_str());
v = config_get("world.game.mode");
if (!v)
v = "";
send(v);
return 1;
}else if (u1 == "name") {
std::string txt = g_settings->get("server_name");
if (txt == "")
txt = g_settings->get("server_address");
send((char*)txt.c_str());
v = config_get("world.server.name");
if (!v || !v[0])
v = "Voxelands Server";
send(v);
return 1;
}else if (u1 == "features") {
std::string txt = "summary,motd,mode,name,players,public,version,privs,features";
send((char*)txt.c_str());
v = "summary,motd,mode,name,players,public,version,privs,features";
send(v);
return 1;
}else if (u1 == "version") {
std::string txt = VERSION_STRING;
send((char*)txt.c_str());
send(VERSION_STRING);
return 1;
}else if (u1 == "privs") {
std::string txt = g_settings->get("default_privs");
send((char*)txt.c_str());
v = config_get("world.server.client.default.privs");
if (!v)
v = "";
send(v);
return 1;
}else if (u1 == "players") {
array_t *players = m_server->getGameServer()->getPlayers(true);
@ -355,25 +396,30 @@ int HTTPRemoteClient::handleAPI()
send((char*)txt.c_str());
return 1;
}else if (u1 == "public") {
if (g_settings->get("default_password") == "") {
send((char*)"public");
v = config_get("world.server.client.default.password");
if (v || config_get_bool("world.server.client.private")) {
send("private");
}else{
send((char*)"private");
send("public");
}
return 1;
}
setResponse("404 Not Found");
send((char*)"404 Not Found");
send("404 Not Found");
return 1;
}
/* handle / url's */
int HTTPRemoteClient::handleIndex()
{
char* v;
int c = 0;
std::string html("<div class=\"panel\"><h2>");
html += g_settings->get("motd");
v = config_get("world.game.motd");
if (v)
html += v;
html += "</h2><p><strong>Version: </strong>";
html += VERSION_STRING;
html += "<br /><strong><a href=\"/player\" class=\"secret\">Players</a>: </strong>";
@ -538,10 +584,9 @@ std::string http_request(char* host, char* url, char* post, int port)
addr.setPort(port);
if (!host || !host[0]) {
h = g_settings->get("api_server");
if (h == "")
host = config_get("global.api.announce");
if (!host || !host[0])
return "";
host = (char*)h.c_str();
}
addr.Resolve(host);

View File

@ -143,7 +143,7 @@ class HTTPServer
public:
HTTPServer(Server &server);
~HTTPServer();
void start(u16 port);
void start();
void stop();
void step();
std::string getPlayerPrivs(std::string name) {

View File

@ -23,13 +23,15 @@
* for Voxelands.
************************************************************************/
#include "common.h"
#include "keycode.h"
#include "main.h" // For g_settings
#include "exceptions.h"
#include "settings.h"
#include "hex.h"
#include "intl.h"
#include <map>
#include "utility.h"
class UnknownKeycode : public BaseException
{
@ -223,7 +225,7 @@ static const char *KeyNames[] =
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
"-", "-", "-", "-", "-", "-", "-", "-", "KEY_ATTN", "KEY_CRSEL", "KEY_EXSEL",
"KEY_EREOF", "KEY_PLAY", "KEY_ZOOM", "KEY_PA1", "KEY_OEM_CLEAR", "-" };
static const char *KeyNamesLang[255];
void init_KeyNamesLang()
@ -376,8 +378,8 @@ KeyPress::KeyPress(const char *name)
Key = keyname_to_keycode(name);
m_name = name;
if (strlen(name) > 8 && strncmp(name, "KEY_KEY_", 8) == 0) {
int chars_read = mbtowc(&Char, name + 8, 1);
assert (chars_read == 1 && "unexpected multibyte character");
if (mbtowc(&Char, name + 8, 1) != 1)
Char = L'\0';
} else
Char = L'\0';
return;
@ -388,8 +390,8 @@ KeyPress::KeyPress(const char *name)
m_name += name;
try {
Key = keyname_to_keycode(m_name.c_str());
int chars_read = mbtowc(&Char, name, 1);
assert (chars_read == 1 && "unexpected multibyte character");
if (mbtowc(&Char, name, 1) != 1)
Char = L'\0';
return;
} catch (UnknownKeycode &e) {};
}
@ -398,8 +400,8 @@ KeyPress::KeyPress(const char *name)
Key = irr::KEY_KEY_CODES_COUNT;
int mbtowc_ret = mbtowc(&Char, name, 1);
assert (mbtowc_ret == 1 && "unexpected multibyte character");
if (mbtowc(&Char, name, 1) != 1)
Char = L'\0';
m_name = name[0];
}
@ -411,8 +413,7 @@ KeyPress::KeyPress(const irr::SEvent::SKeyInput &in, bool prefer_character)
if(prefer_character){
m_name.resize(MB_CUR_MAX+1, '\0');
int written = wctomb(&m_name[0], Char);
if(written > 0){
infostream<<"KeyPress: Preferring character for "<<m_name<<std::endl;
if (written > 0) {
Key = irr::KEY_KEY_CODES_COUNT;
return;
}
@ -423,10 +424,8 @@ KeyPress::KeyPress(const irr::SEvent::SKeyInput &in, bool prefer_character)
} else {
m_name.resize(MB_CUR_MAX+1, '\0');
int written = wctomb(&m_name[0], Char);
if(written < 0){
if (written < 0)
std::string hexstr = hex_encode((const char*)&Char, sizeof(Char));
errorstream<<"KeyPress: Unexpected multibyte character "<<hexstr<<std::endl;
}
}
}
@ -503,12 +502,17 @@ static bool key_setting_cache_init = false;
KeyPress getKeySetting(KeyCode code)
{
char* v;
if (!key_setting_cache_init)
clearKeyCache();
if (g_key_setting_cache[code])
return *g_key_setting_cache[code];
g_key_setting_cache[code] = new KeyPress(g_settings->get(keymap_strings[code]).c_str());
v = config_get((char*)keymap_strings[code]);
if (!v)
v = "";
g_key_setting_cache[code] = new KeyPress(v);
return *g_key_setting_cache[code];
}
@ -519,7 +523,8 @@ void saveKeySetting(KeyPress &key, KeyCode code)
clearKeyCache();
*g_key_setting_cache[code] = key;
g_settings->set(keymap_strings[code],key.sym());
config_set((char*)keymap_strings[code],(char*)key.sym());
}
void clearKeyCache()

212
src/log.c Normal file
View File

@ -0,0 +1,212 @@
/************************************************************************
* log.c
* voxelands - 3d voxel world sandbox game
* Copyright (C) Lisa 'darkrose' Milne 2016 <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/>
************************************************************************/
#include "common.h"
#include "path.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
static struct {
int min_level;
int max_level;
int system_min_level;
int system_max_level;
int console_min_level;
int console_max_level;
char* logfile;
char* levels[7];
} logdata = {
1,
5,
4,
5,
4,
5,
NULL,
{"none","error","warn","action","chat","info","debug"}
};
static void level_setter(char* v, int *l, int d)
{
int i;
if (v) {
for (i=0; i<7; i++) {
if (!strcmp(logdata.levels[i],v)) {
*l = i;
return;
}
}
}
*l = d;
}
/* config setters */
int log_minlevel_setter(char* v)
{
level_setter(v,&logdata.min_level,1);
return 0;
}
int log_maxlevel_setter(char* v)
{
level_setter(v,&logdata.max_level,5);
return 0;
}
int log_sminlevel_setter(char* v)
{
level_setter(v,&logdata.system_min_level,4);
return 0;
}
int log_smaxlevel_setter(char* v)
{
level_setter(v,&logdata.system_max_level,5);
return 0;
}
int log_cminlevel_setter(char* v)
{
level_setter(v,&logdata.console_min_level,4);
return 0;
}
int log_cmaxlevel_setter(char* v)
{
level_setter(v,&logdata.console_max_level,5);
return 0;
}
int log_file_setter(char* v)
{
if (logdata.logfile)
free(logdata.logfile);
logdata.logfile = NULL;
if (!v)
return 0;
logdata.logfile = path_get(NULL,v,0,NULL,0);
return 0;
}
/* print text to game and system consoles */
void vlprint(uint8_t type, char* str)
{
char buff[1024];
char* b = buff;
int s = 1024;
if (!str)
return;
/* if it's not logged, don't process it */
if (
!type
|| (
(type < logdata.min_level || type > logdata.max_level)
&& (type < logdata.system_min_level || type > logdata.system_max_level)
&& (type < logdata.console_min_level || type > logdata.console_max_level)
)
)
return;
switch (type) {
case 1:
strcpy(buff,"ERROR: ");
b += 7;
s -= 7;
break;
case 2:
strcpy(buff,"WARNING: ");
b += 9;
s -= 9;
break;
case 3:
strcpy(buff,"ACTION: ");
b += 8;
s -= 8;
break;
case 4:
strcpy(buff,"CHAT: ");
b += 6;
s -= 6;
break;
case 6:
strcpy(buff,"DEBUG: ");
b += 7;
s -= 7;
break;
default:;
}
if (snprintf(b,s,"%s",str) >= s)
return;
/* TODO: log to system console */
if (type >= logdata.system_min_level && type <= logdata.system_max_level)
printf("%s\n",buff);
/*sys_console_print(buff,1);*/
/* TODO: log to game console */
/*if (type >= logdata.console_min_level && type <= logdata.console_max_level)
console_put(buff);*/
if (type < logdata.min_level || type > logdata.max_level)
return;
if (logdata.logfile) {
/* the only time raw file calls are used, for speed */
FILE *f = fopen(logdata.logfile,"a");
if (!f)
return;
fputs(buff,f);
fclose(f);
}
}
/* print formatted text to game and system consoles */
void vlprintf(uint8_t type, char* fmt,...)
{
char buff[1024];
va_list ap;
if (!fmt)
return;
/* if it's not logged, don't process it */
if (
!type
|| (
(type < logdata.min_level || type > logdata.max_level)
&& (type < logdata.system_min_level || type > logdata.system_max_level)
&& (type < logdata.console_min_level || type > logdata.console_max_level)
)
)
return;
va_start(ap, fmt);
if (vsnprintf(buff, 1024, fmt, ap) >= 1024) {
va_end(ap);
return;
}
va_end(ap);
vlprint(type,buff);
}

View File

@ -23,6 +23,8 @@
* for Voxelands.
************************************************************************/
#include "common.h"
#ifdef NDEBUG
// Disable unit tests
#define ENABLE_TESTS 0
@ -61,9 +63,7 @@
#include "game.h"
#include "keycode.h"
#include "tile.h"
#include "defaultsettings.h"
#include "intl.h"
#include "settings.h"
#include "profiler.h"
#include "log.h"
// for the init functions
@ -83,13 +83,6 @@
// This makes textures
ITextureSource *g_texturesource = NULL;
/*
Settings.
These are loaded from the config file.
*/
GameSettings main_settings;
GameSettings *g_settings = &main_settings;
// Global profiler
Profiler main_profiler;
Profiler *g_profiler = &main_profiler;
@ -769,60 +762,11 @@ int main(int argc, char *argv[])
log_register_thread("main");
/*
Parse command line
*/
// List all allowed options
core::map<std::string, ValueSpec> allowed_options;
allowed_options.insert("help", ValueSpec(VALUETYPE_FLAG));
allowed_options.insert("server", ValueSpec(VALUETYPE_FLAG,
"Run server directly"));
allowed_options.insert("config", ValueSpec(VALUETYPE_STRING,
"Load configuration from specified file"));
allowed_options.insert("port", ValueSpec(VALUETYPE_STRING));
allowed_options.insert("address", ValueSpec(VALUETYPE_STRING));
allowed_options.insert("random-input", ValueSpec(VALUETYPE_FLAG));
allowed_options.insert("disable-unittests", ValueSpec(VALUETYPE_FLAG));
allowed_options.insert("enable-unittests", ValueSpec(VALUETYPE_FLAG));
allowed_options.insert("map-dir", ValueSpec(VALUETYPE_STRING));
#ifdef _WIN32
allowed_options.insert("dstream-on-stderr", ValueSpec(VALUETYPE_FLAG));
#endif
allowed_options.insert("speedtests", ValueSpec(VALUETYPE_FLAG));
allowed_options.insert("info-on-stderr", ValueSpec(VALUETYPE_FLAG));
Settings cmd_args;
bool ret = cmd_args.parseCommandLine(argc, argv, allowed_options);
if (ret == false || cmd_args.getFlag("help")) {
dstream<<"Allowed options:"<<std::endl;
for (core::map<std::string, ValueSpec>::Iterator i = allowed_options.getIterator(); i.atEnd() == false; i++) {
dstream<<" --"<<i.getNode()->getKey();
if(i.getNode()->getValue().type != VALUETYPE_FLAG)
dstream<<" <value>";
dstream<<std::endl;
if (i.getNode()->getValue().help != NULL)
dstream<<" "<<i.getNode()->getValue().help<<std::endl;
}
return cmd_args.getFlag("help") ? 0 : 1;
}
/*
Low-level initialization
*/
bool disable_stderr = false;
#ifdef _WIN32
if (cmd_args.getFlag("dstream-on-stderr") == false)
disable_stderr = true;
#endif
if (cmd_args.getFlag("info-on-stderr"))
log_add_output(&main_stderr_log_out, LMT_INFO);
porting::signal_handler_init();
bool &kill = *porting::signal_handler_killstatus();
@ -830,6 +774,8 @@ int main(int argc, char *argv[])
thread_init();
path_init();
intl_init();
command_init();
config_init(argc,argv);
// Initialize debug streams
{
@ -855,27 +801,10 @@ int main(int argc, char *argv[])
<<", "<<BUILD_INFO
<<std::endl;
/*
Basic initialization
*/
// Initialize default settings
set_default_settings(g_settings);
// Initialize sockets
sockets_init();
atexit(sockets_cleanup);
/*
Read config file
*/
{
char buff[1024];
if (path_get((char*)"config",(char*)"voxelands.conf",0,buff,1024))
g_settings->readConfigFile(buff);
}
// Initialize random seed
srand(time(0));
mysrand(time(0));
@ -899,42 +828,15 @@ int main(int argc, char *argv[])
ISoundManager *sound = NULL;
/*
Run unit tests
*/
if (
(ENABLE_TESTS && cmd_args.getFlag("disable-unittests") == false)
|| cmd_args.getFlag("enable-unittests") == true
)
run_tests();
/*for(s16 y=-100; y<100; y++)
for(s16 x=-100; x<100; x++)
{
std::cout<<noise2d_gradient((double)x/10,(double)y/10, 32415)<<std::endl;
}
return 0;*/
/*
Game parameters
*/
// Port
u16 port = 30000;
if (cmd_args.exists("port")) {
port = cmd_args.getU16("port");
}else if (g_settings->exists("port")) {
port = g_settings->getU16("port");
}
if (port == 0)
port = 30000;
/* TODO: configise this */
path_world_setter((char*)"default");
// Run dedicated server if asked to
if (cmd_args.getFlag("server")) {
if (config_get_bool("server")) {
DSTACK("Dedicated server branch");
// Create time getter
@ -942,7 +844,7 @@ int main(int argc, char *argv[])
// Create server
Server server;
server.start(port);
server.start();
// Run server
dedicated_server_loop(server, kill);
@ -950,60 +852,32 @@ int main(int argc, char *argv[])
return 0;
}
/*
More parameters
*/
// Address to connect to
std::string address = "";
if (cmd_args.exists("address")) {
address = cmd_args.get("address");
}else{
address = g_settings->get("address");
}
std::string playername = g_settings->get("name");
/*
Device initialization
*/
// Resolution selection
bool fullscreen = g_settings->getBool("fullscreen");
u16 screenW = g_settings->getU16("screenW");
u16 screenH = g_settings->getU16("screenH");
bool fullscreen = config_get_bool("client.video.fullscreen");
u16 screenW = config_get_int("client.video.size.width");
u16 screenH = config_get_int("client.video.size.height");
vlprintf(CN_INFO,"size %dx%d",screenW,screenH);
// bpp, fsaa, vsync
bool vsync = g_settings->getBool("vsync");
u16 bits = g_settings->getU16("fullscreen_bpp");
u16 fsaa = g_settings->getU16("fsaa");
bool vsync = config_get_bool("client.video.vsync");
u16 bits = config_get_int("client.video.fullscreen.bpp");
u16 fsaa = config_get_int("client.video.fullscreen.fsaa");
// Determine driver
video::E_DRIVER_TYPE driverType;
video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;
std::string driverstring = g_settings->get("video_driver");
if (driverstring == "null") {
driverType = video::EDT_NULL;
}else if (driverstring == "software") {
driverType = video::EDT_SOFTWARE;
}else if (driverstring == "burningsvideo") {
driverType = video::EDT_BURNINGSVIDEO;
}else if (driverstring == "direct3d8") {
driverType = video::EDT_DIRECT3D8;
}else if (driverstring == "direct3d9") {
driverType = video::EDT_DIRECT3D9;
}else if (driverstring == "opengl") {
driverType = video::EDT_OPENGL;
}else{
errorstream<<"WARNING: Invalid video_driver specified; defaulting "
"to opengl"<<std::endl;
driverType = video::EDT_OPENGL;
{
char* v = config_get("client.video.driver");
if (v && !strcmp(v,"d3d9"))
driverType = video::EDT_DIRECT3D9;
}
/*
@ -1021,15 +895,10 @@ int main(int argc, char *argv[])
params.Stencilbuffer = false;
params.Vsync = vsync;
params.EventReceiver = &receiver;
params.HighPrecisionFPU = g_settings->getBool("high_precision_fpu");
params.HighPrecisionFPU = config_get_bool("client.video.hpfpu");
IrrlichtDevice * device = createDeviceEx(params);
//IrrlichtDevice *device;
//device = createDevice(driverType,
//core::dimension2d<u32>(screenW, screenH),
//16, fullscreen, false, false, &receiver);
if (device == 0)
return 1; // could not create selected driver.
@ -1042,14 +911,8 @@ int main(int argc, char *argv[])
// Disable mipmaps (because some of them look ugly)
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
/*
This changes the minimum allowed number of vertices in a VBO.
Default is 500.
*/
//driver->setMinHardwareBufferVertexCount(50);
// Set the window caption
device->setWindowCaption(L"Voxelands [Main Menu]");
device->setWindowCaption(L"Voxelands");
// Create time getter
g_timegetter = new IrrlichtTimeGetter(device);
@ -1062,25 +925,9 @@ int main(int argc, char *argv[])
drawLoadingScreen(device,L"");
/*
Speed tests (done after irrlicht is loaded to get timer)
*/
if (cmd_args.getFlag("speedtests")) {
dstream<<"Running speed tests"<<std::endl;
SpeedTests();
return 0;
}
device->setResizable(true);
bool random_input = g_settings->getBool("random_input")
|| cmd_args.getFlag("random-input");
InputHandler *input = NULL;
if (random_input) {
input = new RandomInputHandler();
}else{
input = new RealInputHandler(device, &receiver);
}
InputHandler *input = new RealInputHandler(device, &receiver);
scene::ISceneManager* smgr = device->getSceneManager();
@ -1090,11 +937,14 @@ int main(int argc, char *argv[])
{
char buff[1024];
#if USE_FREETYPE
u16 font_size = g_settings->getU16("font_size");
if (path_get((char*)"font",(char*)"unifont.ttf",1,buff,1024))
uint16_t font_size = config_get_int("client.ui.font.size");
char* v = config_get("client.ui.font");
if (!v)
v = "unifont.ttf";
if (path_get("font",v,1,buff,1024))
font = gui::CGUITTFont::createTTFont(guienv, buff, font_size, true, true, 1, 128);
#else
if (path_get((char*)"texture",(char*)"fontlucida.png",1,buff,1024))
if (path_get("texture","fontlucida.png",1,buff,1024))
font = guienv->getFont(buff);
#endif
}
@ -1157,7 +1007,12 @@ int main(int argc, char *argv[])
std::string password;
// if there's no chardef then put the player directly into the character creator
bool character_creator = !g_settings->exists("character_definition");
bool character_creator = true;
{
char* v = config_get("client.character");
if (v && v[0])
character_creator = false;
}
/*
Menu-game loop
@ -1192,33 +1047,36 @@ int main(int argc, char *argv[])
smgr->clear();
// Initialize menu data
std::string playername = "";
{
char* v = config_get("client.name");
if (v)
playername = std::string(v);
}
if (playername == "")
playername = porting::getUser();
MainMenuData menudata;
menudata.address = narrow_to_wide(address);
menudata.address = L"";
menudata.name = narrow_to_wide(playername);
menudata.port = narrow_to_wide(itos(port));
menudata.game_mode = narrow_to_wide(g_settings->get("game_mode"));
menudata.max_mob_level = narrow_to_wide(g_settings->get("max_mob_level"));
menudata.initial_inventory = g_settings->getBool("initial_inventory");
menudata.infinite_inventory = g_settings->getBool("infinite_inventory");
menudata.droppable_inventory = g_settings->getBool("droppable_inventory");
menudata.death_drops_inventory = g_settings->getBool("death_drops_inv");
menudata.enable_damage = g_settings->getBool("enable_damage");
menudata.suffocation = g_settings->getBool("enable_suffocation");
menudata.hunger = g_settings->getBool("enable_hunger");
menudata.tool_wear = g_settings->getBool("tool_wear");
menudata.unsafe_fire = g_settings->getBool("unsafe_fire");
menudata.port = L"";
menudata.game_mode = narrow_to_wide(bridge_config_get("world.game.mode"));
menudata.max_mob_level = narrow_to_wide(bridge_config_get("world.game.mob.spawn.level"));
menudata.initial_inventory = config_get_bool("world.player.inventory.starter");
menudata.infinite_inventory = config_get_bool("world.player.inventory.creative");
menudata.droppable_inventory = config_get_bool("world.player.inventory.droppable");
menudata.death_drops_inventory = config_get_bool("world.player.inventory.keep");
menudata.enable_damage = config_get_bool("world.player.damage");
menudata.suffocation = config_get_bool("world.player.suffocation");
menudata.hunger = config_get_bool("world.player.hunger");
menudata.tool_wear = config_get_bool("world.player.tool.wear");
menudata.unsafe_fire = config_get_bool("world.game.environment.fire.spread");
menudata.delete_map = false;
menudata.clear_map = false;
menudata.use_fixed_seed = false;
if (g_settings->exists("fixed_map_seed")) {
menudata.fixed_seed = narrow_to_wide(g_settings->get("fixed_map_seed"));
if (menudata.fixed_seed != L"")
menudata.use_fixed_seed = true;
}
if (g_settings->exists("mapgen_type"))
menudata.map_type = g_settings->get("mapgen_type");
menudata.fixed_seed = narrow_to_wide(bridge_config_get("world.seed"));
if (menudata.fixed_seed != L"")
menudata.use_fixed_seed = true;
menudata.map_type = config_get("world.map.type");
GUIMainMenu *menu = new GUIMainMenu(
guienv,
@ -1301,8 +1159,8 @@ int main(int argc, char *argv[])
continue;
}
if (menudata.use_fixed_seed)
g_settings->set("fixed_map_seed",wide_to_narrow(menudata.fixed_seed));
g_settings->set("mapgen_type",menudata.map_type);
config_set("world.map.seed",(char*)wide_to_narrow(menudata.fixed_seed).c_str());
config_set("world.map_type",(char*)menudata.map_type.c_str());
}else if (menudata.clear_map) {
if (path_remove((char*)"world",(char*)"map.sqlite")) {
error_message = L"Map clearing failed";
@ -1310,38 +1168,31 @@ int main(int argc, char *argv[])
}
}
playername = wide_to_narrow(menudata.name);
password = translatePassword(playername, menudata.password);
//infostream<<"Main: password hash: '"<<password<<"'"<<std::endl;
address = wide_to_narrow(menudata.address);
config_set("world.server.address",(char*)wide_to_narrow(menudata.address).c_str());
int newport = mywstoi(menudata.port);
if (newport != 0)
port = newport;
g_settings->set("game_mode", wide_to_narrow(menudata.game_mode));
g_settings->set("max_mob_level", wide_to_narrow(menudata.max_mob_level));
g_settings->set("initial_inventory", itos(menudata.initial_inventory));
g_settings->set("infinite_inventory", itos(menudata.infinite_inventory));
g_settings->set("droppable_inventory", itos(menudata.droppable_inventory));
g_settings->set("death_drops_inv", itos(menudata.death_drops_inventory));
g_settings->set("enable_damage", itos(menudata.enable_damage));
g_settings->set("enable_suffocation", itos(menudata.suffocation));
g_settings->set("enable_hunger", itos(menudata.hunger));
g_settings->set("tool_wear", itos(menudata.tool_wear));
g_settings->set("unsafe_fire", itos(menudata.unsafe_fire));
config_set_int("world.server.port",newport);
config_set("world.game.mode", (char*)wide_to_narrow(menudata.game_mode).c_str());
config_set("world.game.mob.spawn.level", (char*)wide_to_narrow(menudata.max_mob_level).c_str());
config_set_int("world.player.inventory.starter", menudata.initial_inventory);
config_set_int("world.player.inventory.creative", menudata.infinite_inventory);
config_set_int("world.player.inventory.droppable", menudata.droppable_inventory);
config_set_int("world.player.inventory.keep", menudata.death_drops_inventory);
config_set_int("world.player.damage", menudata.enable_damage);
config_set_int("world.player.suffocation", menudata.suffocation);
config_set_int("world.player.hunger", menudata.hunger);
config_set_int("world.player.tool.wear", menudata.tool_wear);
config_set_int("world.game.environment.fire.spread", menudata.unsafe_fire);
// Save settings
g_settings->set("name", playername);
g_settings->set("address", address);
g_settings->set("port", itos(port));
// Update configuration file
{
char buff[1024];
if (path_get((char*)"config",(char*)"voxelands.conf",0,buff,1024))
g_settings->updateConfigFile(buff);
}
config_set("client.name", (char*)wide_to_narrow(menudata.name).c_str());
config_set("world.admin.name",(char*)wide_to_narrow(menudata.name).c_str());
config_save(NULL,NULL,NULL);
// Continue to game
break;
@ -1398,14 +1249,10 @@ int main(int argc, char *argv[])
*/
the_game(
kill,
random_input,
input,
device,
font,
playername,
password,
address,
port,
error_message,
sound
);

View File

@ -26,10 +26,6 @@
#ifndef MAIN_HEADER
#define MAIN_HEADER
// Settings
class GameSettings;
extern GameSettings *g_settings;
// This makes and maps textures
class ITextureSource;
extern ITextureSource *g_texturesource;

View File

@ -23,6 +23,8 @@
* for Voxelands.
************************************************************************/
#include "common.h"
#include "map.h"
#include "mapsector.h"
#include "mapblock.h"
@ -39,7 +41,6 @@
#ifndef SERVER
#include <IMaterialRenderer.h>
#endif
#include "settings.h"
#include "log.h"
#include "profiler.h"
#include "inventory.h"
@ -1685,106 +1686,23 @@ void Map::nodeMetadataStep(float dtime, core::map<v3s16, MapBlock*> &changed_blo
ServerMap::ServerMap():
Map(dout_server),
m_seed(0),
m_map_metadata_changed(true),
m_database(NULL),
m_database_read(NULL),
m_database_write(NULL)
{
char b[1024];
infostream<<__FUNCTION_NAME<<std::endl;
//m_chunksize = 8; // Takes a few seconds
if (g_settings->get("fixed_map_seed").empty()) {
m_seed = (((uint64_t)(myrand()%0xffff)<<0)
+ ((uint64_t)(myrand()%0xffff)<<16)
+ ((uint64_t)(myrand()%0xffff)<<32)
+ ((uint64_t)(myrand()%0xffff)<<48));
}else{
m_seed = g_settings->getU64("fixed_map_seed");
}
m_type = MGT_DEFAULT;
if (g_settings->exists("mapgen_type")) {
std::string type = g_settings->get("mapgen_type");
if (type == "flat") {
m_type = MGT_FLAT;
}else if (type == "flatter") {
m_type = MGT_FLATTER;
}else if (type == "smoother") {
m_type = MGT_SMOOTHER;
}else if (type == "hilly") {
m_type = MGT_HILLY;
}else if (type == "mountains") {
m_type = MGT_MOUNTAINS;
}else if (type == "crazy") {
m_type = MGT_CRAZY;
}else if (type == "crazyhills") {
m_type = MGT_CRAZYHILLS;
}
}
/*
Experimental and debug stuff
*/
{
}
loadMapMeta();
/*
Try to load map; if not found, create a new one.
*/
m_map_saving_enabled = false;
if (path_get("world","map.sqlite",1,b,1024))
return;
try{
// If directory exists, check contents and load if possible
char buff[1024];
if (path_get((char*)"world",NULL,1,buff,1024)) {
// If directory is empty, it is safe to save into it.
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{
try{
// Load map metadata (seed, type, chunksize)
loadMapMeta();
}
catch(FileNotGoodException &e){
infostream<<"WARNING: Could not load map metadata"
//<<" Disabling chunk-based generator."
<<std::endl;
//m_chunksize = 0;
}
infostream<<"Server: Successfully loaded map "
<<"and chunk metadata from "<<buff
<<", assuming valid save directory."
<<std::endl;
m_map_saving_enabled = true;
// Map loaded, not creating new one
return;
}
// If directory doesn't exist, it is safe to save to it
}else{
m_map_saving_enabled = true;
}
}
catch(std::exception &e)
{
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;
}
infostream<<"Initializing new map."<<std::endl;
vlprintf(CN_ACTION,"Initializing new map");
// Create zero sector
emergeSector(v2s16(0,0));
@ -1798,13 +1716,8 @@ ServerMap::~ServerMap()
infostream<<__FUNCTION_NAME<<std::endl;
try{
if (m_map_saving_enabled) {
// Save only changed parts
save(true);
infostream<<"Server: saved map"<<std::endl;
}else{
infostream<<"Server: map not saved"<<std::endl;
}
save(true);
infostream<<"Server: saved map"<<std::endl;
}
catch(std::exception &e)
{
@ -1826,11 +1739,6 @@ ServerMap::~ServerMap()
void ServerMap::initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos)
{
bool enable_mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info");
if (enable_mapgen_debug_info)
infostream<<"initBlockMake(): ("<<blockpos.X<<","<<blockpos.Y<<","
<<blockpos.Z<<")"<<std::endl;
// Do nothing if not inside limits (+-1 because of neighbors)
if (
blockpos_over_limit(blockpos - v3s16(1,1,1))
@ -1910,8 +1818,6 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
if (data->no_op)
return NULL;
bool enable_mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info");
/*
Blit generated stuff to map
NOTE: blitBackAll adds nearly everything to changed_blocks
@ -1922,10 +1828,6 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
data->vmanip->blitBackAllWithMeta(&changed_blocks);
}
if (enable_mapgen_debug_info)
infostream<<"finishBlockMake: changed_blocks.size()="
<<changed_blocks.size()<<std::endl;
/*
Copy transforming liquid information
*/
@ -2020,8 +1922,6 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
NOTE: This takes ~60ms, TODO: Investigate why
*/
{
TimeTaker t("finishBlockMake lighting update");
core::map<v3s16, MapBlock*> lighting_update_blocks;
// Center block
lighting_update_blocks.insert(block->getPos(), block);
@ -2039,9 +1939,6 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
v3s16 p = block->getPos()+v3s16(x,y,z);
getBlockNoCreateNoEx(p)->setLightingExpired(false);
}
if(enable_mapgen_debug_info == false)
t.stop(true); // Hide output
}
/*
@ -2116,14 +2013,6 @@ MapBlock * ServerMap::generateBlock(
{
DSTACKF("%s: p=(%d,%d,%d)", __FUNCTION_NAME, p.X, p.Y, p.Z);
/*infostream<<"generateBlock(): "
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
<<std::endl;*/
bool enable_mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info");
TimeTaker timer("generateBlock");
v2s16 p2d(p.X, p.Z);
/*
@ -2143,13 +2032,7 @@ MapBlock * ServerMap::generateBlock(
/*
Generate block
*/
{
TimeTaker t("mapgen::make_block()");
mapgen::make_block(&data);
if (enable_mapgen_debug_info == false)
t.stop(true); // Hide output
}
mapgen::make_block(&data);
/*
Blit data back on map, update lighting, add mobs and whatever this does
@ -2161,9 +2044,6 @@ MapBlock * ServerMap::generateBlock(
*/
MapBlock *block = getBlockNoCreateNoEx(p);
if (enable_mapgen_debug_info == false)
timer.stop(true); // Hide output
return block;
}
@ -2367,18 +2247,11 @@ sqlite3_int64 ServerMap::getBlockAsInteger(const v3s16 pos) {
void ServerMap::save(bool only_changed)
{
DSTACK(__FUNCTION_NAME);
if (m_map_saving_enabled == false) {
infostream<<"WARNING: Not saving map, saving disabled."<<std::endl;
return;
}
if (only_changed == false)
infostream<<"ServerMap: Saving whole map, this can take time."
<<std::endl;
if (only_changed == false || m_map_metadata_changed)
saveMapMeta();
u32 block_count = 0;
u32 block_count_all = 0; // Number of blocks in memory
@ -2462,119 +2335,42 @@ void ServerMap::listAllLoadableBlocks(core::list<v3s16> &dst)
}
}
void ServerMap::saveMapMeta()
{
DSTACK(__FUNCTION_NAME);
infostream<<"ServerMap::saveMapMeta(): "
<<"seed="<<m_seed
<<std::endl;
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::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");
}
Settings params;
params.setU64("seed", m_seed);
switch (m_type) {
case MGT_FLAT:
params.set("type","flat");
break;
case MGT_FLATTER:
params.set("type","flatter");
break;
case MGT_SMOOTHER:
params.set("type","smoother");
break;
case MGT_HILLY:
params.set("type","hilly");
break;
case MGT_MOUNTAINS:
params.set("type","mountains");
break;
case MGT_CRAZY:
params.set("type","crazy");
break;
case MGT_CRAZYHILLS:
params.set("type","crazyhills");
break;
default:
params.set("type","default");
}
params.writeLines(os);
os<<"[end_of_params]\n";
m_map_metadata_changed = false;
}
void ServerMap::loadMapMeta()
{
DSTACK(__FUNCTION_NAME);
infostream<<"ServerMap::loadMapMeta(): Loading map metadata"<<std::endl;
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");
if (!config_get("world.seed")) {
m_seed = (
((uint64_t)(myrand()%0xffff)<<0)
+ ((uint64_t)(myrand()%0xffff)<<16)
+ ((uint64_t)(myrand()%0xffff)<<32)
+ ((uint64_t)(myrand()%0xffff)<<48)
);
config_set_int64("world.seed",m_seed);
}else{
m_seed = config_get_int64("world.seed");
}
std::ifstream is(buff, std::ios_base::binary);
if (is.good() == false) {
infostream<<"ERROR: ServerMap::loadMapMeta(): "
<<"could not open map_meta.txt"<<std::endl;
throw FileNotGoodException("Cannot open map metadata");
}
Settings params;
for (;;) {
if(is.eof())
throw SerializationError
("ServerMap::loadMapMeta(): [end_of_params] not found");
std::string line;
std::getline(is, line);
std::string trimmedline = trim(line);
if (trimmedline == "[end_of_params]")
break;
params.parseConfigLine(line);
}
m_seed = params.getU64("seed");
m_type = MGT_DEFAULT;
if (params.exists("type")) {
std::string type = params.get("type");
if (type == "flat") {
if (config_get("world.map.type")) {
char* type = config_get("world.map.type");
if (!strcmp(type,"flat")) {
m_type = MGT_FLAT;
}else if (type == "flatter") {
}else if (!strcmp(type,"flatter")) {
m_type = MGT_FLATTER;
}else if (type == "smoother") {
}else if (!strcmp(type,"smoother")) {
m_type = MGT_SMOOTHER;
}else if (type == "hilly") {
}else if (!strcmp(type,"hilly")) {
m_type = MGT_HILLY;
}else if (type == "mountains") {
}else if (!strcmp(type,"mountains")) {
m_type = MGT_MOUNTAINS;
}else if (type == "crazy") {
}else if (!strcmp(type,"crazy")) {
m_type = MGT_CRAZY;
}else if (type == "crazyhills") {
}else if (!strcmp(type,"crazyhills")) {
m_type = MGT_CRAZYHILLS;
}else{
config_set("world.map.type","default");
}
}else{
config_set("world.map.type","default");
}
infostream<<"ServerMap::loadMapMeta(): "<<"seed="<<m_seed<<std::endl;
}
void ServerMap::beginSave() {
@ -2773,9 +2569,9 @@ ClientMap::ClientMap(
m_box = core::aabbox3d<f32>(-BS*1000000,-BS*1000000,-BS*1000000,
BS*1000000,BS*1000000,BS*1000000);
m_render_trilinear = g_settings->getBool("trilinear_filter");
m_render_bilinear = g_settings->getBool("bilinear_filter");
m_render_anisotropic = g_settings->getBool("anisotropic_filter");
m_render_trilinear = config_get_bool("client.video.trilinear");
m_render_bilinear = config_get_bool("client.video.bilinear");
m_render_anisotropic = config_get_bool("client.video.anisotropic");
}
ClientMap::~ClientMap()
@ -2921,7 +2717,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
// Blocks from which stuff was actually drawn
u32 blocks_without_stuff = 0;
bool anim_textures = g_settings->getBool("enable_animated_textures");
bool anim_textures = config_get_bool("client.graphics.texture.animations");
float anim_time = m_client->getAnimationTime();
/*

View File

@ -389,8 +389,6 @@ public:
void listAllLoadableBlocks(core::list<v3s16> &dst);
// Saves map seed and possibly other stuff
void saveMapMeta();
void loadMapMeta();
void saveBlock(MapBlock *block);
@ -401,8 +399,6 @@ public:
// For debug printing
virtual void PrintInfo(std::ostream &out);
bool isSavingEnabled(){ return m_map_saving_enabled; }
uint64_t getSeed(){ return m_seed; }
MapGenType getType() {return m_type;}
@ -411,14 +407,6 @@ private:
uint64_t m_seed;
MapGenType m_type;
bool m_map_saving_enabled;
/*
Metadata is re-written on disk only if this is true.
This is reset to false when written on disk.
*/
bool m_map_metadata_changed;
/*
SQLite database and statements
*/

View File

@ -23,6 +23,8 @@
* for Voxelands.
************************************************************************/
#include "common.h"
#include "mapblock_mesh.h"
#include "light.h"
#include "mapblock.h"
@ -30,7 +32,6 @@
#include "main.h" // For g_settings and g_texturesource
#include "content_mapblock.h"
#include "content_nodemeta.h"
#include "settings.h"
#include "profiler.h"
#include "mesh.h"
#include "base64.h"
@ -490,10 +491,8 @@ void MapBlockMesh::animate(float time)
m_animation_data[it->first].frame = frame;
// Make sure we don't cause an overflow. Can get removed in future if no problems occuring
if (it->first >= m_mesh->getMeshBufferCount()) {
errorstream << ": animate() Tying to index non existent Buffer." << std::endl;
if (it->first >= m_mesh->getMeshBufferCount())
return;
}
scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(it->first);
@ -513,11 +512,9 @@ void MapBlockMesh::generate(MeshMakeData *data, v3s16 camera_offset, JMutex *mut
{
DSTACK(__FUNCTION_NAME);
BEGIN_DEBUG_EXCEPTION_HANDLER
data->mesh_detail = g_settings->getU16("mesh_detail");
data->texture_detail = g_settings->getU16("texture_detail");
data->light_detail = g_settings->getU16("light_detail");
data->mesh_detail = config_get_int("client.graphics.mesh.lod");
data->texture_detail = config_get_int("client.graphics.texture.lod");
data->light_detail = config_get_int("client.graphics.light.lod");
m_pos = data->m_blockpos;
SelectedNode selected;
if (!m_animation_data.empty())
@ -736,8 +733,6 @@ void MapBlockMesh::generate(MeshMakeData *data, v3s16 camera_offset, JMutex *mut
// Get frist frame of animation AFTER the mutex is unlocked
animate(0.0);
END_DEBUG_EXCEPTION_HANDLER(errorstream)
}
void MapBlockMesh::refresh(u32 daynight_ratio)

View File

@ -37,7 +37,6 @@
#include <IMeshLoader.h>
#include <IMeshCache.h>
#include "main.h"
#include "settings.h"
// In Irrlicht 1.8 the signature of ITexture::lock was changed from
// (bool, u32) to (E_TEXTURE_LOCK_MODE, u32).

143
src/nvp.c
View File

@ -17,6 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
************************************************************************/
#include "common.h"
#include "list.h"
#include "nvp.h"
#include "crypto.h"
@ -24,6 +25,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
/* comparison functions:
* return 0 to insert
@ -168,3 +170,144 @@ void nvp_set_float(nvp_t **list, char* name, float value)
sprintf(str,"%f",value);
nvp_set(list,name,str,NULL);
}
/* set a name/value pair to a float value */
void nvp_set_v3t(nvp_t **list, char* name, v3_t *value)
{
char str[128];
sprintf(str,"(%f,%f,%f)",value->x,value->y,value->z);
nvp_set(list,name,str,NULL);
}
/* parse a name=value string to an nvp list */
void nvp_from_str(nvp_t **list, char* str)
{
char name[512];
char value[512];
uint8_t is_str = 0;
uint8_t is_value = 0;
int i;
int o = 0;
if (!str)
return;
for (i=0; str[i]; i++) {
if (str[i] == '\r')
continue;
if (str[i] == '\n') {
if (!is_value) {
o = 0;
continue;
}
is_value = 0;
is_str = 0;
value[o] = 0;
o = 0;
nvp_set(list,name,value,NULL);
continue;
}else if (is_value) {
if (!o) {
if (isspace(str[i]))
continue;
if (str[i] == '"') {
is_str = 1;
continue;
}
}
if (is_str) {
if (str[i] == '\\') {
i++;
if (!str[i] || str[i] == '\n') {
is_value = 0;
is_str = 0;
value[o] = 0;
o = 0;
nvp_set(list,name,value,NULL);
continue;
}
}else if (str[i] == '"') {
is_value = 0;
is_str = 0;
value[o] = 0;
o = 0;
nvp_set(list,name,value,NULL);
continue;
}
}
if (o < 511)
value[o++] = str[i];
continue;
}else if (str[i] == '=') {
name[o] = 0;
o = 0;
is_value = 1;
continue;
}
if (isspace(str[i]))
continue;
if (o < 511)
name[o++] = str[i];
}
}
/* write an nvp list to a name=value string */
int nvp_to_str(nvp_t **list, char* buff, int size)
{
nvp_t *n;
int r = 0;
int ns;
int vs;
int i;
if (!size)
return -1;
if (!list || !*list) {
buff[0] = 0;
return 0;
}
n = *list;
while (n) {
if (!n->name || !n->value) {
n = n->next;
continue;
}
ns = strlen(n->name);
vs = strlen(n->value);
if (ns+(vs*2)+6 > size-(r+1))
return -2;
for (i=0; i<ns; i++) {
buff[r++] = n->name[i];
}
buff[r++] = ' ';
buff[r++] = '=';
buff[r++] = ' ';
buff[r++] = '"';
for (i=0; i<vs; i++) {
if (n->value[i] == '"' || n->value[i] == '\\')
buff[r++] = '\\';
buff[r++] = n->value[i];
}
buff[r++] = '"';
buff[r++] = '\n';
n = n->next;
}
buff[r] = 0;
return r;
}

View File

@ -5,6 +5,10 @@
extern "C" {
#endif
#ifndef _HAVE_V3_TYPE
struct v3_s;
#endif
#ifndef _HAVE_NVP_TYPE
#define _HAVE_NVP_TYPE
typedef struct nvp_s {
@ -28,6 +32,9 @@ void *nvp_get_data(nvp_t **list, char* name);
void nvp_set(nvp_t **list, char* name, char* value, void *data);
void nvp_set_int(nvp_t **list, char* name, int value);
void nvp_set_float(nvp_t **list, char* name, float value);
void nvp_set_v3t(nvp_t **list, char* name, struct v3_s *value);
void nvp_from_str(nvp_t **list, char* str);
int nvp_to_str(nvp_t **list, char* buff, int size);
#ifdef __cplusplus
}

View File

@ -26,8 +26,7 @@
#include "particles.h"
#include "constants.h"
#include "debug.h"
#include "main.h" // For g_profiler and g_settings
#include "settings.h"
#include "main.h"
#include "tile.h"
#include "collision.h"
#include <stdlib.h>

View File

@ -17,31 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
************************************************************************/
#ifndef LINUX
#ifdef __linux__
#define LINUX
#endif
#endif
#ifdef LINUX
#ifdef _POSIX_C_SOURCE
#undef _POSIX_C_SOURCE
#endif
#define _POSIX_C_SOURCE 200112L
#ifdef _XOPEN_SOURCE
#undef _XOPEN_SOURCE
#endif
#define _XOPEN_SOURCE 700
#ifdef _DEFAULT_SOURCE
#undef _DEFAULT_SOURCE
#endif
#define _DEFAULT_SOURCE
#endif
#include "common.h"
#include "file.h"
#include "path.h"
#include "list.h"

View File

@ -23,6 +23,9 @@
* for Voxelands.
************************************************************************/
#include "common.h"
#include "nvp.h"
#include "player.h"
#include "map.h"
#include "connection.h"
@ -32,7 +35,6 @@
#include "common_irrlicht.h"
#include "mesh.h"
#endif
#include "settings.h"
#include "path.h"
#include "content_clothesitem.h"
@ -207,31 +209,62 @@ void Player::accelerate(v3f target_speed, f32 max_increase)
void Player::serialize(std::ostream &os)
{
// Utilize a Settings object for storing values
Settings args;
args.setS32("version", 1);
args.set("name", m_name);
args.setFloat("pitch", m_pitch);
args.setFloat("yaw", m_yaw);
args.setV3F("position", m_position);
args.setBool("craftresult_is_preview", craftresult_is_preview);
args.setS32("health", health);
args.setS32("air", air);
args.setS32("hunger", hunger);
if (m_hashome)
args.setV3F("home",m_home);
const char* flags[8] = {"white","blue","green","orange","purple","red","yellow","black"};
for (u16 i=0; i<8; i++) {
std::string n("flag_");
n += flags[i];
char* flags[8] = {
"flag_white",
"flag_blue",
"flag_green",
"flag_orange",
"flag_purple",
"flag_red",
"flag_yellow",
"flag_black"
};
nvp_t *list = NULL;
char buff[1024];
int i;
v3_t v;
nvp_set(&list,"version","1",NULL);
nvp_set(&list,"name",m_name,NULL);
nvp_set_float(&list,"pitch",m_pitch);
nvp_set_float(&list,"yaw",m_yaw);
v.x = m_position.X;
v.y = m_position.Y;
v.z = m_position.Z;
nvp_set_v3t(&list,"position",&v);
nvp_set_int(&list,"craftresult_is_preview",craftresult_is_preview);
nvp_set_int(&list,"health",health);
nvp_set_int(&list,"air",air);
nvp_set_int(&list,"hunger",hunger);
if (m_hashome) {
/* home */
v.x = m_home.X;
v.y = m_home.Y;
v.z = m_home.Z;
nvp_set_v3t(&list,"home",&v);
}
for (i=0; i<8; i++) {
if (!m_hasflag[i])
continue;
args.setV3F(n,m_flag[i]);
/* flags */
v.x = m_flag[i].X;
v.y = m_flag[i].Y;
v.z = m_flag[i].Z;
nvp_set_v3t(&list,flags[i],&v);
}
if (m_given_clothes)
args.set("clothes_given","true");
args.setFloat("wake_timeout",wake_timeout);
nvp_set(&list,"clothes_given","true",NULL);
nvp_set_float(&list,"wake_timeout",wake_timeout);
args.writeLines(os);
if (nvp_to_str(&list,buff,1024) < 1) {
vlprintf(CN_DEBUG,"failed to serialise player data");
nvp_free(&list,0);
return;
}
nvp_free(&list,0);
os << buff;
os<<"PlayerArgsEnd\n";
@ -240,7 +273,20 @@ void Player::serialize(std::ostream &os)
void Player::deSerialize(std::istream &is)
{
Settings args;
nvp_t *list = NULL;
std::string conf;
char* val;
v3_t v;
char* flags[8] = {
"flag_white",
"flag_blue",
"flag_green",
"flag_orange",
"flag_purple",
"flag_red",
"flag_yellow",
"flag_black"
};
for (;;) {
if (is.eof())
@ -250,77 +296,84 @@ void Player::deSerialize(std::istream &is)
std::string trimmedline = trim(line);
if (trimmedline == "PlayerArgsEnd")
break;
args.parseConfigLine(line);
conf += line + "\n";
}
//args.getS32("version");
std::string name = args.get("name");
updateName(name.c_str());
m_pitch = args.getFloat("pitch");
m_yaw = args.getFloat("yaw");
m_position = args.getV3F("position");
if (args.exists("craftresult_is_preview")) {
craftresult_is_preview = args.getBool("craftresult_is_preview");
nvp_from_str(&list,(char*)conf.c_str());
val = nvp_get_str(&list,"name");
if (!val)
val = "Unknown";
updateName(val);
m_pitch = nvp_get_float(&list,"pitch");
m_yaw = nvp_get_float(&list,"yaw");
val = nvp_get_str(&list,"position");
if (val) {
if (!str_tov3t(val,&v))
m_position = v3f(v.x,v.y,v.z);
}
if (nvp_get(&list,"craftresult_is_preview")) {
craftresult_is_preview = nvp_get_bool(&list,"craftresult_is_preview");
}else{
craftresult_is_preview = true;
}
if (args.exists("health")) {
health = args.getS32("health");
if (args.exists("air")) {
air = args.getS32("air");
if (nvp_get(&list,"health")) {
health = nvp_get_int(&list,"health");
if (nvp_get(&list,"air")) {
air = nvp_get_int(&list,"air");
}else{
air = 100;
}
if (args.exists("hunger")) {
hunger = args.getS32("hunger");
if (nvp_get(&list,"hunger")) {
hunger = nvp_get_int(&list,"hunger");
}else{
hunger = 100;
}
}else if (args.exists("hp")) {
health = 5*args.getS32("hp");
if (args.exists("air")) {
air = 5*args.getS32("air");
}else if (nvp_get(&list,"hp")) {
health = 5*nvp_get_int(&list,"hp");
if (nvp_get(&list,"air")) {
air = 5*nvp_get_int(&list,"air");
}else{
air = 100;
}
if (args.exists("hunger")) {
hunger = 5*args.getS32("hunger");
if (nvp_get(&list,"hunger")) {
hunger = 5*nvp_get_int(&list,"hunger");
}else{
hunger = 100;
}
}else{
health = 100;
}
if (args.exists("home")) {
m_home = args.getV3F("home");
m_hashome = true;
}else{
m_hashome = false;
m_hashome = false;
val = nvp_get_str(&list,"home");
if (val) {
if (!str_tov3t(val,&v)) {
m_home = v3f(v.x,v.y,v.z);
m_hashome = true;
}
}
const char* flags[8] = {"white","blue","green","orange","purple","red","yellow","black"};
for (u16 i=0; i<8; i++) {
std::string n("flag_");
n += flags[i];
m_hasflag[i] = args.exists(n);
if (!m_hasflag[i])
m_hasflag[i] = false;
if (!nvp_get(&list,flags[i]))
continue;
m_flag[i] = args.getV3F(n);
val = nvp_get_str(&list,flags[i]);
if (val) {
if (!str_tov3t(val,&v))
m_flag[i] = v3f(v.x,v.y,v.z);
}
if (!m_hashome) {
m_home = m_flag[i];
m_hashome = true;
}
m_hasflag[i] = true;
}
if (args.exists("clothes_given")) {
m_given_clothes = args.getBool("clothes_given");
}else{
m_given_clothes = false;
}
m_given_clothes = nvp_get_bool(&list,"clothes_given");
wake_timeout = nvp_get_float(&list,"wake_timeout");
if (args.exists("wake_timeout")) {
wake_timeout = args.getFloat("wake_timeout");
}else{
wake_timeout = 0.0;
}
nvp_free(&list,0);
inventory.deSerialize(is);
checkInventory();
@ -801,8 +854,14 @@ LocalPlayer::LocalPlayer():
m_ignore_energy(false),
m_low_energy_effect(0)
{
char* v;
m_energy = 10.0;
m_character = g_settings->get("character_definition");
v = config_get("client.character");
if (!v)
v = PLAYER_DEFAULT_CHARDEF;
m_character = v;
}
LocalPlayer::~LocalPlayer()

View File

@ -17,10 +17,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
************************************************************************/
#include "common.h"
#include "common_irrlicht.h"
#include "selection_mesh.h"
#include "content_mapblock.h"
#include "settings.h"
#include "main.h" // For g_settings and g_texturesource
#include "mesh.h"
#include "mapblock.h"
@ -115,10 +116,10 @@ void selection_draw(video::IVideoDriver* driver, Client &client, v3s16 camera_of
cos_changed = true;
}
bool render_trilinear = g_settings->getBool("trilinear_filter");
bool render_bilinear = g_settings->getBool("bilinear_filter");
bool render_anisotropic = g_settings->getBool("anisotropic_filter");
bool anim_textures = g_settings->getBool("enable_animated_textures");
bool render_trilinear = config_get_bool("client.video.trilinear");
bool render_bilinear = config_get_bool("client.video.bilinear");
bool render_anisotropic = config_get_bool("client.video.anisotropic");
bool anim_textures = config_get_bool("client.graphics.texture.animations");
for (std::vector<SelectionMesh*>::iterator i = meshes.begin(); i != meshes.end(); i++) {
SelectionMesh *mesh = *i;
@ -171,14 +172,12 @@ void SelectionMesh::animate(float time)
// If frame doesn't change, skip
if (frame == it->second.frame)// || temp_data.frame < 0)
continue;
m_animation_data[it->first].frame = frame;
// Make sure we don't cause an overflow. Can get removed if future is no problems occuring
if (it->first >= m_mesh->getMeshBufferCount()) {
errorstream << ": animate() Tying to index non existent Buffer." << std::endl;
if (it->first >= m_mesh->getMeshBufferCount())
return;
}
scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(it->first);
@ -207,13 +206,11 @@ void SelectionMesh::generate(MeshMakeData *data)
{
DSTACK(__FUNCTION_NAME);
BEGIN_DEBUG_EXCEPTION_HANDLER
data->m_BSd = 0.02;
data->m_BS = (float)BS+data->m_BSd;
data->mesh_detail = g_settings->getU16("mesh_detail");
data->texture_detail = g_settings->getU16("texture_detail");
data->light_detail = g_settings->getU16("light_detail");
data->mesh_detail = config_get_int("client.graphics.mesh.lod");
data->texture_detail = config_get_int("client.graphics.texture.lod");
data->light_detail = config_get_int("client.graphics.light.lod");
m_pos = data->m_blockpos;
for (std::map<v3s16,SelectedNode>::iterator i = data->m_selected.begin(); i != data->m_selected.end(); i++) {
@ -340,7 +337,6 @@ void SelectionMesh::generate(MeshMakeData *data)
refresh(data->m_daynight_ratio);
m_mesh->recalculateBoundingBox();
animate(0.0); // init first frame
END_DEBUG_EXCEPTION_HANDLER(errorstream)
}
void SelectionMesh::refresh(u32 daynight_ratio)

File diff suppressed because it is too large Load Diff

View File

@ -365,7 +365,7 @@ public:
Server();
~Server();
void start(unsigned short port);
void start();
void stop();
// This is mainly a way to pass the time to the server.
// Actual processing is done in an another thread.
@ -438,9 +438,6 @@ public:
uint64_t getPlayerPrivs(Player *player);
// Saves g_settings to configpath given at initialization
void saveConfig();
void setIpBanned(const std::string &ip, const std::string &name)
{
ban_add(const_cast<char*>(ip.c_str()),const_cast<char*>(name.c_str()));

608
src/servercommand.c Normal file
View File

@ -0,0 +1,608 @@
/************************************************************************
* Minetest-c55
* Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
* Copyright (C) 2011 Ciaran Gultnieks <ciaran@ciarang.com>
*
* servercommand.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 "common.h"
#include "array.h"
#include "auth.h"
#include "ban.h"
#include <string.h>
int command_status(command_context_t *ctx, array_t *args)
{
char buff[1024];
if (bridge_server_get_status(ctx,buff,1024))
return 1;
command_print(ctx,SEND_TO_SENDER,CN_INFO,"%s",buff);
return 0;
}
int command_me(command_context_t *ctx, array_t *args)
{
char* str;
if (!ctx || !args || !args->length)
return 1;
str = array_join(args," ",0);
if (!str)
return 1;
command_print(ctx,SEND_TO_OTHERS | SEND_NO_PREFIX, CN_CHAT, "* %s %s",ctx->player,str);
free(str);
return 0;
}
int command_privs(command_context_t *ctx, array_t *args)
{
char* str;
char buff[256];
uint64_t privs = 0;
if (!args || !args->length) {
if (!ctx) {
/* assume server console */
privs = PRIV_ALL;
}else{
/* Show our own real privs, without any adjustments made for admin status */
privs = auth_getprivs(ctx->player);
}
if (auth_privs2str(privs,buff,256) < 0)
buff[0] = 0;
command_print(ctx,SEND_TO_SENDER,CN_INFO,"%s",buff);
return 0;
}
if (ctx && (ctx->privs&PRIV_PRIVS) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
str = array_get_string(args,0);
if (!str) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (bridge_env_check_player(ctx,str) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"No such player");
return 1;
}
privs = auth_getprivs(str);
if (!privs) {
command_print(ctx,SEND_TO_SENDER,CN_CHAT,"none");
return 0;
}
if (auth_privs2str(privs,buff,256) < 0)
buff[0] = 0;
command_print(ctx,SEND_TO_SENDER,CN_INFO,"%s",buff);
return 0;
}
int command_grant(command_context_t *ctx, array_t *args)
{
char* name;
char* str;
uint64_t privs;
uint64_t newprivs = 0;
char buff[256];
int i;
if (ctx && (ctx->privs&PRIV_PRIVS) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (!args || args->length < 2) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Missing parameter");
return 1;
}
name = array_get_string(args,0);
if (!name) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (bridge_env_check_player(ctx,name) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"No such player");
return 1;
}
privs = auth_getprivs(name);
if (privs == PRIV_INVALID) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"No such player");
return 1;
}
for (i=1; i<args->length; i++) {
str = array_get_string(args,i);
if (!str)
break;
privs = auth_str2privs(str);
if (privs == PRIV_INVALID) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Invalid privileges specified");
return 1;
}
newprivs |= privs;
}
if (!newprivs || newprivs == PRIV_INVALID) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Invalid privileges specified");
return 1;
}
privs |= newprivs;
auth_setprivs(name,privs);
privs = auth_getprivs(name);
if (auth_privs2str(newprivs,buff,256) >= 0) {
char *n = "Server Admin";
if (ctx)
n = ctx->player;
bridge_server_notify_player(ctx,name,"%s granted you the privilege \"%s\"",n,buff);
}
if (auth_privs2str(privs,buff,256) < 0) {
strcpy(buff,"???");
}
command_print(ctx,SEND_TO_SENDER,CN_INFO,"Privileges changed to \"%s\"",buff);
return 0;
}
int command_revoke(command_context_t *ctx, array_t *args)
{
char* name;
char* str;
uint64_t privs;
uint64_t newprivs = 0;
char buff[256];
int i;
if (ctx && (ctx->privs&PRIV_PRIVS) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (!args || args->length < 2) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Missing parameter");
return 1;
}
name = array_get_string(args,0);
if (!name) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (bridge_env_check_player(ctx,name) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"No such player");
return 1;
}
privs = auth_getprivs(name);
if (privs == PRIV_INVALID) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"No such player");
return 1;
}
for (i=1; i<args->length; i++) {
str = array_get_string(args,i);
if (!str)
break;
privs = auth_str2privs(str);
if (privs == PRIV_INVALID) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Invalid privileges specified");
return 1;
}
newprivs |= privs;
}
if (!newprivs || newprivs == PRIV_INVALID) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Invalid privileges specified");
return 1;
}
privs &= ~newprivs;
auth_setprivs(name,privs);
privs = auth_getprivs(name);
if (auth_privs2str(newprivs,buff,256) >= 0) {
char *n = "Server Admin";
if (ctx)
n = ctx->player;
bridge_server_notify_player(ctx,name,"%s revoked from you the privilige \"%s\"",n,buff);
}
if (auth_privs2str(privs,buff,256) < 0) {
strcpy(buff,"???");
}
command_print(ctx,SEND_TO_SENDER,CN_INFO,"Privileges changed to \"%s\"",buff);
return 0;
}
int command_time(command_context_t *ctx, array_t *args)
{
char* str;
uint32_t time;
if (ctx && (ctx->privs&PRIV_SETTIME) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (!args || !args->length) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Missing parameter");
return 1;
}
str = array_get_string(args,0);
if (!str) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Missing parameter");
return 1;
}
time = strtol(str,NULL,10);
time %= 24000;
if (bridge_server_settime(ctx,time)) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Unable to set time");
return 1;
}
str = "Server Admin";
if (ctx)
str = ctx->player;
command_print(ctx,SEND_TO_OTHERS|SEND_TO_SENDER,CN_INFO,"%s sets time to %u",str,time);
return 0;
}
int command_shutdown(command_context_t *ctx, array_t *args)
{
if (ctx && (ctx->privs&PRIV_SERVER) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (bridge_server_shutdown(ctx)) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Unable to shutdown");
return 1;
}
command_print(ctx,SEND_TO_OTHERS|SEND_TO_SENDER,CN_INFO,"Server shutting down (operator request)");
return 0;
}
int command_teleport(command_context_t *ctx, array_t *args)
{
char* str;
v3_t pos;
if (ctx && (ctx->privs&PRIV_SERVER) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (!args || !args->length) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Missing parameter");
return 1;
}
str = array_get_string(args,0);
if (!str) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Missing parameter");
return 1;
}
if (!str_tov3t(str,&pos)) {
pos.x *= 10.0;
pos.y *= 10.0;
pos.z *= 10.0;
}else if (bridge_env_check_player(ctx,str) || bridge_env_player_pos(ctx,str,&pos)) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Teleport to where?");
return 1;
}
if (bridge_move_player(ctx,&pos)) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Unable to teleport");
return 1;
}
vlprintf(CN_ACTION,"%s teleports to %s",ctx->player,str);
command_print(ctx,SEND_TO_SENDER,CN_INFO,"Teleported to %s",str);
return 0;
}
int command_ban(command_context_t *ctx, array_t *args)
{
char* name;
char buff[256];
if (ctx && (ctx->privs&PRIV_BAN) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (!args || !args->length) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Missing parameter");
return 1;
}
name = array_get_string(args,0);
if (!name) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (bridge_env_check_player(ctx,name) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"No such player");
return 1;
}
if (bridge_server_get_player_ip_or_name(ctx,name,buff,256)) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"No such player");
return 1;
}
bridge_server_notify_player(ctx,name,"You have been banned from this server");
ban_add(buff,name);
command_print(ctx,SEND_TO_SENDER,CN_INFO,"Banned %s (%s)",name,buff);
return 0;
}
int command_unban(command_context_t *ctx, array_t *args)
{
char* name;
if (ctx && (ctx->privs&PRIV_BAN) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (!args || !args->length) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Missing parameter");
return 1;
}
name = array_get_string(args,0);
if (!name) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
ban_remove(name);
command_print(ctx,SEND_TO_SENDER,CN_INFO,"Unbanned %s",name);
return 0;
}
int command_adduser(command_context_t *ctx, array_t *args)
{
char* name;
char* pass;
if (ctx && (ctx->privs&PRIV_BAN) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (!args || args->length != 2) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Missing parameter");
return 1;
}
name = array_get_string(args,0);
pass = array_get_string(args,1);
if (!name || !pass) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (bridge_env_check_player(ctx,name) != 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Player '%s' already exists",name);
return 1;
}
if (bridge_server_add_player(ctx,name,pass)) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Unable to add player");
return 1;
}
command_print(ctx,SEND_TO_SENDER,CN_INFO,"Added user %s",name);
return 0;
}
int command_clearobjects(command_context_t *ctx, array_t *args)
{
if (ctx && (ctx->privs&PRIV_SERVER) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
bridge_server_notify_player(ctx,NULL,"Clearing all objects, server may lag for a while.");
bridge_env_clear_objects(ctx);
command_print(ctx,SEND_TO_SENDER|SEND_TO_OTHERS,CN_INFO,"Clearing objects complete.");
return 0;
}
int command_setpassword(command_context_t *ctx, array_t *args)
{
char* name;
char* pass;
char buff[256];
if (ctx && (ctx->privs&PRIV_SERVER) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (!args || args->length != 2) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Missing parameter");
return 1;
}
name = array_get_string(args,0);
pass = array_get_string(args,1);
if (!name || !pass) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (bridge_env_check_player(ctx,name) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"No such player");
return 1;
}
if (str_topwd(name,pass,buff,256)) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Invalid password");
return 1;
}
if (bridge_set_player_password(ctx,name,buff)) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Unable to set password");
return 1;
}
command_print(ctx,SEND_TO_SENDER,CN_INFO,"Password set for %s",name);
return 0;
}
/*
void cmd_help(std::wostringstream &os,
ServerCommandContext *ctx)
{
uint64_t privs = ctx->privs;
if (ctx->parms.size() > 1) {
if ((privs&PRIV_SERVER) == PRIV_SERVER) {
if (ctx->parms[1] == L"shutdown") {
os<<L"-!- /#shutdown - shutdown the server";
return;
}else if (ctx->parms[1] == L"clearobjects") {
os<<L"-!- /clearobjects - remove active objects from the world, may take a long time";
return;
}else if (ctx->parms[1] == L"setting") {
os<<L"-!- /#setting <SETTING> [= VALUE] - change or view a config setting";
return;
}else if (ctx->parms[1] == L"setpassword") {
os<<L"-!- /setpassword <PLAYERNAME> <PASSWORD> - change or set a player's password";
return;
}
}
if ((privs&PRIV_SETTIME) == PRIV_SETTIME && ctx->parms[1] == L"time") {
os<<L"-!- /time <0-23999> - set the game time";
return;
}
if ((privs&PRIV_TELEPORT) == PRIV_TELEPORT && ctx->parms[1] == L"teleport") {
os<<L"-!- /teleport <X>,<Y>,<Z> - teleport to coordinates <X>,<Y>,<Z>";
return;
}
if ((privs&PRIV_PRIVS) == PRIV_PRIVS) {
if (ctx->parms[1] == L"grant") {
os<<L"-!- /grant <PLAYERNAME> <PRIVILEGE> - grant a new privilege to a player";
return;
}else if (ctx->parms[1] == L"revoke") {
os<<L"-!- /revoke <PLAYERNAME> <PRIVILEGE> - remove privilege from a player";
return;
}
}
if ((privs&PRIV_BAN) == PRIV_BAN) {
if (ctx->parms[1] == L"ban") {
os<<L"-!- /ban <PLAYERNAME OR IP ADDRESS> - ban a player from the server";
return;
}else if (ctx->parms[1] == L"unban") {
os<<L"-!- /unban <PLAYERNAME OR IP ADDRESS> - remove a player's ban from the server";
return;
}else if (ctx->parms[1] == L"adduser") {
os<<L"-!- /adduser <PLAYERNAME> <PASSWORD> - add a new player with the specified password";
return;
}
}
if (ctx->parms[1] == L"privs") {
if ((privs&PRIV_PRIVS) == PRIV_PRIVS) {
os<<L"-!- /privs [PLAYERNAME] - view the server privileges of a player";
return;
}
os<<L"-!- /privs - view your server privileges";
return;
}
if (ctx->parms[1] == L"status") {
os<<L"-!- /status - view the server's status and welcome message";
return;
}
if (ctx->parms[1] == L"help") {
os<<L"-!- /help [COMMAND] - get help for a command or a list of commands";
return;
}
}
os<<L"-!- Available commands: ";
os<<L"help status privs";
if ((privs&PRIV_SERVER) == PRIV_SERVER)
os<<L" shutdown setting clearobjects setpassword";
if ((privs&PRIV_SETTIME) == PRIV_SETTIME)
os<<L" time";
if ((privs&PRIV_TELEPORT) == PRIV_TELEPORT)
os<<L" teleport";
if ((privs&PRIV_PRIVS) == PRIV_PRIVS)
os<<L" grant revoke";
if ((privs&PRIV_BAN) == PRIV_BAN)
os<<L" ban unban";
}
*/

View File

@ -1,518 +0,0 @@
/************************************************************************
* Minetest-c55
* Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
* Copyright (C) 2011 Ciaran Gultnieks <ciaran@ciarang.com>
*
* servercommand.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 "servercommand.h"
#include "utility.h"
#include "settings.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
void cmd_status(std::wostringstream &os,
ServerCommandContext *ctx)
{
os<<ctx->server->getStatusString();
}
void cmd_me(std::wostringstream &os,
ServerCommandContext *ctx)
{
std::wstring name = narrow_to_wide(ctx->player->getName());
os << L"* " << name << L" " << ctx->paramstring;
ctx->flags |= SEND_TO_OTHERS | SEND_NO_PREFIX;
}
void cmd_privs(std::wostringstream &os,
ServerCommandContext *ctx)
{
char buff[256];
if (ctx->parms.size() == 1) {
/* Show our own real privs, without any adjustments made for admin status */
uint64_t privs = auth_getprivs((char*)ctx->player->getName());
if (auth_privs2str(privs,buff,256) < 0)
buff[0] = 0;
os<<L"-!- " + narrow_to_wide(buff);
return;
}
if ((ctx->privs & PRIV_PRIVS) == 0) {
os<<L"-!- You don't have permission to do that";
return;
}
Player *tp = ctx->env->getPlayer(wide_to_narrow(ctx->parms[1]).c_str());
if (tp == NULL) {
os<<L"-!- No such player";
return;
}
uint64_t privs = auth_getprivs((char*)tp->getName());
if (auth_privs2str(privs,buff,256) < 0)
buff[0] = 0;
os<<L"-!- " + narrow_to_wide(buff);
}
void cmd_grantrevoke(std::wostringstream &os,
ServerCommandContext *ctx)
{
char buff[256];
if (ctx->parms.size() != 3) {
os<<L"-!- Missing parameter";
return;
}
if ((ctx->privs & PRIV_PRIVS) == 0) {
os<<L"-!- You don't have permission to do that";
return;
}
uint64_t newprivs = auth_str2privs(const_cast<char*>(wide_to_narrow(ctx->parms[2]).c_str()));
if (newprivs == PRIV_INVALID) {
os<<L"-!- Invalid privileges specified";
return;
}
Player *tp = ctx->env->getPlayer(wide_to_narrow(ctx->parms[1]).c_str());
if (tp == NULL) {
os<<L"-!- No such player";
return;
}
std::string playername = wide_to_narrow(ctx->parms[1]);
uint64_t privs = ctx->server->getPlayerAuthPrivs(playername);
if(ctx->parms[0] == L"grant"){
privs |= newprivs;
actionstream<<ctx->player->getName()<<" grants "
<<wide_to_narrow(ctx->parms[2])<<" to "
<<playername<<std::endl;
std::wstring msg;
msg += narrow_to_wide(ctx->player->getName());
msg += L" granted you the privilege \"";
msg += ctx->parms[2];
msg += L"\"";
ctx->server->notifyPlayer(playername.c_str(), msg);
}else{
privs &= ~newprivs;
actionstream<<ctx->player->getName()<<" revokes "
<<wide_to_narrow(ctx->parms[2])<<" from "
<<playername<<std::endl;
std::wstring msg;
msg += narrow_to_wide(ctx->player->getName());
msg += L" revoked from you the privilege \"";
msg += ctx->parms[2];
msg += L"\"";
ctx->server->notifyPlayer(playername.c_str(), msg);
}
ctx->server->setPlayerAuthPrivs(playername, privs);
os<<L"-!- Privileges change to ";
if (auth_privs2str(privs,buff,256) < 0) {
os<<L"???";
}else{
os<<narrow_to_wide(buff);
}
}
void cmd_time(std::wostringstream &os,
ServerCommandContext *ctx)
{
if(ctx->parms.size() != 2)
{
os<<L"-!- Missing parameter";
return;
}
if((ctx->privs & PRIV_SETTIME) ==0)
{
os<<L"-!- You don't have permission to do that";
return;
}
u32 time = mystoi(wide_to_narrow(ctx->parms[1]));
ctx->server->setTimeOfDay(time);
os<<L"-!- time_of_day changed.";
actionstream<<ctx->player->getName()<<" sets time "
<<time<<std::endl;
}
void cmd_shutdown(std::wostringstream &os,
ServerCommandContext *ctx)
{
if((ctx->privs & PRIV_SERVER) ==0)
{
os<<L"-!- You don't have permission to do that";
return;
}
actionstream<<ctx->player->getName()
<<" shuts down server"<<std::endl;
ctx->server->requestShutdown();
os<<L"*** Server shutting down (operator request)";
ctx->flags |= SEND_TO_OTHERS;
}
void cmd_setting(std::wostringstream &os,
ServerCommandContext *ctx)
{
if ((ctx->privs & PRIV_SERVER) ==0) {
os<<L"-!- You don't have permission to do that";
return;
}
/* no value is set, so instead show the current value */
if (ctx->parms.size() == 2) {
if (!g_settings->exists(wide_to_narrow(ctx->parms[1]))) {
os << L"-!- '" << ctx->parms[1] << L"' is not set";
return;
}
os << L"-!- '" << ctx->parms[1] << L"' has value '"
<< narrow_to_wide(g_settings->get(wide_to_narrow(ctx->parms[1]))) << L"'";
return;
}
/*std::string confline = wide_to_narrow(
ctx->parms[1] + L" = " + ctx->params[2]);*/
std::string confline = wide_to_narrow(ctx->paramstring);
actionstream<<ctx->player->getName()
<<" sets: "<<confline<<std::endl;
g_settings->parseConfigLine(confline);
ctx->server->saveConfig();
os<< L"-!- Setting changed and configuration saved.";
}
void cmd_teleport(std::wostringstream &os,
ServerCommandContext *ctx)
{
if((ctx->privs & PRIV_TELEPORT) ==0)
{
os<<L"-!- You don't have permission to do that";
return;
}
if(ctx->parms.size() != 2)
{
os<<L"-!- Missing parameter";
return;
}
std::vector<std::wstring> coords = str_split(ctx->parms[1], L',');
if(coords.size() != 3)
{
os<<L"-!- You can only specify coordinates currently";
return;
}
v3f dest(mywstoi(coords[0])*10, mywstoi(coords[1])*10, mywstoi(coords[2])*10);
actionstream<<ctx->player->getName()<<" teleports from "
<<PP(ctx->player->getPosition()/BS)<<" to "
<<PP(dest/BS)<<std::endl;
ctx->player->setPosition(dest);
ctx->server->SendMovePlayer(ctx->player);
os<< L"-!- Teleported.";
}
void cmd_banunban(std::wostringstream &os, ServerCommandContext *ctx)
{
if ((ctx->privs & PRIV_BAN) == 0) {
os<<L"-!- You don't have permission to do that";
return;
}
if (ctx->parms.size() < 2) {
std::string desc = ctx->server->getBanDescription("");
os<<L"-!- Ban list: "<<narrow_to_wide(desc);
return;
}
if (ctx->parms[0] == L"ban") {
Player *player = ctx->env->getPlayer(wide_to_narrow(ctx->parms[1]).c_str());
if (player == NULL) {
os<<L"-!- No such player";
return;
}
std::wstring msg;
msg += narrow_to_wide(ctx->player->getName());
msg += L" has banned you from this server.";
ctx->server->notifyPlayer(player->getName(), msg);
try{
Address address = ctx->server->getPeerAddress(player->peer_id);
std::string ip_string = address.serializeString();
ctx->server->setIpBanned(ip_string, player->getName());
os<<L"-!- Banned "<<narrow_to_wide(ip_string)<<L"|"
<<narrow_to_wide(player->getName());
actionstream<<ctx->player->getName()<<" bans "
<<player->getName()<<" / "<<ip_string<<std::endl;
} catch(con::PeerNotFoundException){
std::string ip_string = ((ServerRemotePlayer*)player)->getAddress();
if (ip_string != "") {
ctx->server->setIpBanned(ip_string, player->getName());
os<<L"-!- Banned "<<narrow_to_wide(ip_string)<<L"|"
<<narrow_to_wide(player->getName());
actionstream<<ctx->player->getName()<<" bans "
<<player->getName()<<" / "<<ip_string<<std::endl;
}else{
dstream<<__FUNCTION_NAME<<": peer was not found"<<std::endl;
}
}
}else{
std::string ip_or_name = wide_to_narrow(ctx->parms[1]);
std::string desc = ctx->server->getBanDescription(ip_or_name);
ctx->server->unsetIpBanned(ip_or_name);
os<<L"-!- Unbanned "<<narrow_to_wide(desc);
actionstream<<ctx->player->getName()<<" unbans "
<<ip_or_name<<std::endl;
}
}
void cmd_adduser(std::wostringstream &os,
ServerCommandContext *ctx)
{
if ((ctx->privs & PRIV_BAN) == 0) {
os<<L"-!- You don't have permission to do that";
return;
}
if (ctx->parms.size() != 3) {
os<<L"-!- /adduser <PLAYERNAME> <PASSWORD>";
return;
}
if (ctx->server->userExists(wide_to_narrow(ctx->parms[1]).c_str())) {
os<<L"-!- User already exists!";
return;
}
std::string name = wide_to_narrow(ctx->parms[1]);
std::string pass = translatePassword(name,ctx->parms[2]);
ctx->server->addUser(name.c_str(), pass.c_str());
os<<L"-!- Added user "<<ctx->parms[1];
actionstream<<ctx->player->getName()<<" creates user "
<<wide_to_narrow(ctx->parms[1])<<std::endl;
}
void cmd_clearobjects(std::wostringstream &os,
ServerCommandContext *ctx)
{
if ((ctx->privs & PRIV_SERVER) == 0) {
os<<L"-!- You don't have permission to do that";
return;
}
actionstream<<ctx->player->getName()
<<" clears all objects"<<std::endl;
{
std::wstring msg;
msg += L"Clearing all objects. This may take a long time.";
msg += L" You may experience a timeout. (by ";
msg += narrow_to_wide(ctx->player->getName());
msg += L")";
ctx->server->notifyPlayers(msg);
}
ctx->env->clearAllObjects();
actionstream<<"object clearing done"<<std::endl;
os<<L"*** cleared all objects";
ctx->flags |= SEND_TO_OTHERS;
}
void cmd_setpassword(std::wostringstream &os,
ServerCommandContext *ctx)
{
if ((ctx->privs & PRIV_SERVER) ==0) {
os<<L"-!- You don't have permission to do that";
return;
}
if (ctx->parms.size() != 3) {
os<<L"-!- /setpassword <PLAYERNAME> <PASSWORD>";
return;
}
Player *player = ctx->env->getPlayer(wide_to_narrow(ctx->parms[1]).c_str());
if (player == NULL) {
os<<L"-!- No such player";
return;
}
std::string name = wide_to_narrow(ctx->parms[1]);
std::string pass = translatePassword(name,ctx->parms[2]);
ctx->server->setPlayerPassword(name.c_str(), pass.c_str());
os<<L"-!- Password set for player '";
os<<ctx->parms[1];
os<<L"'";
}
void cmd_help(std::wostringstream &os,
ServerCommandContext *ctx)
{
uint64_t privs = ctx->privs;
if (ctx->parms.size() > 1) {
if ((privs&PRIV_SERVER) == PRIV_SERVER) {
if (ctx->parms[1] == L"shutdown") {
os<<L"-!- /#shutdown - shutdown the server";
return;
}else if (ctx->parms[1] == L"clearobjects") {
os<<L"-!- /clearobjects - remove active objects from the world, may take a long time";
return;
}else if (ctx->parms[1] == L"setting") {
os<<L"-!- /#setting <SETTING> [= VALUE] - change or view a config setting";
return;
}else if (ctx->parms[1] == L"setpassword") {
os<<L"-!- /setpassword <PLAYERNAME> <PASSWORD> - change or set a player's password";
return;
}
}
if ((privs&PRIV_SETTIME) == PRIV_SETTIME && ctx->parms[1] == L"time") {
os<<L"-!- /time <0-23999> - set the game time";
return;
}
if ((privs&PRIV_TELEPORT) == PRIV_TELEPORT && ctx->parms[1] == L"teleport") {
os<<L"-!- /teleport <X>,<Y>,<Z> - teleport to coordinates <X>,<Y>,<Z>";
return;
}
if ((privs&PRIV_PRIVS) == PRIV_PRIVS) {
if (ctx->parms[1] == L"grant") {
os<<L"-!- /grant <PLAYERNAME> <PRIVILEGE> - grant a new privilege to a player";
return;
}else if (ctx->parms[1] == L"revoke") {
os<<L"-!- /revoke <PLAYERNAME> <PRIVILEGE> - remove privilege from a player";
return;
}
}
if ((privs&PRIV_BAN) == PRIV_BAN) {
if (ctx->parms[1] == L"ban") {
os<<L"-!- /ban <PLAYERNAME OR IP ADDRESS> - ban a player from the server";
return;
}else if (ctx->parms[1] == L"unban") {
os<<L"-!- /unban <PLAYERNAME OR IP ADDRESS> - remove a player's ban from the server";
return;
}else if (ctx->parms[1] == L"adduser") {
os<<L"-!- /adduser <PLAYERNAME> <PASSWORD> - add a new player with the specified password";
return;
}
}
if (ctx->parms[1] == L"privs") {
if ((privs&PRIV_PRIVS) == PRIV_PRIVS) {
os<<L"-!- /privs [PLAYERNAME] - view the server privileges of a player";
return;
}
os<<L"-!- /privs - view your server privileges";
return;
}
if (ctx->parms[1] == L"status") {
os<<L"-!- /status - view the server's status and welcome message";
return;
}
if (ctx->parms[1] == L"help") {
os<<L"-!- /help [COMMAND] - get help for a command or a list of commands";
return;
}
}
os<<L"-!- Available commands: ";
os<<L"help status privs";
if ((privs&PRIV_SERVER) == PRIV_SERVER)
os<<L" shutdown setting clearobjects setpassword";
if ((privs&PRIV_SETTIME) == PRIV_SETTIME)
os<<L" time";
if ((privs&PRIV_TELEPORT) == PRIV_TELEPORT)
os<<L" teleport";
if ((privs&PRIV_PRIVS) == PRIV_PRIVS)
os<<L" grant revoke";
if ((privs&PRIV_BAN) == PRIV_BAN)
os<<L" ban unban";
}
std::wstring processServerCommand(ServerCommandContext *ctx)
{
std::wostringstream os(std::ios_base::binary);
ctx->flags = SEND_TO_SENDER; // Default, unless we change it.
if (ctx->parms.size() == 0 || ctx->parms[0] == L"help") {
cmd_help(os,ctx);
}else if (ctx->parms[0] == L"status") {
cmd_status(os, ctx);
}else if(ctx->parms[0] == L"privs") {
cmd_privs(os, ctx);
}else if(ctx->parms[0] == L"grant" || ctx->parms[0] == L"revoke") {
cmd_grantrevoke(os, ctx);
}else if(ctx->parms[0] == L"time") {
cmd_time(os, ctx);
}else if(ctx->parms[0] == L"shutdown") {
cmd_shutdown(os, ctx);
}else if(ctx->parms[0] == L"setting") {
cmd_setting(os, ctx);
}else if(ctx->parms[0] == L"teleport") {
cmd_teleport(os, ctx);
}else if(ctx->parms[0] == L"ban" || ctx->parms[0] == L"unban") {
cmd_banunban(os, ctx);
}else if(ctx->parms[0] == L"adduser") {
cmd_adduser(os, ctx);
}else if(ctx->parms[0] == L"me") {
cmd_me(os, ctx);
}else if(ctx->parms[0] == L"setpassword") {
cmd_setpassword(os, ctx);
}else if(ctx->parms[0] == L"clearobjects") {
cmd_clearobjects(os, ctx);
}else{
os<<L"-!- Invalid command '" + ctx->parms[0] + L"', try /help";
}
return os.str();
}

View File

@ -1,74 +0,0 @@
/************************************************************************
* Minetest-c55
* Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
* Copyright (C) 2011 Ciaran Gultnieks <ciaran@ciarang.com>
*
* servercommand.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 SERVERCOMMAND_HEADER
#define SERVERCOMMAND_HEADER
#include <vector>
#include <sstream>
#include "common_irrlicht.h"
#include "player.h"
#include "server.h"
#define SEND_TO_SENDER (1<<0)
#define SEND_TO_OTHERS (1<<1)
#define SEND_NO_PREFIX (1<<2)
struct ServerCommandContext
{
std::vector<std::wstring> parms;
std::wstring paramstring;
Server* server;
ServerEnvironment *env;
Player* player;
// Effective privs for the player, which may be different to their
// stored ones - e.g. if they are named in the config as an admin.
uint64_t privs;
u32 flags;
ServerCommandContext(
std::vector<std::wstring> parms,
std::wstring paramstring,
Server* server,
ServerEnvironment *env,
Player* player,
uint64_t privs)
: parms(parms), paramstring(paramstring),
server(server), env(env), player(player), privs(privs)
{
}
};
// Process a command sent from a client. The environment and connection
// should be locked when this is called.
// Returns a response message, to be dealt with according to the flags set
// in the context.
std::wstring processServerCommand(ServerCommandContext *ctx);
#endif

View File

@ -23,11 +23,7 @@
* for Voxelands.
************************************************************************/
/*
=============================== NOTES ==============================
*/
#include "common.h"
#ifndef SERVER
#ifdef _WIN32
@ -69,8 +65,6 @@
#include "porting.h"
#include "config.h"
#include "mineral.h"
#include "defaultsettings.h"
#include "settings.h"
#include "profiler.h"
#include "log.h"
// for the init functions
@ -83,13 +77,6 @@
#include "thread.h"
#include "path.h"
/*
Settings.
These are loaded from the config file.
*/
GameSettings main_settings;
GameSettings *g_settings = &main_settings;
// Global profiler
Profiler main_profiler;
Profiler *g_profiler = &main_profiler;
@ -173,10 +160,12 @@ int main(int argc, char *argv[])
porting::signal_handler_init();
bool &kill = *porting::signal_handler_killstatus();
thread_init();
path_init();
command_init();
config_init(argc,argv);
// Initialize debug streams
{
char buff[1024];
@ -204,76 +193,14 @@ int main(int argc, char *argv[])
try
{
/*
Parse command line
*/
// List all allowed options
core::map<std::string, ValueSpec> allowed_options;
allowed_options.insert("help", ValueSpec(VALUETYPE_FLAG));
allowed_options.insert("config", ValueSpec(VALUETYPE_STRING,
"Load configuration from specified file"));
allowed_options.insert("port", ValueSpec(VALUETYPE_STRING));
allowed_options.insert("disable-unittests", ValueSpec(VALUETYPE_FLAG));
allowed_options.insert("enable-unittests", ValueSpec(VALUETYPE_FLAG));
allowed_options.insert("map-dir", ValueSpec(VALUETYPE_STRING));
allowed_options.insert("info-on-stderr", ValueSpec(VALUETYPE_FLAG));
Settings cmd_args;
bool ret = cmd_args.parseCommandLine(argc, argv, allowed_options);
if(ret == false || cmd_args.getFlag("help"))
{
dstream<<"Allowed options:"<<std::endl;
for(core::map<std::string, ValueSpec>::Iterator
i = allowed_options.getIterator();
i.atEnd() == false; i++)
{
dstream<<" --"<<i.getNode()->getKey();
if(i.getNode()->getValue().type == VALUETYPE_FLAG)
{
}
else
{
dstream<<" <value>";
}
dstream<<std::endl;
if(i.getNode()->getValue().help != NULL)
{
dstream<<" "<<i.getNode()->getValue().help
<<std::endl;
}
}
return cmd_args.getFlag("help") ? 0 : 1;
}
if(cmd_args.getFlag("info-on-stderr"))
log_add_output(&main_stderr_log_out, LMT_INFO);
/*
Basic initialization
*/
// Initialize default settings
set_default_settings(g_settings);
// Initialize sockets
sockets_init();
atexit(sockets_cleanup);
/*
Read config file
*/
{
char buff[1024];
if (path_get((char*)"config",(char*)"voxelands.conf",0,buff,1024))
g_settings->readConfigFile(buff);
}
// Initialize random seed
srand(time(0));
mysrand(time(0));
@ -288,15 +215,6 @@ int main(int argc, char *argv[])
init_mapnode();
init_mineral();
/*
Run unit tests
*/
if((ENABLE_TESTS && cmd_args.getFlag("disable-unittests") == false)
|| cmd_args.getFlag("enable-unittests") == true)
{
run_tests();
}
/*
Check parameters
*/
@ -313,26 +231,15 @@ int main(int argc, char *argv[])
std::cout<<std::endl;
// Port?
u16 port = 30000;
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) {
port = g_settings->getU16("port");
}else{
dstream<<"Please specify port (in config or on command line)"
<<std::endl;
}
/* TODO: configise this */
path_world_setter((char*)"default");
// Create server
Server server;
server.start(port);
server.start();
HTTPServer http_server(server);
if (g_settings->getBool("enable_http"))
http_server.start(port);
if (config_get_bool("server.net.http"))
http_server.start();
// Run server
dedicated_server_loop(server, kill);

View File

@ -1,731 +0,0 @@
/************************************************************************
* Minetest-c55
* Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
*
* settings.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 SETTINGS_HEADER
#define SETTINGS_HEADER
#include "common_irrlicht.h"
#include <string>
#include <jthread.h>
#include <jmutex.h>
#include <jmutexautolock.h>
#include "strfnd.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include "debug.h"
#include "utility.h"
#include "log.h"
enum ValueType
{
VALUETYPE_STRING,
VALUETYPE_FLAG // Doesn't take any arguments
};
struct ValueSpec
{
ValueSpec(ValueType a_type, const char *a_help=NULL)
{
type = a_type;
help = a_help;
}
ValueType type;
const char *help;
};
using namespace jthread;
class Settings
{
public:
Settings()
{
m_mutex.Init();
}
void writeLines(std::ostream &os)
{
JMutexAutoLock lock(m_mutex);
for(core::map<std::string, std::string>::Iterator
i = m_settings.getIterator();
i.atEnd() == false; i++)
{
std::string name = i.getNode()->getKey();
std::string value = i.getNode()->getValue();
os<<name<<" = "<<value<<"\n";
}
}
virtual bool parseConfigLine(const std::string &line)
{
JMutexAutoLock lock(m_mutex);
std::string trimmedline = trim(line);
// Ignore comments
if(trimmedline[0] == '#')
return true;
//infostream<<"trimmedline=\""<<trimmedline<<"\""<<std::endl;
Strfnd sf(trim(line));
std::string name = sf.next("=");
name = trim(name);
if(name == "")
return true;
std::string value = sf.next("\n");
value = trim(value);
/*infostream<<"Config name=\""<<name<<"\" value=\""
<<value<<"\""<<std::endl;*/
m_settings[name] = value;
return true;
}
void parseConfigLines(std::istream &is, const std::string &endstring)
{
for(;;){
if(is.eof())
break;
std::string line;
std::getline(is, line);
std::string trimmedline = trim(line);
if(endstring != ""){
if(trimmedline == endstring)
break;
}
parseConfigLine(line);
}
}
// Returns false on EOF
bool parseConfigObject(std::istream &is)
{
if(is.eof())
return false;
/*
NOTE: This function might be expanded to allow multi-line
settings.
*/
std::string line;
std::getline(is, line);
//infostream<<"got line: \""<<line<<"\""<<std::endl;
return parseConfigLine(line);
}
/*
Read configuration file
Returns true on success
*/
bool readConfigFile(const char *filename)
{
std::ifstream is(filename);
if(is.good() == false)
{
errorstream<<"Error opening configuration file \""
<<filename<<"\""<<std::endl;
return false;
}
infostream<<"Parsing configuration file: \""
<<filename<<"\""<<std::endl;
while(parseConfigObject(is));
return true;
}
/*
Reads a configuration object from stream (usually a single line)
and adds it to dst.
Preserves comments and empty lines.
Settings that were added to dst are also added to updated.
key of updated is setting name, value of updated is dummy.
Returns false on EOF
*/
bool getUpdatedConfigObject(std::istream &is,
core::list<std::string> &dst,
core::map<std::string, bool> &updated)
{
JMutexAutoLock lock(m_mutex);
if(is.eof())
return false;
// NOTE: This function will be expanded to allow multi-line settings
std::string line;
std::getline(is, line);
std::string trimmedline = trim(line);
std::string line_end = "";
if(is.eof() == false)
line_end = "\n";
// Ignore comments
if(trimmedline[0] == '#')
{
dst.push_back(line+line_end);
return true;
}
Strfnd sf(trim(line));
std::string name = sf.next("=");
name = trim(name);
if(name == "")
{
dst.push_back(line+line_end);
return true;
}
std::string value = sf.next("\n");
value = trim(value);
if(m_settings.find(name))
{
std::string newvalue = m_settings[name];
if(newvalue != value)
{
infostream<<"Changing value of \""<<name<<"\" = \""
<<value<<"\" -> \""<<newvalue<<"\""
<<std::endl;
}
dst.push_back(name + " = " + newvalue + line_end);
updated[name] = true;
}
return true;
}
/*
Updates configuration file
Returns true on success
*/
bool updateConfigFile(const char *filename)
{
infostream<<"Updating configuration file: \""
<<filename<<"\""<<std::endl;
core::list<std::string> objects;
core::map<std::string, bool> updated;
// Read and modify stuff
{
std::ifstream is(filename);
if(is.good() == false)
{
infostream<<"updateConfigFile():"
" Error opening configuration file"
" for reading: \""
<<filename<<"\""<<std::endl;
}
else
{
while(getUpdatedConfigObject(is, objects, updated));
}
}
JMutexAutoLock lock(m_mutex);
// Write stuff back
{
std::ofstream os(filename);
if(os.good() == false)
{
errorstream<<"Error opening configuration file"
" for writing: \""
<<filename<<"\""<<std::endl;
return false;
}
/*
Write updated stuff
*/
for(core::list<std::string>::Iterator
i = objects.begin();
i != objects.end(); i++)
{
os<<(*i);
}
/*
Write stuff that was not already in the file
*/
for(core::map<std::string, std::string>::Iterator
i = m_settings.getIterator();
i.atEnd() == false; i++)
{
if(updated.find(i.getNode()->getKey()))
continue;
std::string name = i.getNode()->getKey();
std::string value = i.getNode()->getValue();
infostream<<"Adding \""<<name<<"\" = \""<<value<<"\""
<<std::endl;
os<<name<<" = "<<value<<"\n";
}
}
return true;
}
/*
NOTE: Types of allowed_options are ignored
returns true on success
*/
bool parseCommandLine(int argc, char *argv[],
core::map<std::string, ValueSpec> &allowed_options)
{
int i=1;
for(;;)
{
if(i >= argc)
break;
std::string argname = argv[i];
if(argname.substr(0, 2) != "--")
{
errorstream<<"Invalid command-line parameter \""
<<argname<<"\": --<option> expected."<<std::endl;
return false;
}
i++;
std::string name = argname.substr(2);
core::map<std::string, ValueSpec>::Node *n;
n = allowed_options.find(name);
if(n == NULL)
{
errorstream<<"Unknown command-line parameter \""
<<argname<<"\""<<std::endl;
return false;
}
ValueType type = n->getValue().type;
std::string value = "";
if(type == VALUETYPE_FLAG)
{
value = "true";
}
else
{
if(i >= argc)
{
errorstream<<"Invalid command-line parameter \""
<<name<<"\": missing value"<<std::endl;
return false;
}
value = argv[i];
i++;
}
infostream<<"Valid command-line parameter: \""
<<name<<"\" = \""<<value<<"\""
<<std::endl;
set(name, value);
}
return true;
}
virtual void set(std::string name, std::string value)
{
JMutexAutoLock lock(m_mutex);
m_settings[name] = value;
}
virtual void set(std::string name, const char *value)
{
JMutexAutoLock lock(m_mutex);
m_settings[name] = value;
}
void setDefault(std::string name, std::string value)
{
JMutexAutoLock lock(m_mutex);
m_defaults[name] = value;
}
bool exists(std::string name)
{
JMutexAutoLock lock(m_mutex);
return (m_settings.find(name) || m_defaults.find(name));
}
std::string get(std::string name)
{
JMutexAutoLock lock(m_mutex);
core::map<std::string, std::string>::Node *n;
n = m_settings.find(name);
if(n == NULL)
{
n = m_defaults.find(name);
if(n == NULL)
{
infostream<<"Settings: Setting not found: \""
<<name<<"\""<<std::endl;
throw SettingNotFoundException("Setting not found");
}
}
return n->getValue();
}
bool getBool(std::string name)
{
return is_yes(get(name));
}
bool getFlag(std::string name)
{
try
{
return getBool(name);
}
catch(SettingNotFoundException &e)
{
return false;
}
}
// Asks if empty
bool getBoolAsk(std::string name, std::string question, bool def)
{
// If it is in settings
if(exists(name))
return getBool(name);
std::string s;
char templine[10];
std::cout<<question<<" [y/N]: ";
std::cin.getline(templine, 10);
s = templine;
if(s == "")
return def;
return is_yes(s);
}
float getFloat(std::string name)
{
return mystof(get(name));
}
u16 getU16(std::string name)
{
return mystoi(get(name), 0, 65535);
}
u16 getU16Ask(std::string name, std::string question, u16 def)
{
// If it is in settings
if(exists(name))
return getU16(name);
std::string s;
char templine[10];
std::cout<<question<<" ["<<def<<"]: ";
std::cin.getline(templine, 10);
s = templine;
if(s == "")
return def;
return mystoi(s, 0, 65535);
}
s16 getS16(std::string name)
{
return mystoi(get(name), -32768, 32767);
}
s32 getS32(std::string name)
{
return mystoi(get(name));
}
v3f getV3F(std::string name)
{
v3f value;
Strfnd f(get(name));
f.next("(");
value.X = mystof(f.next(","));
value.Y = mystof(f.next(","));
value.Z = mystof(f.next(")"));
return value;
}
v2f getV2F(std::string name)
{
v2f value;
Strfnd f(get(name));
f.next("(");
value.X = mystof(f.next(","));
value.Y = mystof(f.next(")"));
return value;
}
uint64_t getU64(std::string name)
{
uint64_t value = 0;
std::string s = get(name);
std::istringstream ss(s);
ss>>value;
return value;
}
void setBool(std::string name, bool value)
{
if(value)
set(name, "true");
else
set(name, "false");
}
void setS32(std::string name, s32 value)
{
set(name, itos(value));
}
void setFloat(std::string name, float value)
{
set(name, ftos(value));
}
void setV3F(std::string name, v3f value)
{
std::ostringstream os;
os<<"("<<value.X<<","<<value.Y<<","<<value.Z<<")";
set(name, os.str());
}
void setV2F(std::string name, v2f value)
{
std::ostringstream os;
os<<"("<<value.X<<","<<value.Y<<")";
set(name, os.str());
}
void setU64(std::string name, uint64_t value)
{
std::ostringstream os;
os<<value;
set(name, os.str());
}
void clear()
{
JMutexAutoLock lock(m_mutex);
m_settings.clear();
m_defaults.clear();
}
void updateValue(Settings &other, const std::string &name)
{
JMutexAutoLock lock(m_mutex);
if(&other == this)
return;
try{
std::string val = other.get(name);
m_settings[name] = val;
} catch(SettingNotFoundException &e){
}
return;
}
void update(Settings &other)
{
JMutexAutoLock lock(m_mutex);
JMutexAutoLock lock2(other.m_mutex);
if(&other == this)
return;
for(core::map<std::string, std::string>::Iterator
i = other.m_settings.getIterator();
i.atEnd() == false; i++)
{
m_settings[i.getNode()->getKey()] = i.getNode()->getValue();
}
for(core::map<std::string, std::string>::Iterator
i = other.m_defaults.getIterator();
i.atEnd() == false; i++)
{
m_defaults[i.getNode()->getKey()] = i.getNode()->getValue();
}
return;
}
Settings & operator+=(Settings &other)
{
JMutexAutoLock lock(m_mutex);
JMutexAutoLock lock2(other.m_mutex);
if(&other == this)
return *this;
for(core::map<std::string, std::string>::Iterator
i = other.m_settings.getIterator();
i.atEnd() == false; i++)
{
m_settings.insert(i.getNode()->getKey(),
i.getNode()->getValue());
}
for(core::map<std::string, std::string>::Iterator
i = other.m_defaults.getIterator();
i.atEnd() == false; i++)
{
m_defaults.insert(i.getNode()->getKey(),
i.getNode()->getValue());
}
return *this;
}
Settings & operator=(Settings &other)
{
JMutexAutoLock lock(m_mutex);
JMutexAutoLock lock2(other.m_mutex);
if(&other == this)
return *this;
clear();
(*this) += other;
return *this;
}
protected:
core::map<std::string, std::string> m_settings;
// All methods that access m_settings/m_defaults directly should lock this.
JMutex m_mutex;
private:
core::map<std::string, std::string> m_defaults;
};
class GameSettings : public Settings
{
public:
GameSettings()
{
Settings();
}
// you'll find this in defaultsettings.cpp
void setGameDefaults(std::string mode);
virtual bool parseConfigLine(const std::string &line)
{
std::string name;
std::string value;
{
JMutexAutoLock lock(m_mutex);
std::string trimmedline = trim(line);
// Ignore comments
if (trimmedline[0] == '#')
return true;
Strfnd sf(trimmedline);
name = sf.next("=");
name = trim(name);
if (name == "")
return true;
value = sf.next("\n");
value = trim(value);
m_settings[name] = value;
}
if (name == "game_mode")
setGameDefaults(value);
return true;
}
virtual void set(std::string name, std::string value)
{
{
JMutexAutoLock lock(m_mutex);
m_settings[name] = value;
}
if (name == "game_mode")
setGameDefaults(value);
}
virtual void set(std::string name, const char *value)
{
{
JMutexAutoLock lock(m_mutex);
m_settings[name] = value;
}
if (name == "game_mode")
setGameDefaults(value);
}
};
#endif

View File

@ -29,6 +29,8 @@
#ifndef SERVER
#include "common.h"
#include "sound_openal.h"
#if defined(_MSC_VER)
@ -49,7 +51,6 @@
#include <vector>
#include "utility.h" // myrand()
#include "path.h"
#include "settings.h"
#include "main.h"
#define BUFFER_SIZE 30000
@ -258,7 +259,7 @@ public:
alDistanceModel(AL_EXPONENT_DISTANCE);
{
f32 volume = g_settings->getFloat("sound_volume");
float volume = config_get_float("client.sound.volume");
if (volume < 1.0)
return;
if (volume > 100.0)

View File

@ -30,7 +30,6 @@
#include <string>
#include <sstream>
#include "utility.h"
#include "settings.h"
#include "main.h"
#include <list>
@ -101,7 +100,6 @@ public:
}
void deSerialize(std::istream &is)
{
bool drop = g_settings->getBool("onload_ignore_objects");
char buf[12];
// version
is.read(buf, 1);
@ -112,8 +110,6 @@ public:
for (u16 i=0; i<count; i++) {
StaticObject s_obj;
s_obj.deSerialize(is, version);
if (!drop)
m_objects.push_back(s_obj);
}
}

200
src/string.c Normal file
View File

@ -0,0 +1,200 @@
/************************************************************************
* string.c
* voxelands - 3d voxel world sandbox game
* Copyright (C) Lisa 'darkrose' Milne 2016 <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/>
************************************************************************/
#include "common.h"
#define VLCRYPTO_EXPOSE_LIBRARY_FUNCTIONS
#include "crypto.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/* remove whitespace from beginning and end of a string */
char* trim(char* str)
{
int l;
while (*str && isspace(*str)) {
str++;
}
l = strlen(str);
while (--l > -1 && (!str[l] || isspace(str[l]))) {
str[l] = 0;
}
return str;
}
/* allocate memory and copy a string *
char* strdup(const char* str)
{
char* r;
int l;
if (!str)
return NULL;
l = strlen(str);
l++;
r = malloc(l);
if (!r)
return NULL;
if (!memcpy(r,str,l)) {
free(r);
return NULL;
}
return r;
}*/
/* append str to dest, only if there's room for all of it */
int strappend(char* dest, int size, char* str)
{
int l;
l = strlen(dest);
l += strlen(str);
if (l >= size)
return 0;
strcat(dest,str);
return l;
}
/* makes a string safe for use as a file or directory name */
int str_sanitise(char* dest, int size, char* str)
{
int o = 0;
int i = 0;
int lws = 0;
for (; o<size; i++) {
if (!str[i]) {
dest[o] = 0;
return o;
}
if (isalnum(str[i])) {
lws = 0;
dest[o++] = str[i];
}else if (!lws) {
dest[o++] = '_';
lws = 1;
}
}
return -1;
}
/* parse a string into a bool true/false 1/0 */
int parse_bool(char* str)
{
if (str) {
if (!strcmp(str,"true"))
return 1;
if (!strcmp(str,"yes"))
return 1;
if (!strcmp(str,"on"))
return 1;
if (!strcmp(str,"enabled"))
return 1;
if (!strcmp(str,"active"))
return 1;
if (strtol(str,NULL,10))
return 1;
}
return 0;
}
/* parse a string to a v3_t */
int str_tov3t(char* str, v3_t *v)
{
char buff[256];
char* b;
char* s1;
char* s2;
char *e;
if (!str)
return 1;
strncpy(buff,str,256);
b = strchr(buff,'(');
if (!b)
return 1;
b++;
s1 = strchr(b,',');
if (!s1)
return 1;
*s1 = 0;
s1++;
s2 = strchr(s1,',');
if (!s2)
return 1;
*s2 = 0;
s2++;
e = strchr(s2,')');
if (!e)
return 1;
*e = 0;
v->x = strtof(b,NULL);
v->y = strtof(s1,NULL);
v->z = strtof(s2,NULL);
return 0;
}
int str_topwd(char* name, char* pass, char* buff, int size)
{
char b1[256];
unsigned char b2[20];
if (!buff || size < 28)
return 1;
if (!name || !name[0]) {
buff[0] = 0;
return 0;
}
if (!pass || !pass[0]) {
buff[0] = 0;
return 0;
}
if (snprintf(b1,256,"%s%s",name,pass) >= 256)
return 1;
if (sha1(b1,b2))
return 1;
if (!base64_lencode((char*)b2,20,buff,size))
return 1;
return 0;
}

View File

@ -38,7 +38,6 @@
#include "porting.h"
#include "content_mapnode.h"
#include "mapsector.h"
#include "settings.h"
#include "log.h"
/*
@ -70,38 +69,6 @@ struct TestUtilities
}
};
struct TestSettings
{
void Run()
{
Settings s;
// Test reading of settings
s.parseConfigLine("leet = 1337");
s.parseConfigLine("leetleet = 13371337");
s.parseConfigLine("leetleet_neg = -13371337");
s.parseConfigLine("floaty_thing = 1.1");
s.parseConfigLine("stringy_thing = asd /( ¤%&(/\" BLÖÄRP");
s.parseConfigLine("coord = (1, 2, 4.5)");
assert(s.getS32("leet") == 1337);
assert(s.getS16("leetleet") == 32767);
assert(s.getS16("leetleet_neg") == -32768);
// Not sure if 1.1 is an exact value as a float, but doesn't matter
assert(fabs(s.getFloat("floaty_thing") - 1.1) < 0.001);
assert(s.get("stringy_thing") == "asd /( ¤%&(/\" BLÖÄRP");
assert(fabs(s.getV3F("coord").X - 1.0) < 0.001);
assert(fabs(s.getV3F("coord").Y - 2.0) < 0.001);
assert(fabs(s.getV3F("coord").Z - 4.5) < 0.001);
// Test the setting of settings too
s.setFloat("floaty_thing_2", 1.2);
s.setV3F("coord2", v3f(1, 2, 3.3));
assert(s.get("floaty_thing_2").substr(0,3) == "1.2");
assert(fabs(s.getFloat("floaty_thing_2") - 1.2) < 0.001);
assert(fabs(s.getV3F("coord2").X - 1.0) < 0.001);
assert(fabs(s.getV3F("coord2").Y - 2.0) < 0.001);
assert(fabs(s.getV3F("coord2").Z - 3.3) < 0.001);
}
};
struct TestCompress
{
void Run()
@ -1154,7 +1121,6 @@ void run_tests()
DSTACK(__FUNCTION_NAME);
infostream<<"run_tests() started"<<std::endl;
TEST(TestUtilities);
TEST(TestSettings);
TEST(TestCompress);
TEST(TestMapNode);
TEST(TestVoxelManipulator);

View File

@ -23,12 +23,13 @@
* for Voxelands.
************************************************************************/
#include "common.h"
#include "tile.h"
#include "debug.h"
#include "main.h" // for g_settings
#include "game.h"
#include "utility.h"
#include "settings.h"
#include "mesh.h"
#include "hex.h"
#include <ICameraSceneNode.h>
@ -57,10 +58,8 @@ TextureSource::TextureSource(IrrlichtDevice *device):
m_name_to_id[""] = 0;
// Build main texture atlas
if(g_settings->getBool("enable_texture_atlas"))
if (config_get_bool("client.graphics.texture.atlas"))
buildMainAtlas();
else
infostream<<"Not building texture atlas."<<std::endl;
}
TextureSource::~TextureSource()

View File

@ -259,23 +259,18 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
return true;
}
// Get an sha-1 hash of the player's name combined with
// the password entered. That's what the server uses as
// their password. (Exception : if the password field is
// blank, we send a blank password - this is for backwards
// compatibility with password-less players).
#include "common.h"
std::string translatePassword(std::string playername, std::wstring password)
{
if(password.length() == 0)
char buff[256];
if (password.length() == 0)
return "";
std::string slt = playername + wide_to_narrow(password);
SHA1 sha1;
sha1.addBytes(slt.c_str(), slt.length());
unsigned char *digest = sha1.getDigest();
std::string pwd = base64_encode(digest, 20);
free(digest);
return pwd;
if (str_topwd((char*)playername.c_str(), (char*)password.c_str(),buff,256))
return "";
return std::string(buff);
}