1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-20 22:33:02 +01:00

allow joining of servers in server list window

This commit is contained in:
IntelOrca
2015-08-16 16:36:57 +01:00
parent 43489db6a2
commit 094cc19411
8 changed files with 205 additions and 114 deletions

View File

@@ -3843,3 +3843,4 @@ STR_5501 :Start Server
STR_5502 :Multiplayer
STR_5503 :Enter hostname or IP address:
STR_5504 :{SMALLFONT}{BLACK}Show multiplayer status
STR_5505 :Unable to connect to server.

View File

@@ -20,12 +20,13 @@
#include "addresses.h"
#include "config.h"
#include "interface/themes.h"
#include "interface/title_sequences.h"
#include "localisation/language.h"
#include "localisation/localisation.h"
#include "util/util.h"
#include "interface/themes.h"
#include "network/network.h"
#include "openrct2.h"
#include "interface/title_sequences.h"
#include "util/util.h"
// Magic number for original game cfg file
static const int MagicNumber = 0x0003113A;
@@ -232,7 +233,7 @@ config_property_definition _twitchDefinitions[] = {
config_property_definition _networkDefinitions[] = {
{ offsetof(network_configuration, player_name), "player_name", CONFIG_VALUE_TYPE_STRING, {.value_string = "Player" }, NULL },
{ offsetof(network_configuration, default_port), "default_port", CONFIG_VALUE_TYPE_UINT32, true, NULL },
{ offsetof(network_configuration, default_port), "default_port", CONFIG_VALUE_TYPE_UINT32, NETWORK_DEFAULT_PORT, NULL },
};
config_section_definition _sectionDefinitions[] = {

View File

@@ -1268,6 +1268,8 @@ static void ttf_process_initial_colour(int colour, text_draw_info *info)
static void ttf_draw_string(rct_drawpixelinfo *dpi, char *text, int colour, int x, int y)
{
if (text == NULL) return;
text_draw_info info;
info.font_sprite_base = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16);
info.flags = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16);

View File

@@ -472,6 +472,7 @@ typedef enum {
BTM_TB_DIRTY_FLAG_PARK_RATING = (1 << 4)
} BTM_TOOLBAR_DIRTY_FLAGS;
// 000N_TTTL
enum {
LOADSAVETYPE_LOAD = 0 << 0,
LOADSAVETYPE_SAVE = 1 << 0,
@@ -479,7 +480,9 @@ enum {
LOADSAVETYPE_GAME = 0 << 1,
LOADSAVETYPE_LANDSCAPE = 1 << 1,
LOADSAVETYPE_SCENARIO = 2 << 1,
LOADSAVETYPE_TRACK = 3 << 1
LOADSAVETYPE_TRACK = 3 << 1,
LOADSAVETYPE_NETWORK = 1 << 4,
};
extern bool gLoadSaveTitleSequenceSave;

View File

@@ -2044,6 +2044,7 @@ enum {
STR_ENTER_HOSTNAME_OR_IP_ADDRESS = 5503,
STR_SHOW_MULTIPLAYER_STATUS_TIP = 5504,
STR_UNABLE_TO_CONNECT_TO_SERVER = 5505,
// Have to include resource strings (from scenarios and objects) for the time being now that language is partially working
STR_COUNT = 32768

View File

@@ -26,6 +26,7 @@
#include "network.h"
extern "C" {
#include "../addresses.h"
#include "../config.h"
#include "../game.h"
#include "../interface/chat.h"
#include "../interface/window.h"
@@ -301,7 +302,7 @@ bool Network::BeginClient(const char* host, unsigned short port)
server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (server_socket == INVALID_SOCKET) {
log_error("Unable to create socket.");
return 0;
return false;
}
SOCKADDR_IN server_address;
@@ -326,7 +327,7 @@ bool Network::BeginClient(const char* host, unsigned short port)
mode = NETWORK_MODE_CLIENT;
Client_Send_AUTH(OPENRCT2_VERSION, "Player", "");
Client_Send_AUTH(OPENRCT2_VERSION, gConfigNetwork.player_name, "");
return true;
}

View File

@@ -162,7 +162,7 @@ rct_window *window_loadsave_open(int type, char *defaultName)
}
_loadsaveType = type;
switch (type) {
switch (type & 0x0F) {
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME):
w->widgets[WIDX_TITLE].image = STR_LOAD_GAME;
break;
@@ -186,8 +186,8 @@ rct_window *window_loadsave_open(int type, char *defaultName)
w->no_list_items = 0;
w->selected_list_item = -1;
includeNewItem = (type & 1) == LOADSAVETYPE_SAVE;
switch (type & 6) {
includeNewItem = (type & 0x01) == LOADSAVETYPE_SAVE;
switch (type & 0x0E) {
case LOADSAVETYPE_GAME:
platform_get_user_directory(path, "save");
if (!platform_ensure_directory_exists(path)) {
@@ -383,7 +383,7 @@ static void window_loadsave_scrollmousedown(rct_window *w, int scrollIndex, int
} else {
// TYPE_FILE
// Load or overwrite
if ((_loadsaveType & 1) == LOADSAVETYPE_SAVE)
if ((_loadsaveType & 0x01) == LOADSAVETYPE_SAVE)
window_overwrite_prompt_open(_listItems[selectedItem].name, _listItems[selectedItem].path);
else
window_loadsave_select(w, _listItems[selectedItem].path);
@@ -730,103 +730,103 @@ static void window_loadsave_populate_list(int includeNewItem, bool browsable, co
static void window_loadsave_select(rct_window *w, const char *path)
{
SDL_RWops* rw;
switch (_loadsaveType) {
switch (_loadsaveType & 0x0E) {
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME) :
if (gLoadSaveTitleSequenceSave) {
utf8 newName[MAX_PATH];
char *extension = (char*)path_get_extension(path_get_filename(path));
strcpy(newName, path_get_filename(path));
if (_stricmp(extension, ".sv6") != 0 && _stricmp(extension, ".sc6") != 0)
strcat(newName, ".sv6");
if (title_sequence_save_exists(gCurrentTitleSequence, newName)) {
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, uint32) = (uint32)&_listItems[w->selected_list_item].name;
window_text_input_open(w, WIDX_SCROLL, 5435, 5404, 1170, (uint32)_listItems[w->selected_list_item].name, TITLE_SEQUENCE_MAX_SAVE_LENGTH - 1);
}
else {
title_sequence_add_save(gCurrentTitleSequence, path, newName);
window_close(w);
}
}
else if (game_load_save(path)) {
window_close(w);
gfx_invalidate_screen();
rct2_endupdate();
if (gLoadSaveTitleSequenceSave) {
utf8 newName[MAX_PATH];
char *extension = (char*)path_get_extension(path_get_filename(path));
strcpy(newName, path_get_filename(path));
if (_stricmp(extension, ".sv6") != 0 && _stricmp(extension, ".sc6") != 0)
strcat(newName, ".sv6");
if (title_sequence_save_exists(gCurrentTitleSequence, newName)) {
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, uint32) = (uint32)&_listItems[w->selected_list_item].name;
window_text_input_open(w, WIDX_SCROLL, 5435, 5404, 1170, (uint32)_listItems[w->selected_list_item].name, TITLE_SEQUENCE_MAX_SAVE_LENGTH - 1);
}
else {
// 1050, not the best message...
window_error_open(STR_LOAD_GAME, 1050);
title_sequence_add_save(gCurrentTitleSequence, path, newName);
window_close(w);
}
break;
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_GAME) :
rw = platform_sdl_rwfromfile(path, "wb+");
if (rw != NULL) {
int success = scenario_save(rw, gConfigGeneral.save_plugin_data ? 1 : 0);
SDL_RWclose(rw);
if (success) {
window_close_by_class(WC_LOADSAVE);
game_do_command(0, 1047, 0, -1, GAME_COMMAND_SET_RIDE_APPEARANCE, 0, 0);
gfx_invalidate_screen();
} else {
window_error_open(STR_SAVE_GAME, 1047);
}
}
else if (game_load_save(path)) {
window_close(w);
gfx_invalidate_screen();
rct2_endupdate();
}
else {
// 1050, not the best message...
window_error_open(STR_LOAD_GAME, 1050);
}
break;
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_GAME) :
rw = platform_sdl_rwfromfile(path, "wb+");
if (rw != NULL) {
int success = scenario_save(rw, gConfigGeneral.save_plugin_data ? 1 : 0);
SDL_RWclose(rw);
if (success) {
window_close_by_class(WC_LOADSAVE);
game_do_command(0, 1047, 0, -1, GAME_COMMAND_SET_RIDE_APPEARANCE, 0, 0);
gfx_invalidate_screen();
} else {
window_error_open(STR_SAVE_GAME, 1047);
}
break;
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_LANDSCAPE) :
editor_load_landscape(path);
if (1) {
} else {
window_error_open(STR_SAVE_GAME, 1047);
}
break;
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_LANDSCAPE) :
editor_load_landscape(path);
if (1) {
gfx_invalidate_screen();
rct2_endupdate();
}
else {
// 1050, not the best message...
window_error_open(STR_LOAD_LANDSCAPE, 1050);
}
break;
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_LANDSCAPE) :
rw = platform_sdl_rwfromfile(path, "wb+");
if (rw != NULL) {
int success = scenario_save(rw, gConfigGeneral.save_plugin_data ? 3 : 2);
SDL_RWclose(rw);
if (success) {
window_close_by_class(WC_LOADSAVE);
gfx_invalidate_screen();
rct2_endupdate();
}
else {
// 1050, not the best message...
window_error_open(STR_LOAD_LANDSCAPE, 1050);
}
break;
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_LANDSCAPE) :
rw = platform_sdl_rwfromfile(path, "wb+");
if (rw != NULL) {
int success = scenario_save(rw, gConfigGeneral.save_plugin_data ? 3 : 2);
SDL_RWclose(rw);
if (success) {
window_close_by_class(WC_LOADSAVE);
gfx_invalidate_screen();
} else {
window_error_open(STR_SAVE_LANDSCAPE, 1049);
}
} else {
window_error_open(STR_SAVE_LANDSCAPE, 1049);
}
break;
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_SCENARIO) :
{
rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
int parkFlagsBackup = RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32);
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_18;
s6Info->var_000 = 255;
rw = platform_sdl_rwfromfile(path, "wb+");
int success = 0;
if (rw != NULL) {
success = scenario_save(rw, gConfigGeneral.save_plugin_data ? 3 : 2);
SDL_RWclose(rw);
}
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) = parkFlagsBackup;
if (success) {
window_close_by_class(WC_LOADSAVE);
title_load();
} else {
window_error_open(STR_SAVE_SCENARIO, STR_SCENARIO_SAVE_FAILED);
s6Info->var_000 = 4;
}
} else {
window_error_open(STR_SAVE_LANDSCAPE, 1049);
}
break;
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_TRACK) :
window_install_track_open(path);
window_close_by_class(WC_LOADSAVE);
break;
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_SCENARIO) :
{
rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
int parkFlagsBackup = RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32);
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_18;
s6Info->var_000 = 255;
rw = platform_sdl_rwfromfile(path, "wb+");
int success = 0;
if (rw != NULL) {
success = scenario_save(rw, gConfigGeneral.save_plugin_data ? 3 : 2);
SDL_RWclose(rw);
}
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) = parkFlagsBackup;
if (success) {
window_close_by_class(WC_LOADSAVE);
title_load();
} else {
window_error_open(STR_SAVE_SCENARIO, STR_SCENARIO_SAVE_FAILED);
s6Info->var_000 = 4;
}
break;
}
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_TRACK) :
window_install_track_open(path);
window_close_by_class(WC_LOADSAVE);
break;
}
}
#pragma region Overwrite prompt

View File

@@ -24,6 +24,7 @@
#include "../localisation/localisation.h"
#include "../network/network.h"
#include "../sprites.h"
#include "error.h"
#define WWIDTH_MIN 500
#define WHEIGHT_MIN 300
@@ -79,8 +80,6 @@ static void window_server_list_invalidate(rct_window *w);
static void window_server_list_paint(rct_window *w, rct_drawpixelinfo *dpi);
static void window_server_list_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int scrollIndex);
static void server_list_get_item_button(int buttonIndex, int x, int y, int width, int *outX, int *outY);
static rct_window_event_list window_server_list_events = {
window_server_list_close,
window_server_list_mouseup,
@@ -114,10 +113,15 @@ 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_load_saved_servers();
static void server_list_save_saved_servers();
static void dispose_saved_server_list();
static void dispose_saved_server(saved_server *serverInfo);
static void add_saved_server(char *address);
static void remove_saved_server(int index);
static void join_server(char *address, bool spectate);
void window_server_list_open()
{
@@ -162,11 +166,7 @@ void window_server_list_open()
static void window_server_list_close(rct_window *w)
{
if (strlen(_playerName) > 0) {
SafeFree(gConfigNetwork.player_name);
gConfigNetwork.player_name = _strdup(_playerName);
config_save_default();
}
server_list_update_player_name(w);
dispose_saved_server_list();
}
@@ -182,6 +182,9 @@ static void window_server_list_mouseup(rct_window *w, int widgetIndex)
case WIDX_ADD_SERVER:
window_text_input_open(w, widgetIndex, STR_ADD_SERVER, STR_ENTER_HOSTNAME_OR_IP_ADDRESS, STR_NONE, 0, 128);
break;
case WIDX_START_SERVER:
window_loadsave_open(LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME | LOADSAVETYPE_NETWORK, NULL);
break;
}
}
@@ -206,15 +209,23 @@ static void window_server_list_scroll_getsize(rct_window *w, int scrollIndex, in
static void window_server_list_scroll_mousedown(rct_window *w, int scrollIndex, int x, int y)
{
if (w->selected_list_item == -1) return;
int serverIndex = w->selected_list_item;
if (serverIndex < 0) return;
if (serverIndex >= _numSavedServers) return;
char *serverAddress = _savedServers[serverIndex].address;
switch (_hoverButtonIndex) {
case WIDX_LIST_REMOVE:
remove_saved_server(serverIndex);
w->no_list_items = _numSavedServers;
window_invalidate(w);
break;
case WIDX_LIST_SPECTATE:
join_server(serverAddress, true);
break;
default:
// Join
join_server(serverAddress, false);
break;
}
}
@@ -251,20 +262,29 @@ static void window_server_list_scroll_mouseover(rct_window *w, int scrollIndex,
static void window_server_list_textinput(rct_window *w, int widgetIndex, char *text)
{
if (widgetIndex != WIDX_PLAYER_NAME_INPUT || text == NULL)
return;
if (text == NULL || text[0] == 0) return;
if (strcmp(_playerName, text) == 0)
return;
switch (widgetIndex) {
case WIDX_PLAYER_NAME_INPUT:
if (strcmp(_playerName, text) == 0)
return;
if (strlen(text) == 0) {
memset(_playerName, 0, sizeof(_playerName));
} else {
memset(_playerName, 0, sizeof(_playerName));
strcpy(_playerName, text);
if (strlen(text) == 0) {
memset(_playerName, 0, sizeof(_playerName));
} else {
memset(_playerName, 0, sizeof(_playerName));
strcpy(_playerName, text);
}
widget_invalidate(w, WIDX_PLAYER_NAME_INPUT);
break;
case WIDX_ADD_SERVER:
add_saved_server(text);
w->no_list_items = _numSavedServers;
window_invalidate(w);
break;
}
widget_invalidate(w, WIDX_PLAYER_NAME_INPUT);
}
static void window_server_list_invalidate(rct_window *w)
@@ -348,6 +368,15 @@ 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)
{
if (strlen(_playerName) > 0) {
SafeFree(gConfigNetwork.player_name);
gConfigNetwork.player_name = _strdup(_playerName);
config_save_default();
}
}
static char *freadstralloc(FILE *file)
{
int capacity = 64;
@@ -451,3 +480,56 @@ static void dispose_saved_server(saved_server *serverInfo)
SafeFree(serverInfo->name);
SafeFree(serverInfo->description);
}
static void add_saved_server(char *address)
{
_numSavedServers++;
if (_savedServers == NULL) {
_savedServers = malloc(_numSavedServers * sizeof(saved_server));
} else {
_savedServers = realloc(_savedServers, _numSavedServers * sizeof(saved_server));
}
int index = _numSavedServers - 1;
_savedServers[index].address = _strdup(address);
_savedServers[index].name = _strdup(address);
_savedServers[index].description = NULL;
}
static void remove_saved_server(int index)
{
if (_numSavedServers <= index) return;
int serversToMove = _numSavedServers - index - 1;
memmove(&_savedServers[index], &_savedServers[index + 1], serversToMove * sizeof(saved_server));
_numSavedServers--;
_savedServers = realloc(_savedServers, _numSavedServers * sizeof(saved_server));
}
static char *substr(char *start, int length)
{
char *result = malloc(length + 1);
memcpy(result, start, length);
result[length] = 0;
return result;
}
static void join_server(char *address, bool spectate)
{
int port = gConfigNetwork.default_port;
char *colon = strchr(address, ':');
if (colon != NULL) {
address = substr(address, colon - address);
sscanf(colon + 1, "%d", &port);
}
if (!network_begin_client(address, port)) {
window_error_open(STR_UNABLE_TO_CONNECT_TO_SERVER, STR_NONE);
}
if (colon != NULL) {
free(address);
}
}