Merge pull request #1826 from zsilencer/develop

fix some multiplayer bugs
This commit is contained in:
Ted John 2015-08-20 07:30:00 +01:00
commit c0ac3ba06d
5 changed files with 36 additions and 94 deletions

View File

@ -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){

View File

@ -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() {}

View File

@ -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();

View File

@ -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;
}

View File

@ -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)