mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-15 11:03:00 +01:00
master server list
This commit is contained in:
@@ -41,6 +41,7 @@ extern "C" {
|
||||
#include "../interface/window.h"
|
||||
#include "../localisation/date.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../network/http.h"
|
||||
#include "../scenario.h"
|
||||
#include "../windows/error.h"
|
||||
#include "../util/util.h"
|
||||
@@ -67,6 +68,7 @@ enum {
|
||||
NETWORK_COMMAND_PING,
|
||||
NETWORK_COMMAND_PINGLIST,
|
||||
NETWORK_COMMAND_SETDISCONNECTMSG,
|
||||
NETWORK_COMMAND_GAMEINFO,
|
||||
NETWORK_COMMAND_MAX,
|
||||
NETWORK_COMMAND_INVALID = -1
|
||||
};
|
||||
@@ -161,8 +163,8 @@ bool NetworkPacket::CommandRequiresAuth()
|
||||
{
|
||||
switch (GetCommand()) {
|
||||
case NETWORK_COMMAND_PING:
|
||||
return false;
|
||||
case NETWORK_COMMAND_AUTH:
|
||||
case NETWORK_COMMAND_GAMEINFO:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
@@ -254,11 +256,15 @@ bool NetworkConnection::SendPacket(NetworkPacket& packet)
|
||||
return false;
|
||||
}
|
||||
|
||||
void NetworkConnection::QueuePacket(std::unique_ptr<NetworkPacket> packet)
|
||||
void NetworkConnection::QueuePacket(std::unique_ptr<NetworkPacket> packet, bool front)
|
||||
{
|
||||
if (authstatus == NETWORK_AUTH_OK || !packet->CommandRequiresAuth()) {
|
||||
packet->size = (uint16)packet->data->size();
|
||||
outboundpackets.push_back(std::move(packet));
|
||||
if (front) {
|
||||
outboundpackets.push_front(std::move(packet));
|
||||
} else {
|
||||
outboundpackets.push_back(std::move(packet));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,7 +384,7 @@ Network::Network()
|
||||
status = NETWORK_STATUS_NONE;
|
||||
last_tick_sent_time = 0;
|
||||
last_ping_sent_time = 0;
|
||||
strcpy(password, "");
|
||||
last_advertise_time = 0;
|
||||
client_command_handlers.resize(NETWORK_COMMAND_MAX, 0);
|
||||
client_command_handlers[NETWORK_COMMAND_AUTH] = &Network::Client_Handle_AUTH;
|
||||
client_command_handlers[NETWORK_COMMAND_MAP] = &Network::Client_Handle_MAP;
|
||||
@@ -394,6 +400,7 @@ Network::Network()
|
||||
server_command_handlers[NETWORK_COMMAND_CHAT] = &Network::Server_Handle_CHAT;
|
||||
server_command_handlers[NETWORK_COMMAND_GAMECMD] = &Network::Server_Handle_GAMECMD;
|
||||
server_command_handlers[NETWORK_COMMAND_PING] = &Network::Server_Handle_PING;
|
||||
server_command_handlers[NETWORK_COMMAND_GAMEINFO] = &Network::Server_Handle_GAMEINFO;
|
||||
}
|
||||
|
||||
Network::~Network()
|
||||
@@ -447,6 +454,10 @@ void Network::Close()
|
||||
|
||||
bool Network::BeginClient(const char* host, unsigned short port)
|
||||
{
|
||||
if (GetMode() != NETWORK_MODE_NONE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Close();
|
||||
if (!Init())
|
||||
return false;
|
||||
@@ -508,6 +519,10 @@ bool Network::BeginServer(unsigned short port, const char* address)
|
||||
printf("Ready for clients...\n");
|
||||
|
||||
mode = NETWORK_MODE_SERVER;
|
||||
status = NETWORK_STATUS_CONNECTED;
|
||||
listening_port = port;
|
||||
|
||||
Advertise();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -566,14 +581,15 @@ void Network::UpdateServer()
|
||||
}
|
||||
}
|
||||
if (SDL_TICKS_PASSED(SDL_GetTicks(), last_tick_sent_time + 25)) {
|
||||
last_tick_sent_time = SDL_GetTicks();
|
||||
Server_Send_TICK();
|
||||
}
|
||||
if (SDL_TICKS_PASSED(SDL_GetTicks(), last_ping_sent_time + 3000)) {
|
||||
last_ping_sent_time = SDL_GetTicks();
|
||||
Server_Send_PING();
|
||||
Server_Send_PINGLIST();
|
||||
}
|
||||
if (SDL_TICKS_PASSED(SDL_GetTicks(), last_advertise_time + 60000)) {
|
||||
Advertise();
|
||||
}
|
||||
SOCKET socket = accept(listening_socket, NULL, NULL);
|
||||
if (socket == INVALID_SOCKET) {
|
||||
if (LAST_SOCKET_ERROR() != EWOULDBLOCK) {
|
||||
@@ -659,21 +675,19 @@ void Network::UpdateClient()
|
||||
if (error == 0) {
|
||||
status = NETWORK_STATUS_CONNECTED;
|
||||
server_connection.ResetLastPacketTime();
|
||||
Client_Send_AUTH(OPENRCT2_VERSION, gConfigNetwork.player_name, "");
|
||||
Client_Send_AUTH(gConfigNetwork.player_name, "");
|
||||
window_network_status_open("Authenticating...");
|
||||
}
|
||||
}
|
||||
}break;
|
||||
case NETWORK_STATUS_CONNECTED:
|
||||
if (!ProcessConnection(server_connection)) {
|
||||
char errormsg[256];
|
||||
char reason[100];
|
||||
reason[0] = 0;
|
||||
std::string errormsg = "Disconnected";
|
||||
if (server_connection.last_disconnect_reason) {
|
||||
sprintf(reason, ": %s", server_connection.last_disconnect_reason);
|
||||
errormsg += ": ";
|
||||
errormsg += server_connection.last_disconnect_reason;
|
||||
}
|
||||
sprintf(errormsg, "Disconnected%s", reason);
|
||||
window_network_status_open(errormsg);
|
||||
window_network_status_open(errormsg.c_str());
|
||||
Close();
|
||||
}
|
||||
ProcessGameCommandQueue();
|
||||
@@ -722,10 +736,10 @@ const char* Network::FormatChat(NetworkPlayer* fromplayer, const char* text)
|
||||
return formatted;
|
||||
}
|
||||
|
||||
void Network::SendPacketToClients(NetworkPacket& packet)
|
||||
void Network::SendPacketToClients(NetworkPacket& packet, bool front)
|
||||
{
|
||||
for (auto it = client_connection_list.begin(); it != client_connection_list.end(); it++) {
|
||||
(*it)->QueuePacket(std::move(NetworkPacket::Duplicate(packet)));
|
||||
(*it)->QueuePacket(std::move(NetworkPacket::Duplicate(packet)), front);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -765,14 +779,32 @@ void Network::KickPlayer(int playerId)
|
||||
|
||||
void Network::SetPassword(const char* password)
|
||||
{
|
||||
safe_strncpy(Network::password, password, sizeof(Network::password));
|
||||
Network::password = password;
|
||||
}
|
||||
|
||||
void Network::Client_Send_AUTH(const char* gameversion, const char* name, const char* password)
|
||||
void Network::ShutdownClient()
|
||||
{
|
||||
if (GetMode() == NETWORK_MODE_CLIENT) {
|
||||
shutdown(server_connection.socket, SHUT_RDWR);
|
||||
}
|
||||
}
|
||||
|
||||
void Network::Advertise()
|
||||
{
|
||||
if (gConfigNetwork.advertise && strlen(gConfigNetwork.master_url) > 0) {
|
||||
last_advertise_time = SDL_GetTicks();
|
||||
#ifndef DISABLE_HTTP
|
||||
std::string url = gConfigNetwork.master_url + std::string("?port=") + std::to_string(listening_port);
|
||||
http_request_json_async(url.c_str(), [](http_json_response *response)->void{});
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void Network::Client_Send_AUTH(const char* name, const char* password)
|
||||
{
|
||||
std::unique_ptr<NetworkPacket> packet = std::move(NetworkPacket::Allocate());
|
||||
*packet << (uint32)NETWORK_COMMAND_AUTH;
|
||||
packet->WriteString(gameversion);
|
||||
packet->WriteString(OPENRCT2_VERSION);
|
||||
packet->WriteString(name);
|
||||
packet->WriteString(password);
|
||||
server_connection.authstatus = NETWORK_AUTH_REQUESTED;
|
||||
@@ -820,7 +852,7 @@ void Network::Client_Send_CHAT(const char* text)
|
||||
{
|
||||
std::unique_ptr<NetworkPacket> packet = std::move(NetworkPacket::Allocate());
|
||||
*packet << (uint32)NETWORK_COMMAND_CHAT;
|
||||
packet->Write((uint8*)text, strlen(text) + 1);
|
||||
packet->WriteString(text);
|
||||
server_connection.QueuePacket(std::move(packet));
|
||||
}
|
||||
|
||||
@@ -828,7 +860,7 @@ void Network::Server_Send_CHAT(const char* text)
|
||||
{
|
||||
std::unique_ptr<NetworkPacket> packet = std::move(NetworkPacket::Allocate());
|
||||
*packet << (uint32)NETWORK_COMMAND_CHAT;
|
||||
packet->Write((uint8*)text, strlen(text) + 1);
|
||||
packet->WriteString(text);
|
||||
SendPacketToClients(*packet);
|
||||
}
|
||||
|
||||
@@ -848,6 +880,7 @@ void Network::Server_Send_GAMECMD(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx
|
||||
|
||||
void Network::Server_Send_TICK()
|
||||
{
|
||||
last_tick_sent_time = SDL_GetTicks();
|
||||
std::unique_ptr<NetworkPacket> packet = std::move(NetworkPacket::Allocate());
|
||||
*packet << (uint32)NETWORK_COMMAND_TICK << (uint32)RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) << (uint32)RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_SRAND_0, uint32);
|
||||
SendPacketToClients(*packet);
|
||||
@@ -873,12 +906,13 @@ void Network::Client_Send_PING()
|
||||
|
||||
void Network::Server_Send_PING()
|
||||
{
|
||||
last_ping_sent_time = SDL_GetTicks();
|
||||
std::unique_ptr<NetworkPacket> packet = std::move(NetworkPacket::Allocate());
|
||||
*packet << (uint32)NETWORK_COMMAND_PING;
|
||||
for (auto it = client_connection_list.begin(); it != client_connection_list.end(); it++) {
|
||||
(*it)->ping_time = SDL_GetTicks();
|
||||
}
|
||||
SendPacketToClients(*packet);
|
||||
SendPacketToClients(*packet, true);
|
||||
}
|
||||
|
||||
void Network::Server_Send_PINGLIST()
|
||||
@@ -899,6 +933,24 @@ void Network::Server_Send_SETDISCONNECTMSG(NetworkConnection& connection, const
|
||||
connection.QueuePacket(std::move(packet));
|
||||
}
|
||||
|
||||
void Network::Server_Send_GAMEINFO(NetworkConnection& connection)
|
||||
{
|
||||
std::unique_ptr<NetworkPacket> packet = std::move(NetworkPacket::Allocate());
|
||||
*packet << (uint32)NETWORK_COMMAND_GAMEINFO;
|
||||
#ifndef DISABLE_HTTP
|
||||
json_t* obj = json_object();
|
||||
json_object_set(obj, "name", json_string(gConfigNetwork.server_name));
|
||||
json_object_set(obj, "haspassword", json_integer(password.size() > 0 ? 1 : 0));
|
||||
json_object_set(obj, "description", json_string(""));
|
||||
json_object_set(obj, "version", json_string(OPENRCT2_VERSION));
|
||||
json_object_set(obj, "players", json_integer(player_list.size()));
|
||||
json_object_set(obj, "maxplayers", json_integer(gConfigNetwork.maxplayers));
|
||||
packet->WriteString(json_dumps(obj, 0));
|
||||
json_object_clear(obj);
|
||||
#endif
|
||||
connection.QueuePacket(std::move(packet));
|
||||
}
|
||||
|
||||
bool Network::ProcessConnection(NetworkConnection& connection)
|
||||
{
|
||||
int packetStatus;
|
||||
@@ -927,7 +979,9 @@ bool Network::ProcessConnection(NetworkConnection& connection)
|
||||
} while (packetStatus == NETWORK_READPACKET_MORE_DATA || packetStatus == NETWORK_READPACKET_SUCCESS);
|
||||
connection.SendQueuedPackets();
|
||||
if (!connection.ReceivedPacketRecently()) {
|
||||
connection.last_disconnect_reason = "No Data";
|
||||
if (!connection.last_disconnect_reason) {
|
||||
connection.last_disconnect_reason = "No Data";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -942,7 +996,7 @@ void Network::ProcessPacket(NetworkConnection& connection, NetworkPacket& packet
|
||||
switch (gNetwork.GetMode()) {
|
||||
case NETWORK_MODE_SERVER:
|
||||
if (server_command_handlers[command]) {
|
||||
if (connection.authstatus == NETWORK_AUTH_OK || command == NETWORK_COMMAND_AUTH) {
|
||||
if (connection.authstatus == NETWORK_AUTH_OK || !packet.CommandRequiresAuth()) {
|
||||
(this->*server_command_handlers[command])(connection, packet);
|
||||
}
|
||||
}
|
||||
@@ -988,7 +1042,7 @@ void Network::RemoveClient(std::unique_ptr<NetworkConnection>& connection)
|
||||
lineCh = utf8_write_codepoint(lineCh, FORMAT_RED);
|
||||
char reasonstr[100];
|
||||
reasonstr[0] = 0;
|
||||
if (connection->last_disconnect_reason) {
|
||||
if (connection->last_disconnect_reason && strlen(connection->last_disconnect_reason) < sizeof(reasonstr)) {
|
||||
sprintf(reasonstr, " (%s)", connection->last_disconnect_reason);
|
||||
}
|
||||
sprintf(lineCh, "%s has disconnected%s", connection_player->name, reasonstr);
|
||||
@@ -1057,6 +1111,10 @@ int Network::Client_Handle_AUTH(NetworkConnection& connection, NetworkPacket& pa
|
||||
connection.last_disconnect_reason = "Bad Password";
|
||||
shutdown(connection.socket, SHUT_RDWR);
|
||||
break;
|
||||
case NETWORK_AUTH_FULL:
|
||||
connection.last_disconnect_reason = "Server Full";
|
||||
shutdown(connection.socket, SHUT_RDWR);
|
||||
break;
|
||||
case NETWORK_AUTH_REQUIREPASSWORD:
|
||||
window_network_status_open_password();
|
||||
break;
|
||||
@@ -1076,11 +1134,14 @@ int Network::Server_Handle_AUTH(NetworkConnection& connection, NetworkPacket& pa
|
||||
if (!name) {
|
||||
connection.authstatus = NETWORK_AUTH_BADNAME;
|
||||
} else
|
||||
if (!password || strlen(password) == 0) {
|
||||
if ((!password || strlen(password) == 0) && Network::password.size() > 0) {
|
||||
connection.authstatus = NETWORK_AUTH_REQUIREPASSWORD;
|
||||
} else
|
||||
if (strcmp(password, Network::password) != 0) {
|
||||
if (password && Network::password != password) {
|
||||
connection.authstatus = NETWORK_AUTH_BADPASSWORD;
|
||||
} else
|
||||
if (gConfigNetwork.maxplayers <= player_list.size()) {
|
||||
connection.authstatus = NETWORK_AUTH_FULL;
|
||||
} else {
|
||||
connection.authstatus = NETWORK_AUTH_OK;
|
||||
NetworkPlayer* player = AddPlayer(name);
|
||||
@@ -1251,15 +1312,21 @@ int Network::Client_Handle_PINGLIST(NetworkConnection& connection, NetworkPacket
|
||||
|
||||
int Network::Client_Handle_SETDISCONNECTMSG(NetworkConnection& connection, NetworkPacket& packet)
|
||||
{
|
||||
static char msg[100] = {0};
|
||||
static std::string msg;
|
||||
const char* disconnectmsg = packet.ReadString();
|
||||
if (disconnectmsg) {
|
||||
safe_strncpy(msg, disconnectmsg, sizeof(msg));
|
||||
connection.last_disconnect_reason = msg;
|
||||
msg = disconnectmsg;
|
||||
connection.last_disconnect_reason = msg.c_str();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Network::Server_Handle_GAMEINFO(NetworkConnection& connection, NetworkPacket& packet)
|
||||
{
|
||||
Server_Send_GAMEINFO(connection);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int network_init()
|
||||
{
|
||||
return gNetwork.Init();
|
||||
@@ -1270,13 +1337,14 @@ void network_close()
|
||||
gNetwork.Close();
|
||||
}
|
||||
|
||||
void network_shutdown_client()
|
||||
{
|
||||
gNetwork.ShutdownClient();
|
||||
}
|
||||
|
||||
int network_begin_client(const char *host, int port)
|
||||
{
|
||||
if (gNetwork.GetMode() == NETWORK_MODE_NONE) {
|
||||
return gNetwork.BeginClient(host, port);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int network_begin_server(int port)
|
||||
@@ -1371,7 +1439,7 @@ void network_send_gamecmd(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32
|
||||
|
||||
void network_send_password(const char* password)
|
||||
{
|
||||
gNetwork.Client_Send_AUTH(OPENRCT2_VERSION, gConfigNetwork.player_name, password);
|
||||
gNetwork.Client_Send_AUTH(gConfigNetwork.player_name, password);
|
||||
}
|
||||
|
||||
void network_kick_player(int playerId)
|
||||
@@ -1387,6 +1455,7 @@ void network_set_password(const char* password)
|
||||
#else
|
||||
int network_get_mode() { return NETWORK_MODE_NONE; }
|
||||
int network_get_status() { return NETWORK_STATUS_NONE; }
|
||||
int network_get_authstatus() { return NETWORK_AUTH_NONE; }
|
||||
uint32 network_get_server_tick() { return RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32); }
|
||||
void network_send_gamecmd(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp, uint8 callback) {}
|
||||
void network_send_map() {}
|
||||
@@ -1399,7 +1468,9 @@ uint32 network_get_player_flags(unsigned int index) { return 0; }
|
||||
int network_get_player_ping(unsigned int index) { return 0; }
|
||||
int network_get_player_id(unsigned int index) { return 0; }
|
||||
void network_send_chat(const char* text) {}
|
||||
void network_send_password(const char* password) {}
|
||||
void network_close() {}
|
||||
void network_shutdown_client() {}
|
||||
void network_kick_player(int playerId) {}
|
||||
void network_set_password(const char* password) {}
|
||||
uint8 network_get_current_player_id() { return 0; }
|
||||
|
||||
Reference in New Issue
Block a user