From a13e033c89c15692c56859756c1c6e9f78623670 Mon Sep 17 00:00:00 2001 From: MoNTE48 Date: Fri, 3 May 2019 21:16:45 +0200 Subject: [PATCH] Back sqlite3 for WIN, fix Sky --- CMakeLists.txt | 2 +- ...ta.xml => com.MultiCraft.game.appdata.xml} | 16 ++++++------- ...st.desktop => com.MultiCraft.game.desktop} | 8 +++---- src/CMakeLists.txt | 21 +++++++++++++++--- src/client.cpp | 7 ++++-- src/map.cpp | 5 +++++ src/porting.cpp | 4 ++-- src/serverenvironment.cpp | 7 +++++- src/sky.cpp | 16 ++++++------- src/subgame.cpp | 6 ++++- textures/base/close.png | Bin 295 -> 295 bytes textures/base/sunrisebg.png | Bin 4153 -> 4167 bytes 12 files changed, 62 insertions(+), 30 deletions(-) rename misc/{net.minetest.minetest.appdata.xml => com.MultiCraft.game.appdata.xml} (83%) rename misc/{net.minetest.minetest.desktop => com.MultiCraft.game.desktop} (91%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d5cc07fc..ea8fe9a6a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -182,7 +182,7 @@ if(UNIX AND NOT APPLE) install(FILES "misc/MultiCraft.svg" DESTINATION "${ICONDIR}/hicolor/scalable/apps") install(FILES "misc/MultiCraft-xorg-icon-128.png" DESTINATION "${ICONDIR}/hicolor/128x128/apps" - RENAME "minetest.png") + RENAME "MultiCraft.png") endif() if(APPLE) diff --git a/misc/net.minetest.minetest.appdata.xml b/misc/com.MultiCraft.game.appdata.xml similarity index 83% rename from misc/net.minetest.minetest.appdata.xml rename to misc/com.MultiCraft.game.appdata.xml index 277225d4b..e5c52c060 100644 --- a/misc/net.minetest.minetest.appdata.xml +++ b/misc/com.MultiCraft.game.appdata.xml @@ -1,22 +1,22 @@ - net.minetest.minetest.desktop + com.MultiCraft.game.desktop CC0-1.0 - LGPL-2.1+ and CC-BY-SA-3.0 and MIT and Apache-2.0 - Minetest + LGPL-3.0+ and CC-BY-SA-3.0 and MIT and Apache-2.0 + MultiCraft Multiplayer infinite-world block sandbox game

- Minetest is an infinite-world block sandbox game and game engine. + MultiCraft is an infinite-world block sandbox game and game engine.

Players can create and destroy various types of blocks in a three-dimensional open world. This allows forming structures in every possible creation, on multiplayer servers or in singleplayer.

- Minetest is designed to be simple, stable, and portable. + MultiCraft is designed to be simple, stable, and portable. It is lightweight enough to run on fairly old hardware.

- Minetest has many features, including: + MultiCraft has many features, including:

  • Ability to walk around, dig, and build in a near-infinite voxel world
  • @@ -51,8 +51,8 @@ http://wiki.minetest.net/FAQ http://wiki.minetest.net - minetest + multicraft - minetest + multicraft sfan5@live.de diff --git a/misc/net.minetest.minetest.desktop b/misc/com.MultiCraft.game.desktop similarity index 91% rename from misc/net.minetest.minetest.desktop rename to misc/com.MultiCraft.game.desktop index ca493c44e..652f4a92c 100644 --- a/misc/net.minetest.minetest.desktop +++ b/misc/com.MultiCraft.game.desktop @@ -1,6 +1,6 @@ [Desktop Entry] -Name=Minetest -GenericName=Minetest +Name=MultiCraft +GenericName=MultiCraft Comment=Multiplayer infinite-world block sandbox Comment[de]=Mehrspieler-Sandkastenspiel mit unendlichen Blockwelten Comment[es]=Juego sandbox multijugador con mundos infinitos @@ -8,8 +8,8 @@ Comment[fr]=Jeu multijoueurs de type bac à sable avec des mondes infinis Comment[ja]=マルチプレイに対応した、無限の世界のブロック型サンドボックスゲームです Comment[ru]=Игра-песочница с безграничным миром, состоящим из блоков Comment[tr]=Tek-Çok oyuncuyla küplerden sonsuz dünyalar inşa et -Exec=minetest -Icon=minetest +Exec=multicraft +Icon=multicraft Terminal=false Type=Application Categories=Game;Simulation; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f57b20893..e1f0ed159 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -232,8 +232,6 @@ if(ENABLE_REDIS) endif(ENABLE_REDIS) -#find_package(SQLite3 REQUIRED) - OPTION(ENABLE_SPATIAL "Enable SpatialIndex AreaStore backend" TRUE) set(USE_SPATIAL FALSE) @@ -259,6 +257,8 @@ add_definitions(-DUSE_CMAKE_CONFIG_H) if(WIN32) # Windows + # Add SQLITE3 + find_package(SQLite3 REQUIRED) if(MSVC) # MSVC Specifics set(PLATFORM_LIBS dbghelp.lib ${PLATFORM_LIBS}) # Surpress some useless warnings @@ -383,6 +383,7 @@ set(common_SRCS database-leveldb.cpp database-postgresql.cpp database-redis.cpp + database-sqlite3.cpp database.cpp debug.cpp defaultsettings.cpp @@ -460,7 +461,6 @@ set(common_SRCS ${UNITTEST_SRCS} ) - # This gives us the icon and file version information if(WIN32) set(WINRESOURCE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../misc/winresource.rc") @@ -558,6 +558,9 @@ include_directories( ${PROJECT_SOURCE_DIR}/script ) +if(WIN32) + include_directories(${SQLITE3_INCLUDE_DIR}) +endif() if(USE_FREETYPE) include_directories(${FREETYPE_INCLUDE_DIRS} ${CGUITTFONT_INCLUDE_DIR}) @@ -592,6 +595,12 @@ if(BUILD_CLIENT) ${PLATFORM_LIBS} ${CLIENT_PLATFORM_LIBS} ) + if(WIN32) + target_link_libraries( + ${client_LIBS} + ${SQLITE3_LIBRARY} + ) + endif() if(APPLE) target_link_libraries( ${client_LIBS} @@ -800,9 +809,15 @@ if(WIN32) if(FREETYPE_DLL) install(FILES ${FREETYPE_DLL} DESTINATION ${BINDIR}) endif() + if(SQLITE3_DLL) + install(FILES ${SQLITE3_DLL} DESTINATION ${BINDIR}) + endif() if(LEVELDB_DLL) install(FILES ${LEVELDB_DLL} DESTINATION ${BINDIR}) endif() + if(LUA_DLL) + install(FILES ${LUA_DLL} DESTINATION ${BINDIR}) + endif() endif() if(BUILD_CLIENT) diff --git a/src/client.cpp b/src/client.cpp index 724f4dca3..515515570 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -43,6 +43,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "version.h" #include "drawscene.h" #include "database.h" +#ifdef _WIN32 +#include "database-sqlite3.h" +#endif #include "serialization.h" #include "guiscalingfilter.h" #include "script/scripting_client.h" @@ -769,7 +772,7 @@ void Client::initLocalMapSaving(const Address &address, return; } - /*const std::string world_path = porting::path_user + const std::string world_path = porting::path_user + DIR_DELIM + "worlds" + DIR_DELIM + "server_" + hostname + "_" + std::to_string(address.getPort()); @@ -778,7 +781,7 @@ void Client::initLocalMapSaving(const Address &address, m_localdb = new MapDatabaseSQLite3(world_path); m_localdb->beginSave(); - actionstream << "Local map saving started, map will be saved at '" << world_path << "'" << std::endl;*/ + actionstream << "Local map saving started, map will be saved at '" << world_path << "'" << std::endl; } void Client::ReceiveAll() diff --git a/src/map.cpp b/src/map.cpp index a63906d2c..6020a21ca 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -43,6 +43,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "server.h" #include "database.h" #include "database-dummy.h" +#ifdef _WIN32 +#include "database-sqlite3.h" +#endif #include "script/scripting_server.h" #include #include @@ -2287,6 +2290,8 @@ MapDatabase *ServerMap::createDatabase( const std::string &savedir, Settings &conf) { + if (name == "sqlite3") + return new MapDatabaseSQLite3(savedir); if (name == "dummy") return new Database_Dummy(); #if USE_LEVELDB diff --git a/src/porting.cpp b/src/porting.cpp index 22ea7b74d..24a251bcb 100644 --- a/src/porting.cpp +++ b/src/porting.cpp @@ -621,9 +621,9 @@ bool setWindowIcon(IrrlichtDevice *device) HWND hWnd; // Window handle switch (device->getVideoDriver()->getDriverType()) { - case video::EDT_DIRECT3D8: +/* case video::EDT_DIRECT3D8: hWnd = reinterpret_cast(exposedData.D3D8.HWnd); - break; + break;*/ case video::EDT_DIRECT3D9: hWnd = reinterpret_cast(exposedData.D3D9.HWnd); break; diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp index 21cf0f753..99d5dbc12 100644 --- a/src/serverenvironment.cpp +++ b/src/serverenvironment.cpp @@ -39,6 +39,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "gameparams.h" #include "database-dummy.h" #include "database-files.h" +#ifdef _WIN32 +#include "database-sqlite3.h" +#endif #if USE_POSTGRESQL #include "database-postgresql.h" #endif @@ -2168,7 +2171,9 @@ PlayerDatabase *ServerEnvironment::openPlayerDatabase(const std::string &name, const std::string &savedir, const Settings &conf) { - if (name == "dummy") + if (name == "sqlite3") + return new PlayerDatabaseSQLite3(savedir); + else if (name == "dummy") return new Database_Dummy(); #if USE_POSTGRESQL else if (name == "postgresql") { diff --git a/src/sky.cpp b/src/sky.cpp index 780d58080..559677169 100644 --- a/src/sky.cpp +++ b/src/sky.cpp @@ -191,7 +191,7 @@ void Sky::render() video::SColor cloudyfogcolor = m_bgcolor; // Draw far cloudy fog thing blended with skycolor - for (u32 j = 0; j < 4; j++) { +/* for (u32 j = 0; j < 4; j++) { video::SColor c = cloudyfogcolor.getInterpolated(m_skycolor, 0.45); vertices[0] = video::S3DVertex(-1, 0.08, -1, 0, 0, 1, c, t, t); vertices[1] = video::S3DVertex( 1, 0.08, -1, 0, 0, 1, c, o, t); @@ -212,10 +212,10 @@ void Sky::render() vertices[i].Pos.rotateXZBy(-180); } driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2); - } + }*/ // Draw far cloudy fog thing - for (u32 j = 0; j < 4; j++) { +/* for (u32 j = 0; j < 4; j++) { video::SColor c = cloudyfogcolor; vertices[0] = video::S3DVertex(-1, -1.0, -1, 0, 0, 1, c, t, t); vertices[1] = video::S3DVertex( 1, -1.0, -1, 0, 0, 1, c, o, t); @@ -236,7 +236,7 @@ void Sky::render() vertices[i].Pos.rotateXZBy(-180); } driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2); - } + }*/ // Draw bottom far cloudy fog thing video::SColor c = cloudyfogcolor; @@ -502,7 +502,7 @@ void Sky::render() // Draw far cloudy fog thing below east and west horizons for (u32 j = 0; j < 2; j++) { - video::SColor c = cloudyfogcolor; + video::SColor c = m_skycolor; vertices[0] = video::S3DVertex(-1, -1.0, -1, 0, 0, 1, c, t, t); vertices[1] = video::S3DVertex( 1, -1.0, -1, 0, 0, 1, c, o, t); vertices[2] = video::S3DVertex( 1, -0.02, -1, 0, 0, 1, c, o, o); @@ -560,12 +560,12 @@ void Sky::update(float time_of_day, float time_brightness, video::SColorf cloudcolor_bright_dawn_f(1.0, 0.7, 0.5); */ - video::SColorf bgcolor_bright_normal_f = video::SColor(255, 155, 193, 240); + video::SColorf bgcolor_bright_normal_f = video::SColor(255, 2, 145, 255); video::SColorf bgcolor_bright_indoor_f = video::SColor(255, 100, 100, 100); - video::SColorf bgcolor_bright_dawn_f = video::SColor(255, 186, 193, 240); + video::SColorf bgcolor_bright_dawn_f = video::SColor(255, 180, 186, 255); video::SColorf bgcolor_bright_night_f = video::SColor(255, 64, 144, 255); - video::SColorf skycolor_bright_normal_f = video::SColor(255, 2, 138, 255); + video::SColorf skycolor_bright_normal_f = video::SColor(255, 2, 145, 255); video::SColorf skycolor_bright_dawn_f = video::SColor(255, 180, 186, 255); video::SColorf skycolor_bright_night_f = video::SColor(255, 0, 107, 255); diff --git a/src/subgame.cpp b/src/subgame.cpp index 6eac37476..09fd25781 100644 --- a/src/subgame.cpp +++ b/src/subgame.cpp @@ -293,7 +293,11 @@ bool loadGameConfAndInitWorld(const std::string &path, const SubgameSpec &gamesp if (!fs::PathExists(worldmt_path)) { std::ostringstream ss(std::ios_base::binary); ss << "gameid = " << gamespec.id - << "\nbackend = leveldb" + #ifdef _WIN32 + << "\nbackend = sqlite3" + #else + << "\nbackend = leveldb" + #endif << "\ncreative_mode = " << g_settings->get("creative_mode") << "\nenable_damage = " << g_settings->get("enable_damage") << "\n"; diff --git a/textures/base/close.png b/textures/base/close.png index aee97290b3478c823ba676f91eb9774e87fc0111..820d4022ccd2f7307101963d76bda864afc42049 100644 GIT binary patch literal 295 zcmV+?0oeYDP)DY7G`n;`< zH%Fhp(Mf&IGSbQ$I~>@krjf@QQC;c*E$)GlMR?V03&q zFuL)E(HYnnoso{wn`a+AW7$oe!G_U=7mO}EaOlDVhc3KebmQQvsg2Qf_e{=t<`6uSz7XPMh443~+u^`;>G=@ tskU6TVXN(4-YopB#^0!3me+<~vc5nL60+29uqprm002ovPDHLkV1j}>iAVqd literal 295 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 RKTH4s002ovPDHLkV1mUTH?{x( literal 4153 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 DI)n*O