command-line/world game selection
parent
df190b8f87
commit
7f7fb9750d
|
@ -94,6 +94,7 @@ configure_file(
|
|||
)
|
||||
|
||||
set(common_SRCS
|
||||
subgame.cpp
|
||||
inventorymanager.cpp
|
||||
mods.cpp
|
||||
serverremoteplayer.cpp
|
||||
|
|
|
@ -51,6 +51,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "itemdef.h"
|
||||
#include "tile.h" // For TextureSource
|
||||
#include "logoutputbuffer.h"
|
||||
#include "subgame.h"
|
||||
|
||||
/*
|
||||
Setting this to 1 enables a special camera mode that forces
|
||||
|
@ -651,11 +652,12 @@ void the_game(
|
|||
std::string map_dir,
|
||||
std::string playername,
|
||||
std::string password,
|
||||
std::string address,
|
||||
std::string address, // If "", local server is used
|
||||
u16 port,
|
||||
std::wstring &error_message,
|
||||
std::string configpath,
|
||||
ChatBackend &chat_backend
|
||||
ChatBackend &chat_backend,
|
||||
const SubgameSpec &gamespec // Used for local game
|
||||
)
|
||||
{
|
||||
video::IVideoDriver* driver = device->getVideoDriver();
|
||||
|
@ -705,7 +707,7 @@ void the_game(
|
|||
if(address == ""){
|
||||
draw_load_screen(L"Creating server...", driver, font);
|
||||
infostream<<"Creating server"<<std::endl;
|
||||
server = new Server(map_dir, configpath, "mesetint");
|
||||
server = new Server(map_dir, configpath, gamespec);
|
||||
server->start(port);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
#include "common_irrlicht.h"
|
||||
#include <string>
|
||||
|
||||
#include "keycode.h"
|
||||
|
||||
class KeyList : protected core::list<KeyPress>
|
||||
|
@ -123,6 +122,7 @@ public:
|
|||
};
|
||||
|
||||
class ChatBackend; /* to avoid having to include chat.h */
|
||||
struct SubgameSpec;
|
||||
|
||||
void the_game(
|
||||
bool &kill,
|
||||
|
@ -133,11 +133,12 @@ void the_game(
|
|||
std::string map_dir,
|
||||
std::string playername,
|
||||
std::string password,
|
||||
std::string address,
|
||||
std::string address, // If "", local server is used
|
||||
u16 port,
|
||||
std::wstring &error_message,
|
||||
std::string configpath,
|
||||
ChatBackend &chat_backend
|
||||
ChatBackend &chat_backend,
|
||||
const SubgameSpec &gamespec // Used for local game
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
74
src/main.cpp
74
src/main.cpp
|
@ -69,6 +69,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "log.h"
|
||||
#include "mods.h"
|
||||
#include "utility_string.h"
|
||||
#include "subgame.h"
|
||||
|
||||
/*
|
||||
Settings.
|
||||
|
@ -781,6 +782,8 @@ int main(int argc, char *argv[])
|
|||
"Print more information to console"));
|
||||
allowed_options.insert("logfile", ValueSpec(VALUETYPE_STRING,
|
||||
"Set logfile path (debug.txt)"));
|
||||
allowed_options.insert("gameid", ValueSpec(VALUETYPE_STRING,
|
||||
"Set gameid"));
|
||||
#ifndef SERVER
|
||||
allowed_options.insert("speedtests", ValueSpec(VALUETYPE_FLAG,
|
||||
"Run speed tests"));
|
||||
|
@ -958,22 +961,63 @@ int main(int argc, char *argv[])
|
|||
port = 30000;
|
||||
|
||||
// Map directory
|
||||
std::string map_dir = porting::path_user + DIR_DELIM + "server" + DIR_DELIM + "worlds" + DIR_DELIM + "world";
|
||||
if(cmd_args.exists("map-dir"))
|
||||
map_dir = cmd_args.get("map-dir");
|
||||
std::string world_path = porting::path_user + DIR_DELIM + "server" + DIR_DELIM + "worlds" + DIR_DELIM + "world";
|
||||
if(cmd_args.exists("world"))
|
||||
world_path = cmd_args.get("world");
|
||||
else if(cmd_args.exists("map-dir"))
|
||||
world_path = cmd_args.get("map-dir");
|
||||
else if(g_settings->exists("map-dir"))
|
||||
map_dir = g_settings->get("map-dir");
|
||||
world_path = g_settings->get("map-dir");
|
||||
else{
|
||||
// No map-dir option was specified.
|
||||
// Check if the world is found from the default directory, and if
|
||||
// not, see if the legacy world directory exists.
|
||||
std::string legacy_map_dir = porting::path_user+DIR_DELIM+".."+DIR_DELIM+"world";
|
||||
if(!fs::PathExists(map_dir) && fs::PathExists(legacy_map_dir)){
|
||||
std::string legacy_world_path = porting::path_user+DIR_DELIM+".."+DIR_DELIM+"world";
|
||||
if(!fs::PathExists(world_path) && fs::PathExists(legacy_world_path)){
|
||||
errorstream<<"Warning: Using legacy world directory \""
|
||||
<<legacy_map_dir<<"\""<<std::endl;
|
||||
map_dir = legacy_map_dir;
|
||||
<<legacy_world_path<<"\""<<std::endl;
|
||||
world_path = legacy_world_path;
|
||||
}
|
||||
}
|
||||
|
||||
// Determine gameid
|
||||
std::string gameid = "";
|
||||
if(cmd_args.exists("gameid"))
|
||||
gameid = cmd_args.get("gameid");
|
||||
std::string world_gameid = getWorldGameId(world_path);
|
||||
if(world_gameid == ""){
|
||||
if(gameid != "")
|
||||
world_gameid = gameid;
|
||||
else{
|
||||
world_gameid = "mesetint";
|
||||
}
|
||||
}
|
||||
if(gameid == "")
|
||||
gameid = world_gameid;
|
||||
else if(world_gameid != ""){
|
||||
if(world_gameid != gameid){
|
||||
errorstream<<"World gameid mismatch"<<std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if(gameid == ""){
|
||||
errorstream<<"No gameid supplied or detected"<<std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
infostream<<"Using gameid \""<<gameid<<"\""<<std::endl;
|
||||
|
||||
SubgameSpec gamespec = findSubgame(gameid);
|
||||
if(!gamespec.isValid()){
|
||||
errorstream<<"Game \""<<gameid<<"\" not found"<<std::endl;
|
||||
std::set<std::string> gameids = getAvailableGameIds();
|
||||
infostream<<"Available gameids: ";
|
||||
for(std::set<std::string>::const_iterator i = gameids.begin();
|
||||
i != gameids.end(); i++)
|
||||
infostream<<(*i)<<" ";
|
||||
infostream<<std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Run dedicated server if asked to or no other option
|
||||
#ifdef SERVER
|
||||
|
@ -991,7 +1035,7 @@ int main(int argc, char *argv[])
|
|||
#endif
|
||||
|
||||
// Create server
|
||||
Server server(map_dir, configpath, "mesetint");
|
||||
Server server(world_path, configpath, gamespec);
|
||||
server.start(port);
|
||||
|
||||
// Run server
|
||||
|
@ -1080,9 +1124,6 @@ int main(int argc, char *argv[])
|
|||
*/
|
||||
//driver->setMinHardwareBufferVertexCount(50);
|
||||
|
||||
// Set the window caption
|
||||
device->setWindowCaption(L"Minetest [Main Menu]");
|
||||
|
||||
// Create time getter
|
||||
g_timegetter = new IrrlichtTimeGetter(device);
|
||||
|
||||
|
@ -1154,6 +1195,8 @@ int main(int argc, char *argv[])
|
|||
*/
|
||||
while(device->run() && kill == false)
|
||||
{
|
||||
// Set the window caption
|
||||
device->setWindowCaption(L"Minetest [Main Menu]");
|
||||
|
||||
// This is used for catching disconnects
|
||||
try
|
||||
|
@ -1257,7 +1300,7 @@ int main(int argc, char *argv[])
|
|||
// Delete map if requested
|
||||
if(menudata.delete_map)
|
||||
{
|
||||
bool r = fs::RecursiveDeleteContent(map_dir);
|
||||
bool r = fs::RecursiveDeleteContent(world_path);
|
||||
if(r == false)
|
||||
error_message = L"Delete failed";
|
||||
continue;
|
||||
|
@ -1303,14 +1346,15 @@ int main(int argc, char *argv[])
|
|||
input,
|
||||
device,
|
||||
font,
|
||||
map_dir,
|
||||
world_path,
|
||||
playername,
|
||||
password,
|
||||
address,
|
||||
port,
|
||||
error_message,
|
||||
configpath,
|
||||
chat_backend
|
||||
chat_backend,
|
||||
gamespec
|
||||
);
|
||||
|
||||
} //try
|
||||
|
|
|
@ -830,13 +830,13 @@ void PlayerInfo::PrintLine(std::ostream *s)
|
|||
*/
|
||||
|
||||
Server::Server(
|
||||
std::string path_world,
|
||||
std::string path_config,
|
||||
std::string gamename
|
||||
const std::string &path_world,
|
||||
const std::string &path_config,
|
||||
const SubgameSpec &gamespec
|
||||
):
|
||||
m_gamename(gamename),
|
||||
m_path_world(path_world),
|
||||
m_path_config(path_config),
|
||||
m_gamespec(gamespec),
|
||||
m_env(NULL),
|
||||
m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this),
|
||||
m_authmanager(path_world+DIR_DELIM+"auth.txt"),
|
||||
|
@ -865,55 +865,38 @@ Server::Server(
|
|||
m_step_dtime_mutex.Init();
|
||||
m_step_dtime = 0.0;
|
||||
|
||||
if(!gamespec.isValid())
|
||||
throw ServerError("Supplied invalid gamespec");
|
||||
|
||||
// Figure out some paths
|
||||
// share/server
|
||||
m_path_share = porting::path_share + DIR_DELIM + "server";
|
||||
// game
|
||||
m_path_game = porting::path_user + DIR_DELIM + "server" + DIR_DELIM
|
||||
+ "games" + DIR_DELIM + m_gamename;
|
||||
bool user_game = true; // Game is in user's directory
|
||||
if(!fs::PathExists(m_path_game)){
|
||||
m_path_game = m_path_share + DIR_DELIM + "games" + DIR_DELIM
|
||||
+ m_gamename;
|
||||
user_game = false;
|
||||
}
|
||||
if(!fs::PathExists(m_path_game)){
|
||||
throw ServerError("Could not find game files for game \""
|
||||
+gamename+"\"");
|
||||
}
|
||||
// addons
|
||||
if(!user_game)
|
||||
m_path_addons.insert(m_path_share + DIR_DELIM + "addons"
|
||||
+ DIR_DELIM + m_gamename);
|
||||
m_path_addons.insert(porting::path_user + DIR_DELIM + "server"
|
||||
+ DIR_DELIM + "addons" + DIR_DELIM + m_gamename);
|
||||
|
||||
infostream<<"Server created for gamename=\""<<gamename<<"\""<<std::endl;
|
||||
infostream<<"- path_world = "<<m_path_world<<std::endl;
|
||||
infostream<<"- path_config = "<<m_path_config<<std::endl;
|
||||
infostream<<"- path_game = "<<m_path_game<<std::endl;
|
||||
for(std::set<std::string>::const_iterator i = m_path_addons.begin();
|
||||
i != m_path_addons.end(); i++)
|
||||
infostream<<"- path_addons+= "<<(*i)<<std::endl;
|
||||
infostream<<"Server created for gameid \""<<m_gamespec.id<<"\""<<std::endl;
|
||||
infostream<<"- world: "<<m_path_world<<std::endl;
|
||||
infostream<<"- config: "<<m_path_config<<std::endl;
|
||||
infostream<<"- game: "<<m_gamespec.path<<std::endl;
|
||||
for(std::set<std::string>::const_iterator i = m_gamespec.addon_paths.begin();
|
||||
i != m_gamespec.addon_paths.end(); i++)
|
||||
infostream<<"- addons: "<<(*i)<<std::endl;
|
||||
|
||||
// Path to builtin.lua
|
||||
std::string builtinpath = m_path_share + DIR_DELIM + "builtin.lua";
|
||||
|
||||
// Add default global mod search path
|
||||
m_modspaths.push_front(m_path_game + DIR_DELIM "mods");
|
||||
m_modspaths.push_front(m_gamespec.path + DIR_DELIM "mods");
|
||||
// Add world mod search path
|
||||
m_modspaths.push_front(m_path_world + DIR_DELIM + "worldmods");
|
||||
// Add addon mod search path
|
||||
for(std::set<std::string>::const_iterator i = m_path_addons.begin();
|
||||
i != m_path_addons.end(); i++){
|
||||
for(std::set<std::string>::const_iterator i = m_gamespec.addon_paths.begin();
|
||||
i != m_gamespec.addon_paths.end(); i++)
|
||||
m_modspaths.push_front((*i) + DIR_DELIM + "mods");
|
||||
}
|
||||
|
||||
// Print out mod search paths
|
||||
for(core::list<std::string>::Iterator i = m_modspaths.begin();
|
||||
i != m_modspaths.end(); i++){
|
||||
std::string modspath = *i;
|
||||
infostream<<"- modspath += "<<modspath<<std::endl;
|
||||
infostream<<"- mods: "<<modspath<<std::endl;
|
||||
}
|
||||
|
||||
// Lock environment
|
||||
|
@ -1106,7 +1089,8 @@ void Server::start(unsigned short port)
|
|||
<<"| Y Y \\ | | \\ ___/| | \\ ___/ \\___ \\ | | "<<std::endl
|
||||
<<"|__|_| /__|___| /\\___ >__| \\___ >____ > |__| "<<std::endl
|
||||
<<" \\/ \\/ \\/ \\/ \\/ "<<std::endl;
|
||||
actionstream<<"Server listening on port "<<port<<"."<<std::endl;
|
||||
actionstream<<"Server for gameid=\""<<m_gamespec.id
|
||||
<<"\" listening on port "<<port<<"."<<std::endl;
|
||||
}
|
||||
|
||||
void Server::stop()
|
||||
|
|
18
src/server.h
18
src/server.h
|
@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "serverremoteplayer.h"
|
||||
#include "mods.h"
|
||||
#include "inventorymanager.h"
|
||||
#include "subgame.h"
|
||||
struct LuaState;
|
||||
typedef struct lua_State lua_State;
|
||||
class IWritableItemDefManager;
|
||||
|
@ -405,11 +406,11 @@ public:
|
|||
/*
|
||||
NOTE: Every public method should be thread-safe
|
||||
*/
|
||||
|
||||
|
||||
Server(
|
||||
std::string gamename,
|
||||
std::string mapsavedir,
|
||||
std::string configpath
|
||||
const std::string &path_world,
|
||||
const std::string &path_config,
|
||||
const SubgameSpec &gamespec
|
||||
);
|
||||
~Server();
|
||||
void start(unsigned short port);
|
||||
|
@ -647,20 +648,15 @@ private:
|
|||
Variables
|
||||
*/
|
||||
|
||||
// Game name
|
||||
std::string m_gamename;
|
||||
// World directory
|
||||
std::string m_path_world;
|
||||
// Path to user's configuration file ("" = no configuration file)
|
||||
std::string m_path_config;
|
||||
// Subgame specification
|
||||
SubgameSpec m_gamespec;
|
||||
|
||||
// Equivalent of /usr/share/minetest/server
|
||||
std::string m_path_share;
|
||||
// Equivalent of /usr/share/minetest/server/games/gamename
|
||||
std::string m_path_game;
|
||||
// Equivalent of /usr/share/minetest/server/addons/gamename
|
||||
// and ~/.minetest/server/addons/gamename
|
||||
std::set<std::string> m_path_addons;
|
||||
|
||||
// Some timers
|
||||
float m_liquid_transform_timer;
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
Minetest-c55
|
||||
Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
#include "subgame.h"
|
||||
#include "porting.h"
|
||||
#include "filesys.h"
|
||||
#include "settings.h"
|
||||
|
||||
SubgameSpec findSubgame(const std::string &id)
|
||||
{
|
||||
if(id == "")
|
||||
return SubgameSpec();
|
||||
std::string share_server = porting::path_share + DIR_DELIM + "server";
|
||||
std::string user_server = porting::path_user + DIR_DELIM + "server";
|
||||
// Find game directory
|
||||
std::string game_path =
|
||||
user_server + DIR_DELIM + "games" + DIR_DELIM + id;
|
||||
bool user_game = true; // Game is in user's directory
|
||||
if(!fs::PathExists(game_path)){
|
||||
game_path = share_server + DIR_DELIM + "games" + DIR_DELIM + id;
|
||||
user_game = false;
|
||||
}
|
||||
if(!fs::PathExists(game_path))
|
||||
return SubgameSpec();
|
||||
// Find addon directories
|
||||
std::set<std::string> addon_paths;
|
||||
if(!user_game)
|
||||
addon_paths.insert(share_server + DIR_DELIM + "addons"
|
||||
+ DIR_DELIM + id);
|
||||
addon_paths.insert(user_server + DIR_DELIM + "addons"
|
||||
+ DIR_DELIM + id);
|
||||
return SubgameSpec(id, game_path, addon_paths);
|
||||
}
|
||||
|
||||
std::set<std::string> getAvailableGameIds()
|
||||
{
|
||||
std::set<std::string> gameids;
|
||||
std::set<std::string> gamespaths;
|
||||
gamespaths.insert(porting::path_share + DIR_DELIM + "server"
|
||||
+ DIR_DELIM + "games");
|
||||
gamespaths.insert(porting::path_user + DIR_DELIM + "server"
|
||||
+ DIR_DELIM + "games");
|
||||
for(std::set<std::string>::const_iterator i = gamespaths.begin();
|
||||
i != gamespaths.end(); i++){
|
||||
std::vector<fs::DirListNode> dirlist = fs::GetDirListing(*i);
|
||||
for(u32 j=0; j<dirlist.size(); j++){
|
||||
if(!dirlist[j].dir)
|
||||
continue;
|
||||
gameids.insert(dirlist[j].name);
|
||||
}
|
||||
}
|
||||
return gameids;
|
||||
}
|
||||
|
||||
std::string getWorldGameId(const std::string &world_path)
|
||||
{
|
||||
std::string conf_path = world_path + DIR_DELIM + "world.mt";
|
||||
Settings conf;
|
||||
bool succeeded = conf.readConfigFile(conf_path.c_str());
|
||||
if(!succeeded)
|
||||
return "";
|
||||
if(!conf.exists("gameid"))
|
||||
return "";
|
||||
return conf.get("gameid");
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
Minetest-c55
|
||||
Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#ifndef SUBGAME_HEADER
|
||||
#define SUBGAME_HEADER
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
struct SubgameSpec
|
||||
{
|
||||
std::string id; // "" = game does not exist
|
||||
std::string path;
|
||||
std::set<std::string> addon_paths;
|
||||
|
||||
SubgameSpec(const std::string &id_="",
|
||||
const std::string &path_="",
|
||||
const std::set<std::string> &addon_paths_=std::set<std::string>()):
|
||||
id(id_),
|
||||
path(path_),
|
||||
addon_paths(addon_paths_)
|
||||
{}
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return (id != "" && path != "");
|
||||
}
|
||||
};
|
||||
|
||||
SubgameSpec findSubgame(const std::string &id);
|
||||
|
||||
std::set<std::string> getAvailableGameIds();
|
||||
|
||||
std::string getWorldGameId(const std::string &world_path);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue