1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-15 19:13:07 +01:00

improve multiplayer

This commit is contained in:
IntelOrca
2015-08-15 23:19:15 +01:00
parent 3f31221973
commit 9746bccbf6
5 changed files with 129 additions and 77 deletions

View File

@@ -12,7 +12,8 @@
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommand>$(TargetDir)\openrct2.exe</LocalDebuggerCommand>
<LocalDebuggerCommandArguments>"C:\Program Files (x86)\Infogrames\RollerCoaster Tycoon 2\Scenarios\Crazy Castle.SC6" --port 5552 --server 127.0.0.1</LocalDebuggerCommandArguments>
<LocalDebuggerCommandArguments>
</LocalDebuggerCommandArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release with Tests|Win32'">
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
@@ -23,7 +24,6 @@
<LocalDebuggerCommand>$(TargetDir)\openrct2.exe</LocalDebuggerCommand>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<LocalDebuggerCommandArguments>
</LocalDebuggerCommandArguments>
<LocalDebuggerCommandArguments>--server 127.0.0.1 --port 12345</LocalDebuggerCommandArguments>
</PropertyGroup>
</Project>

View File

@@ -262,32 +262,39 @@ void game_update()
// make sure client doesn't fall behind the server too much
numUpdates += 10;
}
if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) >= network_get_server_tick()) {
// dont run past the server
numUpdates = 0;
}
} else {
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) != 0) {
numUpdates = 0;
}
}
// Update the game one or more times
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) == 0) {
for (i = 0; i < numUpdates; i++) {
game_logic_update();
start_title_music();
for (i = 0; i < numUpdates; i++) {
game_logic_update();
start_title_music();
if (gGameSpeed > 1)
continue;
if (gGameSpeed > 1)
continue;
// Possibly smooths viewport scrolling, I don't see a difference though
if (RCT2_GLOBAL(0x009E2D74, uint32) == 1) {
RCT2_GLOBAL(0x009E2D74, uint32) = 0;
break;
} else {
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) == INPUT_STATE_RESET ||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) == INPUT_STATE_NORMAL
) {
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_VIEWPORT_SCROLLING) {
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~INPUT_FLAG_VIEWPORT_SCROLLING;
break;
}
} else {
// Possibly smooths viewport scrolling, I don't see a difference though
if (RCT2_GLOBAL(0x009E2D74, uint32) == 1) {
RCT2_GLOBAL(0x009E2D74, uint32) = 0;
break;
} else {
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) == INPUT_STATE_RESET ||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) == INPUT_STATE_NORMAL
) {
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_VIEWPORT_SCROLLING) {
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~INPUT_FLAG_VIEWPORT_SCROLLING;
break;
}
} else {
break;
}
}
}
@@ -332,14 +339,6 @@ void game_update()
void game_logic_update()
{
network_update();
if (network_get_mode() == NETWORK_MODE_CLIENT) {
if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) == network_get_server_tick()) {
// dont run past the server
return;
}
}
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32)++;
RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, uint32)++;
RCT2_GLOBAL(0x009DEA66, sint16)++;

View File

@@ -57,6 +57,17 @@ enum {
NETWORK_COMMAND_MAX
};
const char *NetworkCommandNames[] = {
"NETWORK_COMMAND_AUTH",
"NETWORK_COMMAND_MAP",
"NETWORK_COMMAND_CHAT",
"NETWORK_COMMAND_GAMECMD",
"NETWORK_COMMAND_TICK",
"NETWORK_COMMAND_PLAYERLIST",
"NETWORK_COMMAND_PING",
"NETWORK_COMMAND_PINGLIST",
};
NetworkPacket::NetworkPacket()
{
transferred = 0;
@@ -397,52 +408,73 @@ void Network::Update()
if (GetMode() == NETWORK_MODE_NONE)
return;
if (GetMode() == NETWORK_MODE_CLIENT) {
if (!ProcessConnection(server_connection)) {
Close();
switch (GetMode()) {
case NETWORK_MODE_NONE:
return;
case NETWORK_MODE_SERVER:
UpdateServer();
break;
case NETWORK_MODE_CLIENT:
UpdateClient();
break;
}
}
void Network::UpdateServer()
{
auto it = client_connection_list.begin();
while (it != client_connection_list.end()) {
if (!ProcessConnection(*(*it))) {
RemoveClient((*it));
it = client_connection_list.begin();
} else {
ProcessGameCommandQueue();
it++;
}
} else
if (GetMode() == NETWORK_MODE_SERVER) {
auto it = client_connection_list.begin();
while (it != client_connection_list.end()) {
if (!ProcessConnection(*(*it))) {
RemoveClient((*it));
it = client_connection_list.begin();
} else {
it++;
}
}
if (SDL_GetTicks() - last_tick_sent_time >= 25) {
last_tick_sent_time = SDL_GetTicks();
Server_Send_TICK();
}
if (SDL_GetTicks() - last_ping_sent_time >= 3000) {
last_ping_sent_time = SDL_GetTicks();
Server_Send_PING();
Server_Send_PINGLIST();
}
SOCKET socket = accept(listening_socket, NULL, NULL);
if (socket == INVALID_SOCKET) {
if (WSAGetLastError() != WSAEWOULDBLOCK) {
PrintError();
log_error("Failed to accept client.");
}
if (SDL_GetTicks() - last_tick_sent_time >= 25) {
last_tick_sent_time = SDL_GetTicks();
Server_Send_TICK();
}
if (SDL_GetTicks() - last_ping_sent_time >= 3000) {
last_ping_sent_time = SDL_GetTicks();
Server_Send_PING();
Server_Send_PINGLIST();
}
SOCKET socket = accept(listening_socket, NULL, NULL);
if (socket == INVALID_SOCKET) {
if (WSAGetLastError() != WSAEWOULDBLOCK) {
PrintError();
log_error("Failed to accept client.");
}
} else {
u_long nonblocking = 1;
if (ioctlsocket(socket, FIONBIO, &nonblocking) != NO_ERROR) {
closesocket(socket);
log_error("Failed to set non-blocking mode.");
} else {
u_long nonblocking = 1;
if (ioctlsocket(socket, FIONBIO, &nonblocking) != NO_ERROR) {
closesocket(socket);
log_error("Failed to set non-blocking mode.");
} else {
AddClient(socket);
AddClient(socket);
was_paused_before_client_connected = RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint32) != 0;
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint32) == 0) {
pause_toggle();
}
}
}
}
if (!CheckSRAND(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32), RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_SRAND_0, uint32))) {
window_network_status_open("Network desync detected");
void Network::UpdateClient()
{
if (!ProcessConnection(server_connection)) {
Close();
} else {
ProcessGameCommandQueue();
if (CheckSRAND(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32), RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_SRAND_0, uint32))) {
if (server_srand0_tick == 0) {
// printf("SRAND OK!\n");
}
} else {
window_network_status_open("Network desync detected");
Close();
}
}
}
@@ -478,6 +510,14 @@ void Network::SendPacketToClients(NetworkPacket& packet)
bool Network::CheckSRAND(uint32 tick, uint32 srand0)
{
if (server_srand0_tick == 0)
return true;
if (tick >= server_srand0_tick) {
server_srand0_tick = 0;
return true;
}
if (tick == server_srand0_tick) {
server_srand0_tick = 0;
if (srand0 != server_srand0) {
@@ -634,17 +674,20 @@ void Network::ProcessPacket(NetworkConnection& connection, NetworkPacket& packet
uint32 command;
packet >> command;
if (command < NETWORK_COMMAND_MAX) {
if (GetMode() == NETWORK_MODE_CLIENT) {
if (client_command_handlers[command]) {
(this->*client_command_handlers[command])(connection, packet);
}
} else
if (GetMode() == NETWORK_MODE_SERVER) {
// printf("RECV %s\n", NetworkCommandNames[command]);
switch (gNetwork.GetMode()) {
case NETWORK_MODE_SERVER:
if (server_command_handlers[command]) {
if (connection.authstatus == NETWORK_AUTH_OK || command == NETWORK_COMMAND_AUTH) {
(this->*server_command_handlers[command])(connection, packet);
}
}
break;
case NETWORK_MODE_CLIENT:
if (client_command_handlers[command]) {
(this->*client_command_handlers[command])(connection, packet);
}
break;
}
}
packet.Clear();
@@ -997,11 +1040,13 @@ void network_send_chat(const char* text)
void network_send_gamecmd(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp, uint8 callback)
{
if (gNetwork.GetMode() == NETWORK_MODE_CLIENT) {
gNetwork.Client_Send_GAMECMD(eax, ebx, ecx, edx, esi, edi, ebp, callback);
} else
if (gNetwork.GetMode() == NETWORK_MODE_SERVER) {
switch (gNetwork.GetMode()) {
case NETWORK_MODE_SERVER:
gNetwork.Server_Send_GAMECMD(eax, ebx, ecx, edx, esi, edi, ebp, gNetwork.GetPlayerID(), callback);
break;
case NETWORK_MODE_CLIENT:
gNetwork.Client_Send_GAMECMD(eax, ebx, ecx, edx, esi, edi, ebp, callback);
break;
}
}

View File

@@ -188,6 +188,11 @@ private:
std::vector<uint8> chunk_buffer;
char password[33];
bool was_paused_before_client_connected;
void UpdateServer();
void UpdateClient();
private:
std::vector<int (Network::*)(NetworkConnection& connection, NetworkPacket& packet)> client_command_handlers;
std::vector<int (Network::*)(NetworkConnection& connection, NetworkPacket& packet)> server_command_handlers;

View File

@@ -36,6 +36,7 @@
#include "localisation/date.h"
#include "localisation/localisation.h"
#include "management/news_item.h"
#include "network/network.h"
#include "network/twitch.h"
#include "object.h"
#include "openrct2.h"
@@ -371,6 +372,8 @@ void rct2_update_2()
// TODO: screenshot countdown process
network_update();
// check_cmdline_arg();
// Screens
if (RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) != 0)