finish server list and fix a couple of multiplayer issues

This commit is contained in:
IntelOrca 2015-08-16 17:29:47 +01:00
parent 094cc19411
commit 4f8e289e79
9 changed files with 101 additions and 22 deletions

View File

@ -24,6 +24,7 @@
<LocalDebuggerCommand>$(TargetDir)\openrct2.exe</LocalDebuggerCommand>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<LocalDebuggerCommandArguments>--server 127.0.0.1 --port 12345</LocalDebuggerCommandArguments>
<LocalDebuggerCommandArguments>
</LocalDebuggerCommandArguments>
</PropertyGroup>
</Project>

View File

@ -380,6 +380,8 @@ void game_logic_update()
window_error_open(title_text, body_text);
}
network_tick();
}
/**

View File

@ -619,6 +619,7 @@ void window_sign_small_open(rct_windownumber number);
void window_cheats_open();
void window_player_list_open();
void window_network_status_open(const char* text);
void window_network_status_close();
void window_server_list_open();
void window_research_open();

View File

@ -55,6 +55,7 @@ enum {
NETWORK_COMMAND_PLAYERLIST,
NETWORK_COMMAND_PING,
NETWORK_COMMAND_PINGLIST,
NETWORK_COMMAND_READY,
NETWORK_COMMAND_MAX
};
@ -67,6 +68,7 @@ const char *NetworkCommandNames[] = {
"NETWORK_COMMAND_PLAYERLIST",
"NETWORK_COMMAND_PING",
"NETWORK_COMMAND_PINGLIST",
"NETWORK_COMMAND_READY",
};
NetworkPacket::NetworkPacket()
@ -248,6 +250,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_READY] = &Network::Server_Handle_READY;
}
Network::~Network()
@ -406,12 +409,7 @@ uint8 Network::GetPlayerID()
void Network::Update()
{
if (GetMode() == NETWORK_MODE_NONE)
return;
switch (GetMode()) {
case NETWORK_MODE_NONE:
return;
case NETWORK_MODE_SERVER:
UpdateServer();
break;
@ -466,16 +464,36 @@ 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();
}
}
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 {
window_network_status_open("Network desync detected");
Close();
}
}
@ -636,6 +654,13 @@ 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;
@ -830,15 +855,20 @@ int Network::Client_Handle_MAP(NetworkConnection& connection, NetworkPacket& pac
window_network_status_open(status);
memcpy(&chunk_buffer[offset], (void*)packet.Read(chunksize), chunksize);
if (offset + chunksize == size) {
window_network_status_close();
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) & 1)
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;
window_network_status_open("Loaded new map from network");
Client_Send_READY();
// window_network_status_open("Loaded new map from network");
}
SDL_RWclose(rw);
}
@ -873,8 +903,13 @@ int Network::Client_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket&
uint8 playerid;
uint8 callback;
packet >> tick >> args[0] >> args[1] >> args[2] >> args[3] >> args[4] >> args[5] >> args[6] >> playerid >> callback;
GameCommand gc = GameCommand(tick, args, playerid, callback);
game_command_queue.insert(gc);
if (args[4] == GAME_COMMAND_TOGGLE_PAUSE) {
pause_toggle();
} else {
GameCommand gc = GameCommand(tick, args, playerid, callback);
game_command_queue.insert(gc);
}
return 1;
}
@ -956,6 +991,14 @@ 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();
@ -981,6 +1024,11 @@ void network_update()
gNetwork.Update();
}
void network_tick()
{
gNetwork.UpdateTick();
}
int network_get_mode()
{
return gNetwork.GetMode();

View File

@ -132,6 +132,7 @@ 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);
@ -148,6 +149,7 @@ 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;
@ -192,6 +194,8 @@ private:
void UpdateServer();
void UpdateClient();
void UpdateServerTick();
void UpdateClientTick();
private:
std::vector<int (Network::*)(NetworkConnection& connection, NetworkPacket& packet)> client_command_handlers;
@ -208,6 +212,7 @@ 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);
};
extern "C" {
@ -219,6 +224,7 @@ int network_begin_client(const char *host, int port);
int network_begin_server(int port);
void network_update();
void network_tick();
int network_get_mode();
int network_get_authstatus();
uint32 network_get_server_tick();

View File

@ -244,6 +244,10 @@ void openrct2_launch()
rct2_open_file(gOpenRCT2StartupActionPath);
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_PLAYING;
if (gNetworkStart == NETWORK_MODE_SERVER) {
network_begin_server(gNetworkStartPort);
}
break;
case STARTUP_ACTION_EDIT:
if (strlen(gOpenRCT2StartupActionPath) == 0) {
@ -256,8 +260,6 @@ void openrct2_launch()
if (gNetworkStart == NETWORK_MODE_CLIENT) {
network_begin_client(gNetworkStartHost, gNetworkStartPort);
} else if (gNetworkStart == NETWORK_MODE_SERVER) {
network_begin_server(gNetworkStartPort);
}
openrct2_loop();

View File

@ -26,6 +26,7 @@
#include "../interface/widget.h"
#include "../interface/window.h"
#include "../localisation/localisation.h"
#include "../network/network.h"
#include "../scenario.h"
#include "../title.h"
#include "../windows/error.h"
@ -748,6 +749,10 @@ static void window_loadsave_select(rct_window *w, const char *path)
}
}
else if (game_load_save(path)) {
if (_loadsaveType & LOADSAVETYPE_NETWORK) {
network_begin_server(gConfigNetwork.default_port);
}
window_close(w);
gfx_invalidate_screen();
rct2_endupdate();

View File

@ -106,6 +106,11 @@ void window_network_status_open(const char* text)
window->colours[2] = 7;
}
void window_network_status_close()
{
window_close_by_class(WC_NETWORK_STATUS);
}
static void window_network_status_mouseup(rct_window *w, int widgetIndex)
{
switch (widgetIndex) {

View File

@ -660,8 +660,17 @@ static void window_top_toolbar_invalidate(rct_window *w)
if (!gConfigInterface.toolbar_show_news)
window_top_toolbar_widgets[WIDX_NEWS].type = WWT_EMPTY;
if (network_get_mode() == NETWORK_MODE_NONE)
switch (network_get_mode()) {
case NETWORK_MODE_SERVER:
window_top_toolbar_widgets[WIDX_FASTFORWARD].type = WWT_EMPTY;
break;
case NETWORK_MODE_CLIENT:
window_top_toolbar_widgets[WIDX_PAUSE].type = WWT_EMPTY;
window_top_toolbar_widgets[WIDX_FASTFORWARD].type = WWT_EMPTY;
break;
default:
window_top_toolbar_widgets[WIDX_NETWORK].type = WWT_EMPTY;
}
}
enabledWidgets = 0;