aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client.cpp11
-rw-r--r--src/client.h15
-rw-r--r--src/environment.cpp9
-rw-r--r--src/environment.h4
-rw-r--r--src/inventory.h2
-rw-r--r--src/main.cpp5
-rw-r--r--src/main.h16
-rw-r--r--src/map.cpp20
-rw-r--r--src/map.h17
-rw-r--r--src/mapblock.cpp111
-rw-r--r--src/mapblock.h40
-rw-r--r--src/mapblockobject.h19
-rw-r--r--src/mapsector.cpp2
-rw-r--r--src/mapsector.h2
-rw-r--r--src/player.cpp9
-rw-r--r--src/player.h24
-rw-r--r--src/server.cpp2
-rw-r--r--src/servermain.cpp421
18 files changed, 626 insertions, 103 deletions
diff --git a/src/client.cpp b/src/client.cpp
index b4871ff61..37482ba91 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -70,10 +70,17 @@ void * ClientUpdateThread::Thread()
return NULL;
}
-Client::Client(IrrlichtDevice *device,
- const char *playername):
+Client::Client(
+ IrrlichtDevice *device,
+ const char *playername,
+ JMutex &range_mutex,
+ s16 &viewing_range_nodes,
+ bool &viewing_range_all):
m_thread(this),
m_env(new ClientMap(this,
+ range_mutex,
+ viewing_range_nodes,
+ viewing_range_all,
device->getSceneManager()->getRootSceneNode(),
device->getSceneManager(), 666),
dout_client),
diff --git a/src/client.h b/src/client.h
index 18aa619c6..4720bd720 100644
--- a/src/client.h
+++ b/src/client.h
@@ -20,6 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef CLIENT_HEADER
#define CLIENT_HEADER
+#ifndef SERVER
+
#include "connection.h"
#include "environment.h"
#include "common_irrlicht.h"
@@ -137,7 +139,14 @@ public:
/*
NOTE: Every public method should be thread-safe
*/
- Client(IrrlichtDevice *device, const char *playername);
+ Client(
+ IrrlichtDevice *device,
+ const char *playername,
+ JMutex &range_mutex,
+ s16 &viewing_range_nodes,
+ bool &viewing_range_all
+ );
+
~Client();
/*
The name of the local player should already be set when
@@ -290,5 +299,7 @@ private:
//u32 m_daynight_ratio;
};
-#endif
+#endif // !SERVER
+
+#endif // !CLIENT_HEADER
diff --git a/src/environment.cpp b/src/environment.cpp
index bb2d168ed..386eb124d 100644
--- a/src/environment.cpp
+++ b/src/environment.cpp
@@ -149,7 +149,7 @@ void Environment::step(float dtime)
{
n.d = CONTENT_GRASS_FOOTSTEPS;
m_map->setNode(bottompos, n);
-
+#ifndef SERVER
// Update mesh on client
if(m_map->mapType() == MAPTYPE_CLIENT)
{
@@ -157,6 +157,7 @@ void Environment::step(float dtime)
MapBlock *b = m_map->getBlockNoCreate(p_blocks);
b->updateMesh(m_daynight_ratio);
}
+#endif
}
}
catch(InvalidPositionException &e)
@@ -179,7 +180,9 @@ void Environment::addPlayer(Player *player)
{
DSTACK(__FUNCTION_NAME);
//Check that only one local player exists and peer_ids are unique
+#ifndef SERVER
assert(player->isLocal() == false || getLocalPlayer() == NULL);
+#endif
assert(getPlayer(player->peer_id) == NULL);
m_players.push_back(player);
}
@@ -203,6 +206,7 @@ re_search:
}
}
+#ifndef SERVER
LocalPlayer * Environment::getLocalPlayer()
{
for(core::list<Player*>::Iterator i = m_players.begin();
@@ -214,6 +218,7 @@ LocalPlayer * Environment::getLocalPlayer()
}
return NULL;
}
+#endif
Player * Environment::getPlayer(u16 peer_id)
{
@@ -243,6 +248,7 @@ void Environment::printPlayers(std::ostream &o)
}
}
+#ifndef SERVER
void Environment::updateMeshes(v3s16 blockpos)
{
m_map->updateMeshes(blockpos, m_daynight_ratio);
@@ -252,6 +258,7 @@ void Environment::expireMeshes(bool only_daynight_diffed)
{
m_map->expireMeshes(only_daynight_diffed);
}
+#endif
void Environment::setDayNightRatio(u32 r)
{
diff --git a/src/environment.h b/src/environment.h
index 4b18d6b73..f6ee2ceee 100644
--- a/src/environment.h
+++ b/src/environment.h
@@ -55,13 +55,17 @@ public:
*/
void addPlayer(Player *player);
void removePlayer(u16 peer_id);
+#ifndef SERVER
LocalPlayer * getLocalPlayer();
+#endif
Player * getPlayer(u16 peer_id);
core::list<Player*> getPlayers();
void printPlayers(std::ostream &o);
+#ifndef SERVER
void updateMeshes(v3s16 blockpos);
void expireMeshes(bool only_daynight_diffed);
+#endif
void setDayNightRatio(u32 r);
u32 getDayNightRatio();
diff --git a/src/inventory.h b/src/inventory.h
index 50f3247c3..cb5b54851 100644
--- a/src/inventory.h
+++ b/src/inventory.h
@@ -84,6 +84,7 @@ public:
{
return new MaterialItem(m_content, m_count);
}
+#ifndef SERVER
video::ITexture * getImage()
{
/*if(m_content == CONTENT_TORCH)
@@ -97,6 +98,7 @@ public:
return g_texturecache.get(g_content_inventory_textures[m_content]);
}
+#endif
std::string getText()
{
std::ostringstream os;
diff --git a/src/main.cpp b/src/main.cpp
index 6d470f73d..b747da66a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1509,7 +1509,10 @@ int main(int argc, char *argv[])
Create client
*/
- Client client(device, playername);
+ Client client(device, playername,
+ g_range_mutex,
+ g_viewing_range_nodes,
+ g_viewing_range_all);
Address connect_address(0,0,0,0, port);
try{
diff --git a/src/main.h b/src/main.h
index 6a4b5a090..98af41249 100644
--- a/src/main.h
+++ b/src/main.h
@@ -26,11 +26,6 @@ extern std::string getTimestamp();
#include <jmutex.h>
-extern JMutex g_range_mutex;
-extern s16 g_viewing_range_nodes;
-//extern s16 g_actual_viewing_range_nodes;
-extern bool g_viewing_range_all;
-
// Settings
extern Settings g_settings;
@@ -51,13 +46,10 @@ extern std::ostream *derr_server_ptr;
#define dout_server (*dout_server_ptr)
#define derr_server (*derr_server_ptr)
-// TODO: Move somewhere else? materials.h?
-// This header is only for MATERIALS_COUNT
-//#include "mapnode.h"
-//extern video::SMaterial g_materials[MATERIALS_COUNT];
-
-#include "utility.h"
-extern TextureCache g_texturecache;
+#ifndef SERVER
+ #include "utility.h"
+ extern TextureCache g_texturecache;
+#endif
extern IrrlichtDevice *g_device;
diff --git a/src/map.cpp b/src/map.cpp
index 671e74edd..db9d4120e 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -1062,6 +1062,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
}
}
+#ifndef SERVER
void Map::expireMeshes(bool only_daynight_diffed)
{
TimeTaker timer("expireMeshes()", g_device);
@@ -1128,6 +1129,8 @@ void Map::updateMeshes(v3s16 blockpos, u32 daynight_ratio)
catch(InvalidPositionException &e){}
}
+#endif
+
bool Map::dayNightDiffed(v3s16 blockpos)
{
try{
@@ -2678,12 +2681,17 @@ void ServerMap::PrintInfo(std::ostream &out)
out<<"ServerMap: ";
}
+#ifndef SERVER
+
/*
ClientMap
*/
ClientMap::ClientMap(
Client *client,
+ JMutex &range_mutex,
+ s16 &viewing_range_nodes,
+ bool &viewing_range_all,
scene::ISceneNode* parent,
scene::ISceneManager* mgr,
s32 id
@@ -2691,7 +2699,10 @@ ClientMap::ClientMap(
Map(dout_client),
scene::ISceneNode(parent, mgr, id),
m_client(client),
- mesh(NULL)
+ mesh(NULL),
+ m_range_mutex(range_mutex),
+ m_viewing_range_nodes(viewing_range_nodes),
+ m_viewing_range_all(viewing_range_all)
{
mesh_mutex.Init();
@@ -2805,9 +2816,9 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
s16 viewing_range_nodes;
bool viewing_range_all;
{
- JMutexAutoLock lock(g_range_mutex);
- viewing_range_nodes = g_viewing_range_nodes;
- viewing_range_all = g_viewing_range_all;
+ JMutexAutoLock lock(m_range_mutex);
+ viewing_range_nodes = m_viewing_range_nodes;
+ viewing_range_all = m_viewing_range_all;
}
m_camera_mutex.Lock();
@@ -3042,6 +3053,7 @@ void ClientMap::PrintInfo(std::ostream &out)
out<<"ClientMap: ";
}
+#endif // !SERVER
/*
MapVoxelManipulator
diff --git a/src/map.h b/src/map.h
index d04d647e6..581708a36 100644
--- a/src/map.h
+++ b/src/map.h
@@ -376,13 +376,15 @@ public:
void removeNodeAndUpdate(v3s16 p,
core::map<v3s16, MapBlock*> &modified_blocks);
+#ifndef SERVER
+ void expireMeshes(bool only_daynight_diffed);
+
/*
Updates the faces of the given block and blocks on the
leading edge.
*/
void updateMeshes(v3s16 blockpos, u32 daynight_ratio);
-
- void expireMeshes(bool only_daynight_diffed);
+#endif
/*
Takes the blocks at the trailing edges into account
@@ -535,6 +537,8 @@ private:
bool m_map_saving_enabled;
};
+#ifndef SERVER
+
class Client;
class ClientMap : public Map, public scene::ISceneNode
@@ -542,6 +546,9 @@ class ClientMap : public Map, public scene::ISceneNode
public:
ClientMap(
Client *client,
+ JMutex &range_mutex,
+ s16 &viewing_range_nodes,
+ bool &viewing_range_all,
scene::ISceneNode* parent,
scene::ISceneManager* mgr,
s32 id
@@ -600,8 +607,14 @@ private:
// This is the master heightmap mesh
scene::SMesh *mesh;
JMutex mesh_mutex;
+
+ JMutex &m_range_mutex;
+ s16 &m_viewing_range_nodes;
+ bool &m_viewing_range_all;
};
+#endif
+
class MapVoxelManipulator : public VoxelManipulator
{
public:
diff --git a/src/mapblock.cpp b/src/mapblock.cpp
index 7e23d295b..9372c8fb1 100644
--- a/src/mapblock.cpp
+++ b/src/mapblock.cpp
@@ -34,7 +34,6 @@ MapBlock::MapBlock(NodeContainer *parent, v3s16 pos, bool dummy):
m_pos(pos),
changed(true),
is_underground(false),
- m_mesh_expired(false),
m_day_night_differs(false),
m_objects(this)
{
@@ -42,17 +41,16 @@ MapBlock::MapBlock(NodeContainer *parent, v3s16 pos, bool dummy):
if(dummy == false)
reallocate();
+#ifndef SERVER
+ m_mesh_expired = false;
mesh_mutex.Init();
-
mesh = NULL;
- /*for(s32 i=0; i<DAYNIGHT_CACHE_COUNT; i++)
- {
- mesh[i] = NULL;
- }*/
+#endif
}
MapBlock::~MapBlock()
{
+#ifndef SERVER
{
JMutexAutoLock lock(mesh_mutex);
@@ -61,15 +59,8 @@ MapBlock::~MapBlock()
mesh->drop();
mesh = NULL;
}
- /*for(s32 i=0; i<DAYNIGHT_CACHE_COUNT; i++)
- {
- if(mesh[i] != NULL)
- {
- mesh[i]->drop();
- mesh[i] = NULL;
- }
- }*/
}
+#endif
if(data)
delete[] data;
@@ -136,6 +127,52 @@ MapNode MapBlock::getNodeParentNoEx(v3s16 p)
}
}
+/*
+ Parameters must consist of air and !air.
+ Order doesn't matter.
+
+ If either of the nodes doesn't exist, light is 0.
+
+ parameters:
+ daynight_ratio: 0...1000
+ n: getNodeParent(p)
+ n2: getNodeParent(p + face_dir)
+ face_dir: axis oriented unit vector from p to p2
+*/
+u8 MapBlock::getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
+ v3s16 face_dir)
+{
+ try{
+ u8 light;
+ u8 l1 = n.getLightBlend(daynight_ratio);
+ u8 l2 = n2.getLightBlend(daynight_ratio);
+ if(l1 > l2)
+ light = l1;
+ else
+ light = l2;
+
+ // Make some nice difference to different sides
+
+ /*if(face_dir.X == 1 || face_dir.Z == 1 || face_dir.Y == -1)
+ light = diminish_light(diminish_light(light));
+ else if(face_dir.X == -1 || face_dir.Z == -1)
+ light = diminish_light(light);*/
+
+ if(face_dir.X == 1 || face_dir.X == -1 || face_dir.Y == -1)
+ light = diminish_light(diminish_light(light));
+ else if(face_dir.Z == 1 || face_dir.Z == -1)
+ light = diminish_light(light);
+
+ return light;
+ }
+ catch(InvalidPositionException &e)
+ {
+ return 0;
+ }
+}
+
+#ifndef SERVER
+
void MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
v3s16 dir, v3f scale, v3f posRelative_f,
core::array<FastFace> &dest)
@@ -230,50 +267,6 @@ void MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
}
/*
- Parameters must consist of air and !air.
- Order doesn't matter.
-
- If either of the nodes doesn't exist, light is 0.
-
- parameters:
- daynight_ratio: 0...1000
- n: getNodeParent(p)
- n2: getNodeParent(p + face_dir)
- face_dir: axis oriented unit vector from p to p2
-*/
-u8 MapBlock::getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
- v3s16 face_dir)
-{
- try{
- u8 light;
- u8 l1 = n.getLightBlend(daynight_ratio);
- u8 l2 = n2.getLightBlend(daynight_ratio);
- if(l1 > l2)
- light = l1;
- else
- light = l2;
-
- // Make some nice difference to different sides
-
- /*if(face_dir.X == 1 || face_dir.Z == 1 || face_dir.Y == -1)
- light = diminish_light(diminish_light(light));
- else if(face_dir.X == -1 || face_dir.Z == -1)
- light = diminish_light(light);*/
-
- if(face_dir.X == 1 || face_dir.X == -1 || face_dir.Y == -1)
- light = diminish_light(diminish_light(light));
- else if(face_dir.Z == 1 || face_dir.Z == -1)
- light = diminish_light(light);
-
- return light;
- }
- catch(InvalidPositionException &e)
- {
- return 0;
- }
-}
-
-/*
Gets node tile from any place relative to block.
Returns TILE_NODE if doesn't exist or should not be drawn.
*/
@@ -844,6 +837,8 @@ void MapBlock::updateMesh(u32 daynight_ratio)
}
}*/
+#endif // !SERVER
+
/*
Propagates sunlight down through the block.
Doesn't modify nodes that are not affected by sunlight.
diff --git a/src/mapblock.h b/src/mapblock.h
index 2743d8397..304794dd4 100644
--- a/src/mapblock.h
+++ b/src/mapblock.h
@@ -88,11 +88,6 @@ public:
class MapBlock : public NodeContainer
{
public:
-
- //scene::SMesh *mesh[DAYNIGHT_CACHE_COUNT];
- scene::SMesh *mesh;
- JMutex mesh_mutex;
-
MapBlock(NodeContainer *parent, v3s16 pos, bool dummy=false);
~MapBlock();
@@ -131,7 +126,7 @@ public:
{
changed = true;
}
-
+#ifndef SERVER
void setMeshExpired(bool expired)
{
m_mesh_expired = expired;
@@ -141,7 +136,7 @@ public:
{
return m_mesh_expired;
}
-
+#endif
v3s16 getPos()
{
return m_pos;
@@ -273,10 +268,6 @@ public:
setNode(x0+x, y0+y, z0+z, node);
}
- static void makeFastFace(TileSpec tile, u8 light, v3f p,
- v3s16 dir, v3f scale, v3f posRelative_f,
- core::array<FastFace> &dest);
-
u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
v3s16 face_dir);
@@ -288,6 +279,11 @@ public:
face_dir);
}
+#ifndef SERVER
+ static void makeFastFace(TileSpec tile, u8 light, v3f p,
+ v3s16 dir, v3f scale, v3f posRelative_f,
+ core::array<FastFace> &dest);
+
TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir);
u8 getNodeContent(v3s16 p, MapNode mn);
@@ -311,6 +307,7 @@ public:
/*void updateMesh(s32 daynight_i);
// Updates all DAYNIGHT_CACHE_COUNT meshes
void updateMeshes(s32 first_i=0);*/
+#endif // !SERVER
bool propagateSunlight(core::map<v3s16, bool> & light_sources);
@@ -388,7 +385,8 @@ public:
{
return m_objects.getCount();
}
-
+
+#ifndef SERVER
/*
Methods for setting temporary modifications to nodes for
drawing
@@ -406,6 +404,7 @@ public:
{
m_temp_mods.clear();
}
+#endif
/*
Day-night lighting difference
@@ -431,6 +430,16 @@ public:
void deSerialize(std::istream &is, u8 version);
+ /*
+ Public member variables
+ */
+
+#ifndef SERVER
+ //scene::SMesh *mesh[DAYNIGHT_CACHE_COUNT];
+ scene::SMesh *mesh;
+ JMutex mesh_mutex;
+#endif
+
private:
/*
@@ -468,19 +477,22 @@ private:
/*
Used for some initial lighting stuff.
At least /has been/ used. 8)
+ It's probably useless now.
*/
bool is_underground;
-
- bool m_mesh_expired;
// Whether day and night lighting differs
bool m_day_night_differs;
MapBlockObjectList m_objects;
+#ifndef SERVER
+ bool m_mesh_expired;
+
// Temporary modifications to nodes
// These are only used when drawing
core::map<v3s16, NodeMod> m_temp_mods;
+#endif
};
inline bool blockpos_over_limit(v3s16 p)
diff --git a/src/mapblockobject.h b/src/mapblockobject.h
index 8518d6b11..1a403bfe1 100644
--- a/src/mapblockobject.h
+++ b/src/mapblockobject.h
@@ -135,6 +135,12 @@ public:
// A return value of true requests deletion of the object by the caller.
// NOTE: Only server calls this.
virtual bool serverStep(float dtime) { return false; };
+
+#ifdef SERVER
+ void clientStep(float dtime) {};
+ void addToScene(void *smgr) {};
+ void removeFromScene() {};
+#else
// This should do slight animations only or so
virtual void clientStep(float dtime) {};
@@ -147,6 +153,7 @@ public:
// Should return silently if there is nothing to remove
// NOTE: This has to be called before calling destructor
virtual void removeFromScene() {};
+#endif
virtual std::string infoText() { return ""; }
@@ -270,8 +277,8 @@ public:
virtual bool serverStep(float dtime) { return false; };
virtual void clientStep(float dtime) {};
- virtual void addToScene(scene::ISceneManager *smgr) = 0;
- virtual void removeFromScene() = 0;
+ /*virtual void addToScene(scene::ISceneManager *smgr) = 0;
+ virtual void removeFromScene() = 0;*/
/*
Special methods
@@ -375,7 +382,7 @@ public:
return false;
}
-
+#ifndef SERVER
virtual void clientStep(float dtime)
{
m_pos += m_speed * dtime;
@@ -424,6 +431,7 @@ public:
m_node = NULL;
}
}
+#endif
virtual std::string getInventoryString()
{
@@ -520,6 +528,7 @@ public:
{
return false;
}
+#ifndef SERVER
virtual void addToScene(scene::ISceneManager *smgr)
{
if(m_node != NULL)
@@ -587,6 +596,7 @@ public:
m_node = NULL;
}
}
+#endif
virtual std::string infoText()
{
@@ -601,14 +611,15 @@ public:
/*
Special methods
*/
-
void updateSceneNode()
{
+#ifndef SERVER
if(m_node != NULL)
{
m_node->setPosition(getAbsolutePos());
m_node->setRotation(v3f(0, m_yaw, 0));
}
+#endif
}
void setText(std::string text)
diff --git a/src/mapsector.cpp b/src/mapsector.cpp
index f83679314..8a3728c8f 100644
--- a/src/mapsector.cpp
+++ b/src/mapsector.cpp
@@ -607,6 +607,7 @@ ServerMapSector* ServerMapSector::deSerialize(
return sector;
}
+#ifndef SERVER
/*
ClientMapSector
*/
@@ -667,5 +668,6 @@ void ClientMapSector::deSerialize(std::istream &is)
m_corners[2] = c2;
m_corners[3] = c3;
}
+#endif // !SERVER
//END
diff --git a/src/mapsector.h b/src/mapsector.h
index d5ffa7f1d..b57688115 100644
--- a/src/mapsector.h
+++ b/src/mapsector.h
@@ -309,6 +309,7 @@ private:
core::map<v3s16, u8> *m_objects;
};
+#ifndef SERVER
class ClientMapSector : public MapSector
{
public:
@@ -331,6 +332,7 @@ private:
// The ground height of the corners is stored in here
s16 m_corners[4];
};
+#endif
#endif
diff --git a/src/player.cpp b/src/player.cpp
index ef2a3bdfb..2c04f1f76 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -228,6 +228,8 @@ void Player::accelerate(v3f target_speed, f32 max_increase)
RemotePlayer
*/
+#ifndef SERVER
+
RemotePlayer::RemotePlayer(
scene::ISceneNode* parent,
IrrlichtDevice *device,
@@ -236,7 +238,7 @@ RemotePlayer::RemotePlayer(
m_text(NULL)
{
m_box = core::aabbox3d<f32>(-BS/2,0,-BS/2,BS/2,BS*2,BS/2);
-
+
if(parent != NULL && device != NULL)
{
// ISceneNode stores a member called SceneManager
@@ -320,6 +322,9 @@ void RemotePlayer::updateName(const char *name)
}
}
+#endif
+
+#ifndef SERVER
/*
LocalPlayer
*/
@@ -399,5 +404,5 @@ void LocalPlayer::applyControl(float dtime)
// Accelerate to target speed with maximum increment
accelerate(speed, inc);
}
-
+#endif
diff --git a/src/player.h b/src/player.h
index 91ad99911..7337eb6db 100644
--- a/src/player.h
+++ b/src/player.h
@@ -109,6 +109,26 @@ protected:
v3f m_position;
};
+class ServerRemotePlayer : public Player
+{
+public:
+ ServerRemotePlayer()
+ {
+ }
+ virtual ~ServerRemotePlayer()
+ {
+ }
+
+ bool isLocal() const
+ {
+ return false;
+ }
+
+private:
+};
+
+#ifndef SERVER
+
class RemotePlayer : public Player, public scene::ISceneNode
{
public:
@@ -165,6 +185,9 @@ private:
core::aabbox3d<f32> m_box;
};
+#endif
+
+#ifndef SERVER
struct PlayerControl
{
PlayerControl()
@@ -225,6 +248,7 @@ public:
private:
};
+#endif // !SERVER
#endif
diff --git a/src/server.cpp b/src/server.cpp
index acb4003da..a2dfc8269 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -2082,7 +2082,7 @@ void Server::peerAdded(con::Peer *peer)
// The player shouldn't already exist
assert(player == NULL);
- player = new RemotePlayer();
+ player = new ServerRemotePlayer();
player->peer_id = peer->id;
/*
diff --git a/src/servermain.cpp b/src/servermain.cpp
new file mode 100644
index 000000000..e8d7c471d
--- /dev/null
+++ b/src/servermain.cpp
@@ -0,0 +1,421 @@
+/*
+Minetest-c55
+Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.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 2 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, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+/*
+=============================== NOTES ==============================
+
+TODO: Move the default settings into some separate file
+
+*/
+
+#ifndef SERVER
+ #ifdef _WIN32
+ #else
+ #error "For a server build, SERVER must be defined globally"
+ #endif
+#endif
+
+#ifdef UNITTEST_DISABLE
+ #ifdef _WIN32
+ #pragma message ("Disabling unit tests")
+ #else
+ #warning "Disabling unit tests"
+ #endif
+ // Disable unit tests
+ #define ENABLE_TESTS 0
+#else
+ // Enable unit tests
+ #define ENABLE_TESTS 1
+#endif
+
+#ifdef _MSC_VER
+#pragma comment(lib, "jthread.lib")
+#pragma comment(lib, "zlibwapi.lib")
+#endif
+
+#ifdef _WIN32
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
+ #define sleep_ms(x) Sleep(x)
+#else
+ #include <unistd.h>
+ #define sleep_ms(x) usleep(x*1000)
+#endif
+
+#include <iostream>
+#include <fstream>
+#include <time.h>
+#include <jmutexautolock.h>
+#include <locale.h>
+#include "common_irrlicht.h"
+#include "debug.h"
+#include "map.h"
+#include "player.h"
+#include "main.h"
+#include "test.h"
+#include "environment.h"
+#include "server.h"
+#include "serialization.h"
+#include "constants.h"
+#include "strfnd.h"
+#include "porting.h"
+
+// Dummy variable
+IrrlichtDevice *g_device = NULL;
+
+/*
+ Settings.
+ These are loaded from the config file.
+*/
+
+Settings g_settings;
+
+// Sets default settings
+void set_default_settings()
+{
+ // Client stuff
+ g_settings.setDefault("wanted_fps", "30");
+ g_settings.setDefault("fps_max", "60");
+ g_settings.setDefault("viewing_range_nodes_max", "300");
+ g_settings.setDefault("viewing_range_nodes_min", "35");
+ g_settings.setDefault("screenW", "");
+ g_settings.setDefault("screenH", "");
+ g_settings.setDefault("host_game", "");
+ g_settings.setDefault("port", "");
+ g_settings.setDefault("address", "");
+ g_settings.setDefault("name", "");
+ g_settings.setDefault("random_input", "false");
+ g_settings.setDefault("client_delete_unused_sectors_timeout", "1200");
+ g_settings.setDefault("enable_fog", "true");
+
+ // Server stuff
+ g_settings.setDefault("creative_mode", "false");
+ g_settings.setDefault("heightmap_blocksize", "32");
+ g_settings.setDefault("height_randmax", "constant 50.0");
+ g_settings.setDefault("height_randfactor", "constant 0.6");
+ g_settings.setDefault("height_base", "linear 0 0 0");
+ g_settings.setDefault("plants_amount", "1.0");
+ g_settings.setDefault("ravines_amount", "1.0");
+ g_settings.setDefault("objectdata_interval", "0.2");
+ g_settings.setDefault("active_object_range", "2");
+ g_settings.setDefault("max_simultaneous_block_sends_per_client", "1");
+ g_settings.setDefault("max_simultaneous_block_sends_server_total", "4");
+ g_settings.setDefault("disable_water_climb", "true");
+ g_settings.setDefault("endless_water", "true");
+ g_settings.setDefault("max_block_send_distance", "5");
+ g_settings.setDefault("max_block_generate_distance", "4");
+}
+
+/*
+ Debug streams
+*/
+
+// Connection
+std::ostream *dout_con_ptr = &dummyout;
+std::ostream *derr_con_ptr = &dstream_no_stderr;
+
+// Server
+std::ostream *dout_server_ptr = &dstream;
+std::ostream *derr_server_ptr = &dstream;
+
+// Client
+std::ostream *dout_client_ptr = &dstream;
+std::ostream *derr_client_ptr = &dstream;
+
+
+/*
+ Timestamp stuff
+*/
+
+JMutex g_timestamp_mutex;
+
+std::string getTimestamp()
+{
+ if(g_timestamp_mutex.IsInitialized()==false)
+ return "";
+ JMutexAutoLock lock(g_timestamp_mutex);
+ time_t t = time(NULL);
+ struct tm *tm = localtime(&t);
+ char cs[20];
+ strftime(cs, 20, "%H:%M:%S", tm);
+ return cs;
+}
+
+int main(int argc, char *argv[])
+{
+ /*
+ Low-level initialization
+ */
+
+ bool disable_stderr = false;
+#ifdef _WIN32
+ disable_stderr = true;
+#endif
+
+ // Initialize debug streams
+ debugstreams_init(disable_stderr, DEBUGFILE);
+ // Initialize debug stacks
+ debug_stacks_init();
+
+ DSTACK(__FUNCTION_NAME);
+
+ 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));
+
+ 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;
+ }
+
+
+ /*
+ Basic initialization
+ */
+
+ // Initialize default settings
+ set_default_settings();
+
+ // Print startup message
+ dstream<<DTIME<<"minetest-c55 server"
+ " with SER_FMT_VER_HIGHEST="<<(int)SER_FMT_VER_HIGHEST
+ <<", ENABLE_TESTS="<<ENABLE_TESTS
+ <<std::endl;
+
+ // Set locale. This is for forcing '.' as the decimal point.
+ std::locale::global(std::locale("C"));
+ // This enables printing all characters in bitmap font
+ setlocale(LC_CTYPE, "en_US");
+
+ // Initialize sockets
+ sockets_init();
+ atexit(sockets_cleanup);
+
+ // Initialize timestamp mutex
+ g_timestamp_mutex.Init();
+
+ /*
+ Initialization
+ */
+
+ /*
+ Read config file
+ */
+
+ // Path of configuration file in use
+ std::string configpath = "";
+
+ if(cmd_args.exists("config"))
+ {
+ bool r = g_settings.readConfigFile(cmd_args.get("config").c_str());
+ if(r == false)
+ {
+ dstream<<"Could not read configuration from \""
+ <<cmd_args.get("config")<<"\""<<std::endl;
+ return 1;
+ }
+ configpath = cmd_args.get("config");
+ }
+ else
+ {
+ const char *filenames[2] =
+ {
+ "../minetest.conf",
+ "../../minetest.conf"
+ };
+
+ for(u32 i=0; i<2; i++)
+ {
+ bool r = g_settings.readConfigFile(filenames[i]);
+ if(r)
+ {
+ configpath = filenames[i];
+ break;
+ }
+ }
+ }
+
+ // Initialize random seed
+ srand(time(0));
+
+ /*
+ Run unit tests
+ */
+ if((ENABLE_TESTS && cmd_args.getFlag("disable-unittests") == false)
+ || cmd_args.getFlag("enable-unittests") == true)
+ {
+ run_tests();
+ }
+
+ // Read map parameters from settings
+
+ HMParams hm_params;
+ hm_params.blocksize = g_settings.getU16("heightmap_blocksize");
+ hm_params.randmax = g_settings.get("height_randmax");
+ hm_params.randfactor = g_settings.get("height_randfactor");
+ hm_params.base = g_settings.get("height_base");
+
+ MapParams map_params;
+ map_params.plants_amount = g_settings.getFloat("plants_amount");
+ map_params.ravines_amount = g_settings.getFloat("ravines_amount");
+
+ /*
+ Check parameters
+ */
+
+ std::cout<<std::endl<<std::endl;
+
+ std::cout
+ <<" .__ __ __ "<<std::endl
+ <<" _____ |__| ____ _____/ |_ ____ _______/ |_ "<<std::endl
+ <<" / \\| |/ \\_/ __ \\ __\\/ __ \\ / ___/\\ __\\"<<std::endl
+ <<"| Y Y \\ | | \\ ___/| | \\ ___/ \\___ \\ | | "<<std::endl
+ <<"|__|_| /__|___| /\\___ >__| \\___ >____ > |__| "<<std::endl
+ <<" \\/ \\/ \\/ \\/ \\/ "<<std::endl
+ <<std::endl
+ <<"Now with more waterish water!"
+ <<std::endl;
+
+ std::cout<<std::endl;
+
+ // 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");
+ }
+ else
+ {
+ dstream<<"Please specify port (in config or on command line)"
+ <<std::endl;
+ }
+
+ DSTACK("Dedicated server branch");
+
+ std::cout<<std::endl;
+ std::cout<<"========================"<<std::endl;
+ std::cout<<"Running dedicated server"<<std::endl;
+ std::cout<<"========================"<<std::endl;
+ std::cout<<std::endl;
+
+ Server server("../map", hm_params, map_params);
+ server.start(port);
+
+ for(;;)
+ {
+ // This is kind of a hack but can be done like this
+ // because server.step() is very light
+ sleep_ms(30);
+ server.step(0.030);
+
+ static int counter = 0;
+ counter--;
+ if(counter <= 0)
+ {
+ counter = 10;
+
+ core::list<PlayerInfo> list = server.getPlayerInfo();
+ core::list<PlayerInfo>::Iterator i;
+ static u32 sum_old = 0;
+ u32 sum = PIChecksum(list);
+ if(sum != sum_old)
+ {
+ std::cout<<DTIME<<"Player info:"<<std::endl;
+ for(i=list.begin(); i!=list.end(); i++)
+ {
+ i->PrintLine(&std::cout);
+ }
+ }
+ sum_old = sum;
+ }
+ }
+
+ /*
+ Update configuration file
+ */
+ if(configpath != "")
+ {
+ g_settings.updateConfigFile(configpath.c_str());
+ }
+
+ } //try
+ catch(con::PeerNotFoundException &e)
+ {
+ dstream<<DTIME<<"Connection timed out."<<std::endl;
+ }
+#if CATCH_UNHANDLED_EXCEPTIONS
+ /*
+ This is what has to be done in every thread to get suitable debug info
+ */
+ catch(std::exception &e)
+ {
+ dstream<<std::endl<<DTIME<<"An unhandled exception occurred: "
+ <<e.what()<<std::endl;
+ assert(0);
+ }
+#endif
+
+ debugstreams_deinit();
+
+ return 0;
+}
+
+//END