diff --git a/projects/openrct2.vcxproj.user b/projects/openrct2.vcxproj.user
index 6e0ad43592..96c90432a6 100644
--- a/projects/openrct2.vcxproj.user
+++ b/projects/openrct2.vcxproj.user
@@ -12,7 +12,8 @@
$(TargetDir)
WindowsLocalDebugger
$(TargetDir)\openrct2.exe
- "C:\Program Files (x86)\Infogrames\RollerCoaster Tycoon 2\Scenarios\Crazy Castle.SC6" --port 5552 --server 127.0.0.1
+
+
$(TargetDir)
@@ -23,7 +24,6 @@
$(TargetDir)\openrct2.exe
WindowsLocalDebugger
$(TargetDir)
-
-
+ --server 127.0.0.1 --port 12345
\ No newline at end of file
diff --git a/src/game.c b/src/game.c
index 6a497edfa9..af06998e03 100644
--- a/src/game.c
+++ b/src/game.c
@@ -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)++;
diff --git a/src/network/network.cpp b/src/network/network.cpp
index f0baba10d9..ab3696eca8 100644
--- a/src/network/network.cpp
+++ b/src/network/network.cpp
@@ -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;
}
}
diff --git a/src/network/network.h b/src/network/network.h
index 121ddf5b24..17dc74a497 100644
--- a/src/network/network.h
+++ b/src/network/network.h
@@ -188,6 +188,11 @@ private:
std::vector chunk_buffer;
char password[33];
+ bool was_paused_before_client_connected;
+
+ void UpdateServer();
+ void UpdateClient();
+
private:
std::vector client_command_handlers;
std::vector server_command_handlers;
diff --git a/src/rct2.c b/src/rct2.c
index 24f00a2c45..61af055adf 100644
--- a/src/rct2.c
+++ b/src/rct2.c
@@ -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)