forked from teamnwah/openmw-tes3coop
Added master server stuff
This commit is contained in:
parent
02a447c589
commit
c695923825
7 changed files with 268 additions and 6 deletions
|
@ -48,6 +48,7 @@ set(SERVER
|
||||||
Networking.cpp
|
Networking.cpp
|
||||||
Utils.cpp
|
Utils.cpp
|
||||||
Log.cpp
|
Log.cpp
|
||||||
|
MasterClient.cpp
|
||||||
Script/Script.cpp Script/ScriptFunction.cpp
|
Script/Script.cpp Script/ScriptFunction.cpp
|
||||||
Script/ScriptFunctions.cpp
|
Script/ScriptFunctions.cpp
|
||||||
Script/Functions/Translocations.cpp Script/Functions/Stats.cpp Script/Functions/Items.cpp
|
Script/Functions/Translocations.cpp Script/Functions/Stats.cpp Script/Functions/Items.cpp
|
||||||
|
|
172
apps/openmw-mp/MasterClient.cpp
Normal file
172
apps/openmw-mp/MasterClient.cpp
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
//
|
||||||
|
// Created by koncord on 14.08.16.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <RakSleep.h>
|
||||||
|
#include <Getche.h>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <RakPeerInterface.h>
|
||||||
|
#include "MasterClient.hpp"
|
||||||
|
#include "Log.hpp"
|
||||||
|
#include "Networking.hpp"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
bool MasterClient::sRun = false;
|
||||||
|
|
||||||
|
MasterClient::MasterClient(std::string queryAddr, unsigned short queryPort, std::string serverAddr,
|
||||||
|
unsigned short serverPort) : queryAddr(queryAddr), queryPort(queryPort),
|
||||||
|
serverAddr(serverAddr), serverPort(serverPort)
|
||||||
|
{
|
||||||
|
httpConnection = RakNet::HTTPConnection2::GetInstance();
|
||||||
|
tcpInterface.Start(0, 64);
|
||||||
|
tcpInterface.AttachPlugin(httpConnection);
|
||||||
|
players = 0;
|
||||||
|
maxPlayers = 0;
|
||||||
|
motd = "";
|
||||||
|
timeout = 1000; // every 1 seconds
|
||||||
|
}
|
||||||
|
|
||||||
|
void MasterClient::SetPlayers(unsigned pl)
|
||||||
|
{
|
||||||
|
mutexData.lock();
|
||||||
|
players = pl;
|
||||||
|
mutexData.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MasterClient::SetMaxPlayers(unsigned pl)
|
||||||
|
{
|
||||||
|
mutexData.lock();
|
||||||
|
maxPlayers = pl;
|
||||||
|
mutexData.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MasterClient::SetMOTD(std::string &motd)
|
||||||
|
{
|
||||||
|
mutexData.lock();
|
||||||
|
this->motd = motd.substr(0, 200);
|
||||||
|
mutexData.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
RakNet::RakString MasterClient::Send(std::string motd, unsigned players, unsigned maxPlayers, bool update)
|
||||||
|
{
|
||||||
|
/*static unsigned short oldServerPort, oldQueryPort;
|
||||||
|
static string oldMotd;
|
||||||
|
static unsigned oldPlayers, oldMaxPlayers;*/
|
||||||
|
std::stringstream sstr;
|
||||||
|
mutexData.lock();
|
||||||
|
sstr << "{";
|
||||||
|
sstr << "\"port\": " << serverPort << ", ";
|
||||||
|
sstr << "\"query_port\": " << queryPort << ", ";
|
||||||
|
sstr << "\"motd\": \"" << motd << "\", ";
|
||||||
|
sstr << "\"players\": " << players << ", ";
|
||||||
|
sstr << "\"max_players\": " << maxPlayers;
|
||||||
|
sstr << "}";
|
||||||
|
mutexData.unlock();
|
||||||
|
|
||||||
|
std::string contentType = "application/json";
|
||||||
|
RakNet::RakString createRequest;
|
||||||
|
|
||||||
|
if (update)
|
||||||
|
createRequest = RakNet::RakString::FormatForPUT(
|
||||||
|
string("/api/servers/" + serverAddr + ":" + to_string(serverPort)).c_str(), contentType.c_str(),
|
||||||
|
sstr.str().c_str());
|
||||||
|
else
|
||||||
|
createRequest = RakNet::RakString::FormatForPOST("/api/servers", contentType.c_str(),
|
||||||
|
sstr.str().c_str());
|
||||||
|
|
||||||
|
httpConnection->TransmitRequest(createRequest.C_String(), queryAddr.c_str(), queryPort);
|
||||||
|
|
||||||
|
RakNet::Packet *packet;
|
||||||
|
RakNet::SystemAddress sa;
|
||||||
|
|
||||||
|
RakNet::RakString transmitted, hostTransmitted;
|
||||||
|
RakNet::RakString response;
|
||||||
|
RakNet::SystemAddress hostReceived;
|
||||||
|
int contentOffset;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
|
||||||
|
// This is kind of crappy, but for TCP plugins, always do HasCompletedConnectionAttempt,
|
||||||
|
// then Receive(), then HasFailedConnectionAttempt(),HasLostConnection()
|
||||||
|
sa = tcpInterface.HasCompletedConnectionAttempt();
|
||||||
|
if (sa != RakNet::UNASSIGNED_SYSTEM_ADDRESS)
|
||||||
|
LOG_MESSAGE_SIMPLE(Log::INFO, "Connected to master server: %s", sa.ToString());
|
||||||
|
|
||||||
|
sa = tcpInterface.HasFailedConnectionAttempt();
|
||||||
|
if (sa != RakNet::UNASSIGNED_SYSTEM_ADDRESS)
|
||||||
|
{
|
||||||
|
LOG_MESSAGE_SIMPLE(Log::WARNING, "Failed to connect to master server: %s", sa.ToString());
|
||||||
|
return "FAIL_CONNECT";
|
||||||
|
}
|
||||||
|
sa = tcpInterface.HasLostConnection();
|
||||||
|
if (sa != RakNet::UNASSIGNED_SYSTEM_ADDRESS)
|
||||||
|
{
|
||||||
|
LOG_MESSAGE_SIMPLE(Log::WARNING, "Lost connection to master server: %s", sa.ToString());
|
||||||
|
return "LOST_CONNECTION";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (packet = tcpInterface.Receive(); packet; tcpInterface.DeallocatePacket(
|
||||||
|
packet), packet = tcpInterface.Receive());
|
||||||
|
|
||||||
|
if (httpConnection->GetResponse(transmitted, hostTransmitted, response, hostReceived, contentOffset))
|
||||||
|
{
|
||||||
|
if(contentOffset < 0)
|
||||||
|
return "NO_CONTENT"; // no content
|
||||||
|
tcpInterface.CloseConnection(sa);
|
||||||
|
return (response.C_String() + contentOffset);
|
||||||
|
}
|
||||||
|
RakSleep(30);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MasterClient::Update()
|
||||||
|
{
|
||||||
|
assert(!sRun);
|
||||||
|
RakNet::RakString response = Send(motd, players, maxPlayers, false);
|
||||||
|
bool update = true;
|
||||||
|
sRun = true;
|
||||||
|
while (sRun)
|
||||||
|
{
|
||||||
|
if (response == "Created")
|
||||||
|
LOG_MESSAGE_SIMPLE(Log::INFO, "Server registered on the master server.", "");
|
||||||
|
else if (response == "Accepted")
|
||||||
|
LOG_MESSAGE_SIMPLE(Log::INFO, "Server updated information about himself on the master server.", "");
|
||||||
|
else if (response == "bad request")
|
||||||
|
{
|
||||||
|
LOG_MESSAGE_SIMPLE(Log::WARNING, "Update rate is too low, and the master server has deleted information about"
|
||||||
|
" the server. Trying low rate...", "");
|
||||||
|
SetUpdateRate(timeout - step_rate);
|
||||||
|
update = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*cout << "Error: \""<< response << "\"" << endl;
|
||||||
|
cout << response.GetLength() << endl;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
RakSleep(timeout);
|
||||||
|
;
|
||||||
|
players = mwmp::Networking::Get().NumberOfConnections();
|
||||||
|
response = Send(motd, players, maxPlayers, update);
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MasterClient::Stop()
|
||||||
|
{
|
||||||
|
sRun = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MasterClient::SetUpdateRate(unsigned int rate)
|
||||||
|
{
|
||||||
|
if(timeout < min_rate)
|
||||||
|
timeout = min_rate;
|
||||||
|
else if (timeout > max_rate)
|
||||||
|
timeout = max_rate;
|
||||||
|
timeout = rate;
|
||||||
|
}
|
46
apps/openmw-mp/MasterClient.hpp
Normal file
46
apps/openmw-mp/MasterClient.hpp
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
//
|
||||||
|
// Created by koncord on 14.08.16.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef OPENMW_MASTERCLIENT_HPP
|
||||||
|
#define OPENMW_MASTERCLIENT_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <raknet/HTTPConnection2.h>
|
||||||
|
#include <raknet/TCPInterface.h>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
class MasterClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const unsigned int step_rate = 1000;
|
||||||
|
static const unsigned int min_rate = 1000;
|
||||||
|
static const unsigned int max_rate = 30000;
|
||||||
|
public:
|
||||||
|
MasterClient(std::string queryAddr, unsigned short queryPort, std::string serverAddr, unsigned short serverPort);
|
||||||
|
void SetPlayers(unsigned pl);
|
||||||
|
void SetMaxPlayers(unsigned pl);
|
||||||
|
void SetMOTD(std::string &motd);
|
||||||
|
void Update();
|
||||||
|
void Stop();
|
||||||
|
void SetUpdateRate(unsigned int rate);
|
||||||
|
|
||||||
|
private:
|
||||||
|
RakNet::RakString Send(std::string motd, unsigned players, unsigned maxPlayers, bool update = true);
|
||||||
|
private:
|
||||||
|
std::string queryAddr;
|
||||||
|
unsigned short queryPort;
|
||||||
|
std::string serverAddr;
|
||||||
|
unsigned short serverPort;
|
||||||
|
std::string motd;
|
||||||
|
unsigned players, maxPlayers;
|
||||||
|
RakNet::HTTPConnection2 *httpConnection;
|
||||||
|
RakNet::TCPInterface tcpInterface;
|
||||||
|
unsigned int timeout;
|
||||||
|
static bool sRun;
|
||||||
|
std::mutex mutexData;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //OPENMW_MASTERCLIENT_HPP
|
|
@ -402,3 +402,8 @@ void Networking::KickPlayer(RakNet::RakNetGUID guid)
|
||||||
{
|
{
|
||||||
peer->CloseConnection(guid, true);
|
peer->CloseConnection(guid, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned short Networking::NumberOfConnections() const
|
||||||
|
{
|
||||||
|
return peer->NumberOfConnections();
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#define OPENMW_NETWORKING_HPP
|
#define OPENMW_NETWORKING_HPP
|
||||||
|
|
||||||
#include <components/openmw-mp/PacketsController.hpp>
|
#include <components/openmw-mp/PacketsController.hpp>
|
||||||
|
#include "Player.hpp"
|
||||||
|
|
||||||
namespace mwmp
|
namespace mwmp
|
||||||
{
|
{
|
||||||
|
@ -19,6 +20,7 @@ namespace mwmp
|
||||||
void DisconnectPlayer(RakNet::RakNetGUID guid);
|
void DisconnectPlayer(RakNet::RakNetGUID guid);
|
||||||
void KickPlayer(RakNet::RakNetGUID guid);
|
void KickPlayer(RakNet::RakNetGUID guid);
|
||||||
void Update(RakNet::Packet *packet);
|
void Update(RakNet::Packet *packet);
|
||||||
|
unsigned short NumberOfConnections() const;
|
||||||
|
|
||||||
int MainLoop();
|
int MainLoop();
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <BitStream.h>
|
#include <BitStream.h>
|
||||||
#include "Player.hpp"
|
#include "Player.hpp"
|
||||||
#include "Networking.hpp"
|
#include "Networking.hpp"
|
||||||
|
#include "MasterClient.hpp"
|
||||||
#include "Log.hpp"
|
#include "Log.hpp"
|
||||||
#include <RakPeer.h>
|
#include <RakPeer.h>
|
||||||
#include <MessageIdentifiers.h>
|
#include <MessageIdentifiers.h>
|
||||||
|
@ -10,6 +11,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace mwmp;
|
using namespace mwmp;
|
||||||
|
@ -64,6 +66,11 @@ std::string loadSettings (Settings::Manager & settings)
|
||||||
return settingspath;
|
return settingspath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void queryThread(MasterClient *mclient)
|
||||||
|
{
|
||||||
|
mclient->Update();
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
Settings::Manager mgr;
|
Settings::Manager mgr;
|
||||||
|
@ -76,6 +83,7 @@ int main(int argc, char *argv[])
|
||||||
LOG_INIT(logLevel);
|
LOG_INIT(logLevel);
|
||||||
|
|
||||||
int players = mgr.getInt("players", "General");
|
int players = mgr.getInt("players", "General");
|
||||||
|
string addr = mgr.getString("address", "General");
|
||||||
int port = mgr.getInt("port", "General");
|
int port = mgr.getInt("port", "General");
|
||||||
|
|
||||||
string plugin_home = mgr.getString("home", "Plugins");
|
string plugin_home = mgr.getString("home", "Plugins");
|
||||||
|
@ -99,7 +107,7 @@ int main(int argc, char *argv[])
|
||||||
const char passw[8] = "1234567";
|
const char passw[8] = "1234567";
|
||||||
peer->SetIncomingPassword(passw, sizeof(passw));
|
peer->SetIncomingPassword(passw, sizeof(passw));
|
||||||
|
|
||||||
RakNet::SocketDescriptor sd((unsigned short)port, 0);
|
RakNet::SocketDescriptor sd((unsigned short)port, addr.c_str());
|
||||||
if (peer->Startup((unsigned)players, &sd, 1) != RakNet::RAKNET_STARTED)
|
if (peer->Startup((unsigned)players, &sd, 1) != RakNet::RAKNET_STARTED)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -107,11 +115,33 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
Networking networking(peer);
|
Networking networking(peer);
|
||||||
|
|
||||||
|
bool masterEnabled = mgr.getBool("enabled", "MasterServer");
|
||||||
|
thread thrQuery;
|
||||||
|
MasterClient *mclient;
|
||||||
|
if(masterEnabled)
|
||||||
|
{
|
||||||
|
LOG_MESSAGE_SIMPLE(Log::INFO, "%s", "Sharing server query info to master enabled.");
|
||||||
|
string masterAddr = mgr.getString("address", "MasterServer");
|
||||||
|
int masterPort = mgr.getInt("port", "MasterServer");
|
||||||
|
mclient = new MasterClient(masterAddr, (unsigned short) masterPort, addr, (unsigned short) port);
|
||||||
|
mclient->SetMaxPlayers((unsigned)players);
|
||||||
|
string motd = mgr.getString("motd", "General");
|
||||||
|
mclient->SetMOTD(motd);
|
||||||
|
thrQuery = thread(queryThread, mclient);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int code = networking.MainLoop();
|
int code = networking.MainLoop();
|
||||||
|
|
||||||
RakNet::RakPeerInterface::DestroyInstance(peer);
|
RakNet::RakPeerInterface::DestroyInstance(peer);
|
||||||
|
|
||||||
|
if(thrQuery.joinable())
|
||||||
|
{
|
||||||
|
mclient->Stop();
|
||||||
|
thrQuery.join();
|
||||||
|
}
|
||||||
|
|
||||||
if (code == 0)
|
if (code == 0)
|
||||||
printf("Quitting peacefully.\n");
|
|
||||||
LOG_MESSAGE_SIMPLE(Log::INFO, "%s", "Quitting peacefully.");
|
LOG_MESSAGE_SIMPLE(Log::INFO, "%s", "Quitting peacefully.");
|
||||||
|
|
||||||
LOG_QUIT();
|
LOG_QUIT();
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
[General]
|
[General]
|
||||||
;master = master.tes3mp.com:8088
|
# from 3 to 0. 3 - only errors, 0 - all messages
|
||||||
|
loglevel = 0
|
||||||
|
motd = My TES3MP server
|
||||||
|
address = server.tes3mp.com
|
||||||
port = 25565
|
port = 25565
|
||||||
;query = false #enable query server
|
|
||||||
;query-port = 25566
|
|
||||||
players = 4
|
players = 4
|
||||||
|
|
||||||
[Plugins]
|
[Plugins]
|
||||||
;home = ~/local/openmw/tes3mp
|
#home = ~/local/openmw/tes3mp
|
||||||
home = ~/ClionProjects/PS-dev
|
home = ~/ClionProjects/PS-dev
|
||||||
plugins = tes3mp.lua,chat_parser.lua
|
plugins = tes3mp.lua,chat_parser.lua
|
||||||
|
|
||||||
|
[MasterServer]
|
||||||
|
enabled = true
|
||||||
|
address = master.tes3mp.com
|
||||||
|
port = 8080
|
||||||
|
rate = 1000
|
Loading…
Reference in a new issue