mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #1826 from zsilencer/develop
fix some multiplayer bugs
This commit is contained in:
commit
c0ac3ba06d
34
src/game.c
34
src/game.c
|
@ -262,11 +262,6 @@ 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;
|
||||
|
@ -299,6 +294,7 @@ void game_update()
|
|||
}
|
||||
}
|
||||
|
||||
network_update();
|
||||
news_item_update_current();
|
||||
window_dispatch_update_all();
|
||||
|
||||
|
@ -333,6 +329,13 @@ 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(RCT2_ADDRESS_SCREEN_AGE, sint16)++;
|
||||
|
@ -374,8 +377,6 @@ void game_logic_update()
|
|||
|
||||
window_error_open(title_text, body_text);
|
||||
}
|
||||
|
||||
network_tick();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -477,13 +478,15 @@ int game_do_command_p(int command, int *eax, int *ebx, int *ecx, int *edx, int *
|
|||
return cost;
|
||||
}
|
||||
|
||||
if (network_get_mode() != NETWORK_MODE_NONE && !(flags & GAME_COMMAND_FLAG_NETWORKED) && !(flags & GAME_COMMAND_FLAG_GHOST) && !(flags & GAME_COMMAND_FLAG_5) && RCT2_GLOBAL(0x009A8C28, uint8) == 1) {
|
||||
network_send_gamecmd(*eax, *ebx, *ecx, *edx, *esi, *edi, *ebp, game_command_callback_get_index(game_command_callback));
|
||||
if (network_get_mode() == NETWORK_MODE_CLIENT) {
|
||||
game_command_callback = 0;
|
||||
// Decrement nest count
|
||||
RCT2_GLOBAL(0x009A8C28, uint8)--;
|
||||
return cost;
|
||||
if (network_get_mode() != NETWORK_MODE_NONE && !(flags & GAME_COMMAND_FLAG_NETWORKED) && !(flags & GAME_COMMAND_FLAG_GHOST) && !(flags & GAME_COMMAND_FLAG_5) && RCT2_GLOBAL(0x009A8C28, uint8) == 1 /* Send only top-level commands */) {
|
||||
if (command != GAME_COMMAND_LOAD_OR_QUIT) { // Disable these commands over the network
|
||||
network_send_gamecmd(*eax, *ebx, *ecx, *edx, *esi, *edi, *ebp, game_command_callback_get_index(game_command_callback));
|
||||
if (network_get_mode() == NETWORK_MODE_CLIENT) { // Client sent the command to the server, do not run it locally, just return. It will run when server sends it
|
||||
game_command_callback = 0;
|
||||
// Decrement nest count
|
||||
RCT2_GLOBAL(0x009A8C28, uint8)--;
|
||||
return cost;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -813,6 +816,9 @@ int game_load_network(SDL_RWops* rw)
|
|||
uint32 checksum;
|
||||
SDL_RWread(rw, &checksum, sizeof(uint32), 1);
|
||||
|
||||
// Read other data not in normal save files
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint32) = SDL_ReadLE32(rw);
|
||||
|
||||
if (!load_success){
|
||||
set_load_objects_fail_reason();
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_5){
|
||||
|
|
|
@ -59,7 +59,6 @@ enum {
|
|||
NETWORK_COMMAND_PLAYERLIST,
|
||||
NETWORK_COMMAND_PING,
|
||||
NETWORK_COMMAND_PINGLIST,
|
||||
NETWORK_COMMAND_READY,
|
||||
NETWORK_COMMAND_MAX
|
||||
};
|
||||
|
||||
|
@ -72,7 +71,6 @@ const char *NetworkCommandNames[] = {
|
|||
"NETWORK_COMMAND_PLAYERLIST",
|
||||
"NETWORK_COMMAND_PING",
|
||||
"NETWORK_COMMAND_PINGLIST",
|
||||
"NETWORK_COMMAND_READY",
|
||||
};
|
||||
|
||||
NetworkPacket::NetworkPacket()
|
||||
|
@ -254,7 +252,6 @@ 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_READY] = &Network::Server_Handle_READY;
|
||||
}
|
||||
|
||||
Network::~Network()
|
||||
|
@ -375,7 +372,7 @@ bool Network::BeginServer(unsigned short port)
|
|||
return false;
|
||||
}
|
||||
|
||||
NetworkPlayer* player = AddPlayer("Server Player");
|
||||
NetworkPlayer* player = AddPlayer(gConfigNetwork.player_name);
|
||||
player->flags |= NETWORK_PLAYER_FLAG_ISSERVER;
|
||||
player_id = player->id;
|
||||
|
||||
|
@ -456,10 +453,6 @@ void Network::UpdateServer()
|
|||
log_error("Failed to set non-blocking mode.");
|
||||
} else {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -469,33 +462,8 @@ void Network::UpdateClient()
|
|||
if (!ProcessConnection(server_connection)) {
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
void Network::UpdateTick()
|
||||
{
|
||||
switch (GetMode()) {
|
||||
case NETWORK_MODE_SERVER:
|
||||
UpdateServerTick();
|
||||
break;
|
||||
case NETWORK_MODE_CLIENT:
|
||||
UpdateClientTick();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Network::UpdateServerTick()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Network::UpdateClientTick()
|
||||
{
|
||||
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 {
|
||||
if (!CheckSRAND(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32), RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_SRAND_0, uint32))) {
|
||||
window_network_status_open("Network desync detected");
|
||||
Close();
|
||||
}
|
||||
|
@ -536,7 +504,7 @@ bool Network::CheckSRAND(uint32 tick, uint32 srand0)
|
|||
if (server_srand0_tick == 0)
|
||||
return true;
|
||||
|
||||
if (tick >= server_srand0_tick) {
|
||||
if (tick > server_srand0_tick) {
|
||||
server_srand0_tick = 0;
|
||||
return true;
|
||||
}
|
||||
|
@ -570,7 +538,7 @@ void Network::Server_Send_MAP(NetworkConnection* connection)
|
|||
int size = (int)SDL_RWtell(rw);
|
||||
int chunksize = 1000;
|
||||
for (int i = 0; i < size; i += chunksize) {
|
||||
int datasize = min(chunksize, size - i);
|
||||
int datasize = (std::min)(chunksize, size - i);
|
||||
std::unique_ptr<NetworkPacket> packet = std::move(NetworkPacket::Allocate());
|
||||
*packet << (uint32)NETWORK_COMMAND_MAP << (uint32)size << (uint32)i;
|
||||
packet->Write(&buffer[i], datasize);
|
||||
|
@ -658,13 +626,6 @@ void Network::Server_Send_PINGLIST()
|
|||
SendPacketToClients(*packet);
|
||||
}
|
||||
|
||||
void Network::Client_Send_READY()
|
||||
{
|
||||
std::unique_ptr<NetworkPacket> packet = std::move(NetworkPacket::Allocate());
|
||||
*packet << (uint32)NETWORK_COMMAND_READY;
|
||||
server_connection.QueuePacket(std::move(packet));
|
||||
}
|
||||
|
||||
bool Network::ProcessConnection(NetworkConnection& connection)
|
||||
{
|
||||
int packetStatus;
|
||||
|
@ -864,14 +825,9 @@ int Network::Client_Handle_MAP(NetworkConnection& connection, NetworkPacket& pac
|
|||
SDL_RWops* rw = SDL_RWFromMem(&chunk_buffer[0], size);
|
||||
if (game_load_network(rw)) {
|
||||
game_load_init();
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) == 0) {
|
||||
pause_toggle();
|
||||
}
|
||||
game_command_queue.clear();
|
||||
server_tick = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32);
|
||||
server_srand0_tick = 0;
|
||||
|
||||
Client_Send_READY();
|
||||
// window_network_status_open("Loaded new map from network");
|
||||
}
|
||||
SDL_RWclose(rw);
|
||||
|
@ -908,12 +864,8 @@ int Network::Client_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket&
|
|||
uint8 callback;
|
||||
packet >> tick >> args[0] >> args[1] >> args[2] >> args[3] >> args[4] >> args[5] >> args[6] >> playerid >> callback;
|
||||
|
||||
if (args[4] == GAME_COMMAND_TOGGLE_PAUSE) {
|
||||
pause_toggle();
|
||||
} else {
|
||||
GameCommand gc = GameCommand(tick, args, playerid, callback);
|
||||
game_command_queue.insert(gc);
|
||||
}
|
||||
GameCommand gc = GameCommand(tick, args, playerid, callback);
|
||||
game_command_queue.insert(gc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -995,14 +947,6 @@ int Network::Client_Handle_PINGLIST(NetworkConnection& connection, NetworkPacket
|
|||
return 1;
|
||||
}
|
||||
|
||||
int Network::Server_Handle_READY(NetworkConnection& connection, NetworkPacket& packet)
|
||||
{
|
||||
if (!was_paused_before_client_connected) {
|
||||
game_do_command(0, 1, 0, 0, GAME_COMMAND_TOGGLE_PAUSE, 0, 0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int network_init()
|
||||
{
|
||||
return gNetwork.Init();
|
||||
|
@ -1028,11 +972,6 @@ void network_update()
|
|||
gNetwork.Update();
|
||||
}
|
||||
|
||||
void network_tick()
|
||||
{
|
||||
gNetwork.UpdateTick();
|
||||
}
|
||||
|
||||
int network_get_mode()
|
||||
{
|
||||
return gNetwork.GetMode();
|
||||
|
@ -1105,7 +1044,6 @@ void network_send_gamecmd(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32
|
|||
|
||||
#else
|
||||
int network_get_mode() { return NETWORK_MODE_NONE; }
|
||||
void network_tick() {}
|
||||
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() {}
|
||||
|
|
|
@ -138,7 +138,6 @@ public:
|
|||
uint32 GetServerTick();
|
||||
uint8 GetPlayerID();
|
||||
void Update();
|
||||
void UpdateTick();
|
||||
NetworkPlayer* GetPlayerByID(int id);
|
||||
const char* FormatChat(NetworkPlayer* fromplayer, const char* text);
|
||||
void SendPacketToClients(NetworkPacket& packet);
|
||||
|
@ -155,7 +154,6 @@ public:
|
|||
void Client_Send_PING();
|
||||
void Server_Send_PING();
|
||||
void Server_Send_PINGLIST();
|
||||
void Client_Send_READY();
|
||||
|
||||
std::vector<std::unique_ptr<NetworkPlayer>> player_list;
|
||||
|
||||
|
@ -196,12 +194,8 @@ private:
|
|||
std::vector<uint8> chunk_buffer;
|
||||
char password[33];
|
||||
|
||||
bool was_paused_before_client_connected;
|
||||
|
||||
void UpdateServer();
|
||||
void UpdateClient();
|
||||
void UpdateServerTick();
|
||||
void UpdateClientTick();
|
||||
|
||||
private:
|
||||
std::vector<int (Network::*)(NetworkConnection& connection, NetworkPacket& packet)> client_command_handlers;
|
||||
|
@ -218,7 +212,6 @@ private:
|
|||
int Client_Handle_PING(NetworkConnection& connection, NetworkPacket& packet);
|
||||
int Server_Handle_PING(NetworkConnection& connection, NetworkPacket& packet);
|
||||
int Client_Handle_PINGLIST(NetworkConnection& connection, NetworkPacket& packet);
|
||||
int Server_Handle_READY(NetworkConnection& connection, NetworkPacket& packet);
|
||||
};
|
||||
|
||||
#endif // __cplusplus
|
||||
|
@ -234,7 +227,6 @@ int network_begin_server(int port);
|
|||
|
||||
int network_get_mode();
|
||||
void network_update();
|
||||
void network_tick();
|
||||
int network_get_authstatus();
|
||||
uint32 network_get_server_tick();
|
||||
uint8 network_get_player_id();
|
||||
|
|
|
@ -1041,6 +1041,9 @@ int scenario_save_network(SDL_RWops* rw)
|
|||
|
||||
free(s6);
|
||||
|
||||
// Write other data not in normal save files
|
||||
SDL_WriteLE32(rw, RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint32));
|
||||
|
||||
gfx_invalidate_screen();
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@ static rct_window_event_list window_server_list_events = {
|
|||
static int _hoverButtonIndex = -1;
|
||||
|
||||
static void server_list_get_item_button(int buttonIndex, int x, int y, int width, int *outX, int *outY);
|
||||
static void server_list_update_player_name(rct_window *w);
|
||||
static void server_list_update_player_name();
|
||||
static void server_list_load_saved_servers();
|
||||
static void server_list_save_saved_servers();
|
||||
static void dispose_saved_server_list();
|
||||
|
@ -166,7 +166,7 @@ void window_server_list_open()
|
|||
|
||||
static void window_server_list_close(rct_window *w)
|
||||
{
|
||||
server_list_update_player_name(w);
|
||||
server_list_update_player_name();
|
||||
dispose_saved_server_list();
|
||||
}
|
||||
|
||||
|
@ -183,6 +183,7 @@ static void window_server_list_mouseup(rct_window *w, int widgetIndex)
|
|||
window_text_input_open(w, widgetIndex, STR_ADD_SERVER, STR_ENTER_HOSTNAME_OR_IP_ADDRESS, STR_NONE, 0, 128);
|
||||
break;
|
||||
case WIDX_START_SERVER:
|
||||
server_list_update_player_name();
|
||||
window_loadsave_open(LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME | LOADSAVETYPE_NETWORK, NULL);
|
||||
break;
|
||||
}
|
||||
|
@ -223,9 +224,11 @@ static void window_server_list_scroll_mousedown(rct_window *w, int scrollIndex,
|
|||
window_invalidate(w);
|
||||
break;
|
||||
case WIDX_LIST_SPECTATE:
|
||||
server_list_update_player_name();
|
||||
join_server(serverAddress, true);
|
||||
break;
|
||||
default:
|
||||
server_list_update_player_name();
|
||||
join_server(serverAddress, false);
|
||||
break;
|
||||
}
|
||||
|
@ -370,7 +373,7 @@ static void server_list_get_item_button(int buttonIndex, int x, int y, int width
|
|||
*outY = y + 2;
|
||||
}
|
||||
|
||||
static void server_list_update_player_name(rct_window *w)
|
||||
static void server_list_update_player_name()
|
||||
{
|
||||
if (strlen(_playerName) > 0) {
|
||||
SafeFree(gConfigNetwork.player_name);
|
||||
|
@ -495,7 +498,7 @@ static void add_saved_server(char *address)
|
|||
int index = _numSavedServers - 1;
|
||||
_savedServers[index].address = _strdup(address);
|
||||
_savedServers[index].name = _strdup(address);
|
||||
_savedServers[index].description = NULL;
|
||||
_savedServers[index].description = _strdup("");
|
||||
}
|
||||
|
||||
static void remove_saved_server(int index)
|
||||
|
|
Loading…
Reference in New Issue