From ab7477c4c3e2a3647dc4fb65c71567946d33b0e3 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sun, 19 Dec 2010 19:11:05 +0200 Subject: [PATCH] added dedicated server build without irrlicht --- Makefile | 65 ++++--- src/client.cpp | 11 +- src/client.h | 15 +- src/environment.cpp | 9 +- src/environment.h | 4 + src/inventory.h | 2 + src/main.cpp | 5 +- src/main.h | 16 +- src/map.cpp | 20 +- src/map.h | 17 +- src/mapblock.cpp | 111 ++++++------ src/mapblock.h | 40 ++-- src/mapblockobject.h | 19 +- src/mapsector.cpp | 2 + src/mapsector.h | 2 + src/player.cpp | 9 +- src/player.h | 24 +++ src/server.cpp | 2 +- src/servermain.cpp | 421 +++++++++++++++++++++++++++++++++++++++++++ 19 files changed, 669 insertions(+), 125 deletions(-) create mode 100644 src/servermain.cpp diff --git a/Makefile b/Makefile index dfe180573..08107718c 100644 --- a/Makefile +++ b/Makefile @@ -4,25 +4,28 @@ TARGET = test SOURCE_FILES = guiPauseMenu.cpp mapnode.cpp tile.cpp voxel.cpp mapblockobject.cpp inventory.cpp debug.cpp serialization.cpp light.cpp filesys.cpp connection.cpp environment.cpp client.cpp server.cpp socket.cpp mapblock.cpp mapsector.cpp heightmap.cpp map.cpp player.cpp utility.cpp main.cpp test.cpp SOURCES = $(addprefix src/, $(SOURCE_FILES)) -OBJECTS = $(SOURCES:.cpp=.o) -FASTTARGET = fasttest +BUILD_DIR = build +OBJECTS = $(addprefix $(BUILD_DIR)/, $(SOURCE_FILES:.cpp=.o)) +#OBJECTS = $(SOURCES:.cpp=.o) + +FAST_TARGET = fasttest + +SERVER_TARGET = server +SERVER_SOURCE_FILES = mapnode.cpp voxel.cpp mapblockobject.cpp inventory.cpp debug.cpp serialization.cpp light.cpp filesys.cpp connection.cpp environment.cpp server.cpp socket.cpp mapblock.cpp mapsector.cpp heightmap.cpp map.cpp player.cpp utility.cpp servermain.cpp test.cpp +SERVER_SOURCES = $(addprefix src/, $(SERVER_SOURCE_FILES)) +SERVER_BUILD_DIR = serverbuild +SERVER_OBJECTS = $(addprefix $(SERVER_BUILD_DIR)/, $(SERVER_SOURCE_FILES:.cpp=.o)) +#SERVER_OBJECTS = $(SERVER_SOURCES:.cpp=.o) IRRLICHTPATH = ../irrlicht/irrlicht-1.7.1 JTHREADPATH = ../jthread/jthread-1.2.1 -CPPFLAGS = -I$(IRRLICHTPATH)/include -I/usr/X11R6/include -I$(JTHREADPATH)/src - #CXXFLAGS = -O2 -ffast-math -Wall -fomit-frame-pointer -pipe CXXFLAGS = -O2 -ffast-math -Wall -g -pipe #CXXFLAGS = -O1 -ffast-math -Wall -g #CXXFLAGS = -Wall -g -O0 -#CXXFLAGS = -O3 -ffast-math -Wall -#CXXFLAGS = -O3 -ffast-math -Wall -g -#CXXFLAGS = -O2 -ffast-math -Wall -g - -FASTCXXFLAGS = -O3 -ffast-math -Wall -fomit-frame-pointer -pipe -funroll-loops -mtune=i686 -#FASTCXXFLAGS = -O3 -ffast-math -Wall -fomit-frame-pointer -pipe -funroll-loops -mtune=i686 -fwhole-program +#FAST_CXXFLAGS = -O3 -ffast-math -Wall -fomit-frame-pointer -pipe -funroll-loops -mtune=i686 #Default target @@ -35,8 +38,13 @@ endif # Target specific settings all_linux fast_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L$(IRRLICHTPATH)/lib/Linux -L$(JTHREADPATH)/src/.libs -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -ljthread -lz +all_linux fast_linux: CPPFLAGS = -I$(IRRLICHTPATH)/include -I/usr/X11R6/include -I$(JTHREADPATH)/src +fast_linux server_linux: CXXFLAGS = -O3 -ffast-math -Wall -fomit-frame-pointer -pipe -funroll-loops -mtune=i686 +server_linux: LDFLAGS = -L$(JTHREADPATH)/src/.libs -ljthread -lz -lpthread +server_linux: CPPFLAGS = -I$(IRRLICHTPATH)/include -I/usr/X11R6/include -I$(JTHREADPATH)/src -DSERVER all_linux fast_linux clean_linux: SYSTEM=Linux +# These are out of date all_win32: LDFLAGS = -L$(IRRLICHTPATH)/lib/Win32-gcc -L$(JTHREADPATH)/Debug -lIrrlicht -lopengl32 -lm -ljthread all_win32 clean_win32: SYSTEM=Win32-gcc all_win32 clean_win32: SUF=.exe @@ -44,31 +52,44 @@ all_win32 clean_win32: SUF=.exe # Name of the binary - only valid for targets which set SYSTEM DESTPATH = bin/$(TARGET)$(SUF) -FASTDESTPATH = bin/$(FASTTARGET)$(SUF) +FAST_DESTPATH = bin/$(FAST_TARGET)$(SUF) +SERVER_DESTPATH = bin/$(SERVER_TARGET)$(SUF) # Build commands -all_linux all_win32: $(DESTPATH) - -fast_linux: $(FASTDESTPATH) +all_linux all_win32: make_build_dir $(DESTPATH) +fast_linux: make_build_dir $(FAST_DESTPATH) +server_linux: make_server_build_dir $(SERVER_DESTPATH) -$(FASTDESTPATH): $(SOURCES) - $(CXX) -o $(FASTDESTPATH) $(SOURCES) $(CPPFLAGS) $(FASTCXXFLAGS) $(LDFLAGS) -DUNITTEST_DISABLE - @# Errno doesn't work ("error: ‘__errno_location’ was not declared in this scope") - @#cat $(SOURCES) | $(CXX) -o $(FASTDESTPATH) -x c++ - -Isrc/ $(CPPFLAGS) $(FASTCXXFLAGS) $(LDFLAGS) -DUNITTEST_DISABLE -DDISABLE_ERRNO +make_build_dir: + mkdir -p $(BUILD_DIR) +make_server_build_dir: + mkdir -p $(SERVER_BUILD_DIR) $(DESTPATH): $(OBJECTS) $(CXX) -o $@ $(OBJECTS) $(LDFLAGS) -.cpp.o: +$(FAST_DESTPATH): $(SOURCES) + $(CXX) -o $@ $(OBJECTS) $(LDFLAGS) -DUNITTEST_DISABLE + +$(SERVER_DESTPATH): $(SERVER_OBJECTS) + $(CXX) -o $@ $(SERVER_OBJECTS) $(LDFLAGS) -DSERVER -DUNITTEST_DISABLE + +$(BUILD_DIR)/%.o: src/%.cpp $(CXX) -c -o $@ $< $(CPPFLAGS) $(CXXFLAGS) -clean: clean_linux clean_win32 clean_fast_linux +$(SERVER_BUILD_DIR)/%.o: src/%.cpp + $(CXX) -c -o $@ $< $(CPPFLAGS) $(CXXFLAGS) + +clean: clean_linux clean_win32 clean_fast_linux clean_server_linux clean_linux clean_win32: @$(RM) $(OBJECTS) $(DESTPATH) clean_fast_linux: - @$(RM) $(FASTDESTPATH) + @$(RM) $(OBJECTS) $(FAST_DESTPATH) + +clean_server_linux: + @$(RM) $(SERVER_OBJECTS) $(SERVER_DESTPATH) -.PHONY: all all_win32 clean clean_linux clean_win32 +.PHONY: all all_win32 clean clean_linux clean_win32 clean_fast_linux clean_server_linux 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::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 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 -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 &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; idrop(); mesh = NULL; } - /*for(s32 i=0; idrop(); - 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 &dest) @@ -229,50 +266,6 @@ void MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p, //return f; } -/* - 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 &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 &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 & 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 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 *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(-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 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 + +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 + #define sleep_ms(x) Sleep(x) +#else + #include + #define sleep_ms(x) usleep(x*1000) +#endif + +#include +#include +#include +#include +#include +#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 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:"<::Iterator + i = allowed_options.getIterator(); + i.atEnd() == false; i++) + { + dstream<<" --"<getKey(); + if(i.getNode()->getValue().type == VALUETYPE_FLAG) + { + } + else + { + dstream<<" "; + } + dstream<getValue().help != NULL) + { + dstream<<" "<getValue().help + <__| \\___ >____ > |__| "< list = server.getPlayerInfo(); + core::list::Iterator i; + static u32 sum_old = 0; + u32 sum = PIChecksum(list); + if(sum != sum_old) + { + std::cout<PrintLine(&std::cout); + } + } + sum_old = sum; + } + } + + /* + Update configuration file + */ + if(configpath != "") + { + g_settings.updateConfigFile(configpath.c_str()); + } + + } //try + catch(con::PeerNotFoundException &e) + { + dstream<