1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-07-22 17:18:39 +00:00

new auto masterserver

This commit is contained in:
proller 2013-02-22 02:00:44 +04:00 committed by Ilya Zhuravlev
parent ef6b8bee07
commit ee07c3f7cf
20 changed files with 6919 additions and 49 deletions

View file

@ -5,6 +5,7 @@ cmake_minimum_required( VERSION 2.6 )
mark_as_advanced(EXECUTABLE_OUTPUT_PATH LIBRARY_OUTPUT_PATH)
mark_as_advanced(JTHREAD_INCLUDE_DIR JTHREAD_LIBRARY)
mark_as_advanced(SQLITE3_INCLUDE_DIR SQLITE3_LIBRARY)
mark_as_advanced(JSON_INCLUDE_DIR JSON_LIBRARY)
option(ENABLE_CURL "Enable cURL support for fetching media" 1)
@ -170,6 +171,7 @@ endif()
find_package(Jthread REQUIRED)
find_package(Sqlite3 REQUIRED)
find_package(Json REQUIRED)
if(USE_FREETYPE)
find_package(Freetype REQUIRED)
@ -242,6 +244,7 @@ set(common_SRCS
biome.cpp
clientserver.cpp
staticobject.cpp
serverlist.cpp
util/serialize.cpp
util/directiontables.cpp
util/numeric.cpp
@ -303,7 +306,6 @@ set(minetest_SRCS
filecache.cpp
tile.cpp
shader.cpp
serverlist.cpp
game.cpp
main.cpp
)
@ -332,6 +334,7 @@ include_directories(
${JTHREAD_INCLUDE_DIR}
${SQLITE3_INCLUDE_DIR}
${LUA_INCLUDE_DIR}
${JSON_INCLUDE_DIR}
)
if(USE_FREETYPE)
@ -341,6 +344,12 @@ if(USE_FREETYPE)
)
endif(USE_FREETYPE)
if(USE_CURL)
include_directories(
${CURL_INCLUDE_DIR}
)
endif(USE_CURL)
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/bin")
if(BUILD_CLIENT)
@ -359,18 +368,15 @@ if(BUILD_CLIENT)
${JTHREAD_LIBRARY}
${SQLITE3_LIBRARY}
${LUA_LIBRARY}
${JSON_LIBRARY}
${PLATFORM_LIBS}
${CLIENT_PLATFORM_LIBS}
)
if(USE_CURL)
target_link_libraries(
${PROJECT_NAME}
${CURL_LIBRARY}
)
include_directories(
${CURL_INCLUDE_DIR}
)
endif(USE_CURL)
if(USE_FREETYPE)
target_link_libraries(
@ -388,12 +394,20 @@ if(BUILD_SERVER)
${ZLIB_LIBRARIES}
${JTHREAD_LIBRARY}
${SQLITE3_LIBRARY}
${JSON_LIBRARY}
${GETTEXT_LIBRARY}
${LUA_LIBRARY}
${PLATFORM_LIBS}
)
if(USE_CURL)
target_link_libraries(
${PROJECT_NAME}server
${CURL_LIBRARY}
)
endif(USE_CURL)
endif(BUILD_SERVER)
#
# Set some optimizations and tweaks
#
@ -569,4 +583,9 @@ else (LUA_FOUND)
add_subdirectory(lua)
endif (LUA_FOUND)
if (JSON_FOUND)
else (JSON_FOUND)
add_subdirectory(json)
endif (JSON_FOUND)
#end

View file

@ -130,8 +130,13 @@ void set_default_settings(Settings *settings)
settings->setDefault("media_fetch_threads", "8");
settings->setDefault("serverlist_url", "servers.minetest.ru/server.list");
settings->setDefault("serverlist_url", "servers.minetest.net");
settings->setDefault("serverlist_file", "favoriteservers.txt");
settings->setDefault("server_announce", "false");
settings->setDefault("server_url", "");
settings->setDefault("server_address", "");
settings->setDefault("server_name", "");
settings->setDefault("server_description", "");
settings->setDefault("font_path", porting::getDataPath("fonts" DIR_DELIM "liberationsans.ttf"));
settings->setDefault("font_size", "13");

View file

@ -108,6 +108,7 @@ enum
GUI_ID_ENABLE_PARTICLES_CB,
GUI_ID_DAMAGE_CB,
GUI_ID_CREATIVE_CB,
GUI_ID_PUBLIC_CB,
GUI_ID_JOIN_GAME_BUTTON,
GUI_ID_CHANGE_KEYS_BUTTON,
GUI_ID_DELETE_WORLD_BUTTON,
@ -562,6 +563,14 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
Environment->addCheckBox(m_data->enable_damage, rect, this, GUI_ID_DAMAGE_CB,
wgettext("Enable Damage"));
}
#if USE_CURL
{
core::rect<s32> rect(0, 0, 250, 30);
rect += m_topleft_server + v2s32(30+20+250+20, 60);
Environment->addCheckBox(m_data->enable_public, rect, this, GUI_ID_PUBLIC_CB,
wgettext("Public"));
}
#endif
// Delete world button
{
core::rect<s32> rect(0, 0, 130, 30);
@ -841,6 +850,11 @@ void GUIMainMenu::readInput(MainMenuData *dst)
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
dst->enable_damage = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_PUBLIC_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
dst->enable_public = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_FANCYTREE_CB);
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
@ -912,8 +926,8 @@ void GUIMainMenu::readInput(MainMenuData *dst)
{
ServerListSpec server =
getServerListSpec(wide_to_narrow(dst->address), wide_to_narrow(dst->port));
dst->servername = server.name;
dst->serverdescription = server.description;
dst->servername = server["name"].asString();
dst->serverdescription = server["description"].asString();
}
}
@ -1174,13 +1188,31 @@ void GUIMainMenu::updateGuiServerList()
i != m_data->servers.end(); i++)
{
std::string text;
if (i->name != "" && i->description != "")
text = i->name + " (" + i->description + ")";
else if (i->name !="")
text = i->name;
else
text = i->address + ":" + i->port;
if ((*i)["clients"].asString().size())
text += (*i)["clients"].asString();
if ((*i)["clients_max"].asString().size())
text += "/" + (*i)["clients_max"].asString();
text += " ";
if ((*i)["version"].asString().size())
text += (*i)["version"].asString() + " ";
if ((*i)["password"].asString().size())
text += "*";
if ((*i)["creative"].asString().size())
text += "C";
if ((*i)["damage"].asString().size())
text += "D";
if ((*i)["pvp"].asString().size())
text += "P";
text += " ";
if ((*i)["name"] != "" && (*i)["description"] != "")
text += (*i)["name"].asString() + " (" + (*i)["description"].asString() + ")";
else if ((*i)["name"] !="")
text += (*i)["name"].asString();
else
text += (*i)["address"].asString() + ":" + (*i)["port"].asString();
serverlist->addItem(narrow_to_wide(text).c_str());
}
}
@ -1191,26 +1223,26 @@ void GUIMainMenu::serverListOnSelected()
{
gui::IGUIListBox *serverlist = (gui::IGUIListBox*)getElementFromId(GUI_ID_SERVERLIST);
u16 id = serverlist->getSelected();
if (id < 0) return;
//if (id < 0) return; // u16>0!
((gui::IGUIEditBox*)getElementFromId(GUI_ID_ADDRESS_INPUT))
->setText(narrow_to_wide(m_data->servers[id].address).c_str());
->setText(narrow_to_wide(m_data->servers[id]["address"].asString()).c_str());
((gui::IGUIEditBox*)getElementFromId(GUI_ID_PORT_INPUT))
->setText(narrow_to_wide(m_data->servers[id].port).c_str());
->setText(narrow_to_wide(m_data->servers[id]["port"].asString()).c_str());
}
}
ServerListSpec GUIMainMenu::getServerListSpec(std::string address, std::string port)
{
ServerListSpec server;
server.address = address;
server.port = port;
server["address"] = address;
server["port"] = port;
for(std::vector<ServerListSpec>::iterator i = m_data->servers.begin();
i != m_data->servers.end(); i++)
{
if (i->address == address && i->port == port)
if ((*i)["address"] == address && (*i)["port"] == port)
{
server.description = i->description;
server.name = i->name;
server["description"] = (*i)["description"];
server["name"] = (*i)["name"];
break;
}
}

View file

@ -55,6 +55,7 @@ struct MainMenuData
// Server options
bool creative_mode;
bool enable_damage;
bool enable_public;
int selected_world;
bool simple_singleplayer_mode;
// Actions
@ -77,6 +78,7 @@ struct MainMenuData
// Server opts
creative_mode(false),
enable_damage(false),
enable_public(false),
selected_world(0),
simple_singleplayer_mode(false),
// Actions

14
src/json/CMakeLists.txt Normal file
View file

@ -0,0 +1,14 @@
if( UNIX )
set(json_SRCS jsoncpp.cpp)
set(json_platform_LIBS "")
else( UNIX )
set(json_SRCS jsoncpp.cpp)
set(json_platform_LIBS "")
endif( UNIX )
add_library(json ${json_SRCS})
target_link_libraries(
json
${json_platform_LIBS}
)

16
src/json/UPDATING Normal file
View file

@ -0,0 +1,16 @@
#!/bin/sh
cd ..
svn co https://jsoncpp.svn.sourceforge.net/svnroot/jsoncpp/trunk/jsoncpp jsoncpp
svn up jsoncpp
cd jsoncpp
python amalgamate.py
cp -R dist/json ..
cp dist/jsoncpp.cpp ../json
# maybe you need to patch:
# src/json/jsoncpp.cpp:
# -#include <json/json.h>
# +#include "json/json.h"
#svn export --force https://jsoncpp.svn.sourceforge.net/svnroot/jsoncpp/trunk/jsoncpp/src/lib_json json
#svn export --force https://jsoncpp.svn.sourceforge.net/svnroot/jsoncpp/trunk/jsoncpp/include/json json

1914
src/json/json.h Normal file

File diff suppressed because it is too large Load diff

4367
src/json/jsoncpp.cpp Normal file

File diff suppressed because it is too large Load diff

View file

@ -1095,6 +1095,7 @@ int main(int argc, char *argv[])
#else
bool run_dedicated_server = cmd_args.getFlag("server");
#endif
g_settings->set("server_dedicated", run_dedicated_server ? "true" : "false");
if(run_dedicated_server)
{
DSTACK("Dedicated server branch");
@ -1593,6 +1594,7 @@ int main(int argc, char *argv[])
g_settings->set("creative_mode", itos(menudata.creative_mode));
g_settings->set("enable_damage", itos(menudata.enable_damage));
g_settings->set("server_announce", itos(menudata.enable_public));
g_settings->set("name", playername);
g_settings->set("address", address);
g_settings->set("port", itos(port));
@ -1619,10 +1621,10 @@ int main(int argc, char *argv[])
else if (address != "")
{
ServerListSpec server;
server.name = menudata.servername;
server.address = wide_to_narrow(menudata.address);
server.port = wide_to_narrow(menudata.port);
server.description = menudata.serverdescription;
server["name"] = menudata.servername;
server["address"] = wide_to_narrow(menudata.address);
server["port"] = wide_to_narrow(menudata.port);
server["description"] = menudata.serverdescription;
ServerList::insert(server);
}

View file

@ -51,6 +51,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "sound.h" // dummySoundManager
#include "event_manager.h"
#include "hex.h"
#include "serverlist.h"
#include "util/string.h"
#include "util/pointedthing.h"
#include "util/mathconstants.h"
@ -961,9 +962,11 @@ Server::Server(
{
m_liquid_transform_timer = 0.0;
m_print_info_timer = 0.0;
m_masterserver_timer = 0.0;
m_objectdata_timer = 0.0;
m_emergethread_trigger_timer = 0.0;
m_savemap_timer = 0.0;
m_clients_number = 0;
m_env_mutex.Init();
m_con_mutex.Init();
@ -1505,7 +1508,7 @@ void Server::AsyncRunStep()
counter = 0.0;
JMutexAutoLock lock2(m_con_mutex);
m_clients_number = 0;
if(m_clients.size() != 0)
infostream<<"Players:"<<std::endl;
for(core::map<u16, RemoteClient*>::Iterator
@ -1519,10 +1522,25 @@ void Server::AsyncRunStep()
continue;
infostream<<"* "<<player->getName()<<"\t";
client->PrintInfo(infostream);
++m_clients_number;
}
}
}
#if USE_CURL
// send masterserver announce
{
float &counter = m_masterserver_timer;
if((!counter || counter >= 300.0) && g_settings->getBool("server_announce") == true)
{
ServerList::sendAnnounce(!counter ? "start" : "update", m_clients_number);
counter = 0.01;
}
counter += dtime;
}
#endif
//if(g_settings->getBool("enable_experimental"))
{
@ -5186,6 +5204,10 @@ void dedicated_server_loop(Server &server, bool &kill)
if(server.getShutdownRequested() || kill)
{
infostream<<"Dedicated server quitting"<<std::endl;
#if USE_CURL
if(g_settings->getBool("server_announce") == true)
ServerList::sendAnnounce("delete");
#endif
break;
}

View file

@ -720,6 +720,7 @@ private:
// Some timers
float m_liquid_transform_timer;
float m_print_info_timer;
float m_masterserver_timer;
float m_objectdata_timer;
float m_emergethread_trigger_timer;
float m_savemap_timer;
@ -737,6 +738,7 @@ private:
JMutex m_con_mutex;
// Connected clients (behind the con mutex)
core::map<u16, RemoteClient*> m_clients;
u16 m_clients_number; //for announcing masterserver
// Bann checking
BanManager m_banmanager;

View file

@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "filesys.h"
#include "porting.h"
#include "log.h"
#include "json/json.h"
#if USE_CURL
#include <curl/curl.h>
#endif
@ -83,7 +84,7 @@ std::vector<ServerListSpec> getOnline()
{
CURLcode res;
curl_easy_setopt(curl, CURLOPT_URL, g_settings->get("serverlist_url").c_str());
curl_easy_setopt(curl, CURLOPT_URL, (g_settings->get("serverlist_url")+"/list").c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ServerList::WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &liststring);
@ -92,8 +93,7 @@ std::vector<ServerListSpec> getOnline()
errorstream<<"Serverlist at url "<<g_settings->get("serverlist_url")<<" not found (internet connection?)"<<std::endl;
curl_easy_cleanup(curl);
}
return ServerList::deSerialize(liststring);
return ServerList::deSerializeJson(liststring);
}
#endif
@ -106,8 +106,8 @@ bool deleteEntry (ServerListSpec server)
std::vector<ServerListSpec> serverlist = ServerList::getLocal();
for(unsigned i = 0; i < serverlist.size(); i++)
{
if (serverlist[i].address == server.address
&& serverlist[i].port == server.port)
if (serverlist[i]["address"] == server["address"]
&& serverlist[i]["port"] == server["port"])
{
serverlist.erase(serverlist.begin() + i);
}
@ -150,17 +150,21 @@ std::vector<ServerListSpec> deSerialize(std::string liststring)
{
std::vector<ServerListSpec> serverlist;
std::istringstream stream(liststring);
std::string line;
std::string line, tmp;
while (std::getline(stream, line))
{
std::transform(line.begin(), line.end(),line.begin(), ::toupper);
if (line == "[SERVER]")
{
ServerListSpec thisserver;
std::getline(stream, thisserver.name);
std::getline(stream, thisserver.address);
std::getline(stream, thisserver.port);
std::getline(stream, thisserver.description);
std::getline(stream, tmp);
thisserver["name"] = tmp;
std::getline(stream, tmp);
thisserver["address"] = tmp;
std::getline(stream, tmp);
thisserver["port"] = tmp;
std::getline(stream, tmp);
thisserver["description"] = tmp;
serverlist.push_back(thisserver);
}
}
@ -173,13 +177,100 @@ std::string serialize(std::vector<ServerListSpec> serverlist)
for(std::vector<ServerListSpec>::iterator i = serverlist.begin(); i != serverlist.end(); i++)
{
liststring += "[server]\n";
liststring += i->name + "\n";
liststring += i->address + "\n";
liststring += i->port + "\n";
liststring += i->description + "\n";
liststring += (*i)["name"].asString() + "\n";
liststring += (*i)["address"].asString() + "\n";
liststring += (*i)["port"].asString() + "\n";
liststring += (*i)["description"].asString() + "\n";
liststring += "\n";
}
return liststring;
}
std::vector<ServerListSpec> deSerializeJson(std::string liststring)
{
std::vector<ServerListSpec> serverlist;
Json::Value root;
Json::Reader reader;
std::istringstream stream(liststring);
if (!liststring.size()) {
return serverlist;
}
if (!reader.parse( stream, root ) )
{
errorstream << "Failed to parse server list " << reader.getFormattedErrorMessages();
return serverlist;
}
if (root["list"].isArray())
for (unsigned int i = 0; i < root["list"].size(); i++)
{
if (root["list"][i].isObject()) {
serverlist.push_back(root["list"][i]);
}
}
return serverlist;
}
std::string serializeJson(std::vector<ServerListSpec> serverlist)
{
Json::Value root;
Json::Value list(Json::arrayValue);
for(std::vector<ServerListSpec>::iterator i = serverlist.begin(); i != serverlist.end(); i++)
{
list.append(*i);
}
root["list"] = list;
Json::StyledWriter writer;
return writer.write( root );
}
#if USE_CURL
static size_t ServerAnnounceCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
return 0;
//((std::string*)userp)->append((char*)contents, size * nmemb);
//return size * nmemb;
}
void sendAnnounce(std::string action, u16 clients) {
Json::Value server;
if (action.size())
server["action"] = action;
server["port"] = g_settings->get("port");
if (action != "del") {
server["name"] = g_settings->get("server_name");
server["description"] = g_settings->get("server_description");
server["address"] = g_settings->get("server_address");
server["version"] = VERSION_STRING;
server["url"] = g_settings->get("server_url");
server["creative"] = g_settings->get("creative_mode");
server["damage"] = g_settings->get("enable_damage");
server["dedicated"] = g_settings->get("server_dedicated");
server["password"] = g_settings->getBool("disallow_empty_password");
server["pvp"] = g_settings->getBool("enable_pvp");
server["clients"] = clients;
server["clients_max"] = g_settings->get("max_users");
}
if(server["action"] == "start")
actionstream << "announcing to " << g_settings->get("serverlist_url") << std::endl;
Json::StyledWriter writer;
CURL *curl;
curl = curl_easy_init();
if (curl)
{
CURLcode res;
curl_easy_setopt(curl, CURLOPT_URL, (g_settings->get("serverlist_url")+std::string("/announce?json=")+curl_easy_escape(curl, writer.write( server ).c_str(), 0)).c_str());
//curl_easy_setopt(curl, CURLOPT_USERAGENT, "minetest");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ServerList::ServerAnnounceCallback);
//curl_easy_setopt(curl, CURLOPT_WRITEDATA, &liststring);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 1);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 1);
res = curl_easy_perform(curl);
//if (res != CURLE_OK)
// errorstream<<"Serverlist at url "<<g_settings->get("serverlist_url")<<" not found (internet connection?)"<<std::endl;
curl_easy_cleanup(curl);
}
}
#endif
} //namespace ServerList

View file

@ -19,17 +19,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <iostream>
#include "config.h"
#include "json/json.h"
#ifndef SERVERLIST_HEADER
#define SERVERLIST_HEADER
struct ServerListSpec
{
std::string name;
std::string address;
std::string port;
std::string description;
};
typedef Json::Value ServerListSpec;
namespace ServerList
{
@ -41,6 +36,11 @@ namespace ServerList
bool insert(ServerListSpec server);
std::vector<ServerListSpec> deSerialize(std::string liststring);
std::string serialize(std::vector<ServerListSpec>);
std::vector<ServerListSpec> deSerializeJson(std::string liststring);
std::string serializeJson(std::vector<ServerListSpec>);
#if USE_CURL
void sendAnnounce(std::string action = "", u16 clients = 0);
#endif
} //ServerList namespace
#endif