From 41d7b52f8c733df7c991fda51c3b4ac3b0139238 Mon Sep 17 00:00:00 2001 From: Cooliokid956 <68075390+Cooliokid956@users.noreply.github.com> Date: Thu, 1 Jan 2026 03:04:25 -0600 Subject: [PATCH] Add version info (Windows) + Smart update checker --- res/icon.rc | 28 +++++++++++++- src/pc/djui/djui_panel_join_lobbies.c | 2 +- src/pc/djui/djui_panel_main.c | 15 +++++--- src/pc/network/coopnet/coopnet.c | 6 +-- src/pc/network/packets/packet_join.c | 6 +-- src/pc/network/packets/packet_mod_list.c | 6 +-- src/pc/network/version.c | 6 ++- src/pc/network/version.h | 7 ++++ src/pc/pc_main.h | 4 +- src/pc/update_checker.c | 48 ++++++++++++++++++++---- 10 files changed, 101 insertions(+), 27 deletions(-) diff --git a/res/icon.rc b/res/icon.rc index 7e84e50bf..a7d340011 100644 --- a/res/icon.rc +++ b/res/icon.rc @@ -1 +1,27 @@ -id ICON res/icon.ico \ No newline at end of file +id ICON res/icon.ico + +#include +#include "../src/pc/network/version.h" +VS_VERSION_INFO VERSIONINFO +FILEVERSION 1,(VERSION_NUMBER-37),MINOR_VERSION_NUMBER,0 +PRODUCTVERSION VERSION_NUMBER,MINOR_VERSION_NUMBER,0,0 +FILEOS VOS_NT +FILETYPE VFT_APP +{ + BLOCK StringFileInfo + { + BLOCK "040904B0" + { + VALUE "FileDescription", "Super Mario 64 Coop Deluxe" + VALUE "FileVersion", SM64COOPDX_VERSION + VALUE "ProductName", "Super Mario 64 Coop Deluxe" + VALUE "ProductVersion", SM64COOPDX_VERSION + VALUE "InternalName", "sm64coopdx.exe" + VALUE "OriginalFilename", "sm64coopdx.exe" + } + } + BLOCK "VarFileInfo" + { + VALUE "Translation", 0x0409, 0x04B0 + } +} \ No newline at end of file diff --git a/src/pc/djui/djui_panel_join_lobbies.c b/src/pc/djui/djui_panel_join_lobbies.c index bc0d7514f..0a9278b48 100644 --- a/src/pc/djui/djui_panel_join_lobbies.c +++ b/src/pc/djui/djui_panel_join_lobbies.c @@ -87,7 +87,7 @@ void djui_panel_join_query(uint64_t aLobbyId, UNUSED uint64_t aOwnerId, uint16_t snprintf(mode, 64, "%s", aMode); char version[MAX_VERSION_LENGTH] = { 0 }; - snprintf(version, MAX_VERSION_LENGTH, "%s", get_version()); + snprintf(version, MAX_VERSION_LENGTH, "%s", get_real_version()); bool disabled = strcmp(version, aVersion) != 0; if (disabled) { snprintf(mode, 64, "\\#ff0000\\[%s]", aVersion); diff --git a/src/pc/djui/djui_panel_main.c b/src/pc/djui/djui_panel_main.c index 57707045c..0a849bb51 100644 --- a/src/pc/djui/djui_panel_main.c +++ b/src/pc/djui/djui_panel_main.c @@ -61,15 +61,18 @@ void djui_panel_main_create(struct DjuiBase* caller) { djui_base_set_color(&message->base, 255, 255, 160, 255); djui_text_set_alignment(message, DJUI_HALIGN_CENTER, DJUI_VALIGN_BOTTOM); } else { - #ifdef COMPILE_TIME - struct DjuiText* version = djui_text_create(&panel->base, get_version_with_build_date()); - #else - struct DjuiText* version = djui_text_create(&panel->base, get_version()); - #endif + struct DjuiText* version = djui_text_create( + &panel->base, + #ifdef COMPILE_TIME + get_version_with_build_date() + #else + get_version() + #endif + ); djui_base_set_size_type(&version->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&version->base, 1.0f, 1.0f); djui_base_set_color(&version->base, 50, 50, 50, 255); - djui_text_set_alignment(version, DJUI_HALIGN_RIGHT, DJUI_VALIGN_BOTTOM); + djui_text_set_alignment(version, configExCoopTheme ? DJUI_HALIGN_CENTER : DJUI_HALIGN_RIGHT, DJUI_VALIGN_BOTTOM); } } diff --git a/src/pc/network/coopnet/coopnet.c b/src/pc/network/coopnet/coopnet.c index 5b5ac4244..e343d75e4 100644 --- a/src/pc/network/coopnet/coopnet.c +++ b/src/pc/network/coopnet/coopnet.c @@ -177,7 +177,7 @@ static void coopnet_populate_description(void) { char* buffer = sCoopNetDescription; int bufferLength = MAX_COOPNET_DESCRIPTION_LENGTH; // get version - const char* version = get_version(); + const char* version = get_real_version(); int versionLength = strlen(version); snprintf(buffer, bufferLength, "%s", version); buffer += versionLength; @@ -212,12 +212,12 @@ void ns_coopnet_update(void) { if (sReconnecting) { LOG_INFO("Update lobby"); coopnet_populate_description(); - coopnet_lobby_update(sLocalLobbyId, GAME_NAME, get_version(), configPlayerName, mode, sCoopNetDescription); + coopnet_lobby_update(sLocalLobbyId, GAME_NAME, get_real_version(), configPlayerName, mode, sCoopNetDescription); } else { LOG_INFO("Create lobby"); snprintf(gCoopNetPassword, 64, "%s", configPassword); coopnet_populate_description(); - coopnet_lobby_create(GAME_NAME, get_version(), configPlayerName, mode, (uint16_t)configAmountOfPlayers, gCoopNetPassword, sCoopNetDescription); + coopnet_lobby_create(GAME_NAME, get_real_version(), configPlayerName, mode, (uint16_t)configAmountOfPlayers, gCoopNetPassword, sCoopNetDescription); } } else if (sNetworkType == NT_CLIENT) { LOG_INFO("Join lobby"); diff --git a/src/pc/network/packets/packet_join.c b/src/pc/network/packets/packet_join.c index 0f1602352..c41f23414 100644 --- a/src/pc/network/packets/packet_join.c +++ b/src/pc/network/packets/packet_join.c @@ -45,7 +45,7 @@ void network_send_join_request(void) { struct Packet p = { 0 }; packet_init(&p, PACKET_JOIN_REQUEST, true, PLMT_NONE); char version[MAX_VERSION_LENGTH] = { 0 }; - snprintf(version, MAX_VERSION_LENGTH, "%s", get_version()); + snprintf(version, MAX_VERSION_LENGTH, "%s", get_real_version()); packet_write(&p, &version, sizeof(u8) * MAX_VERSION_LENGTH); packet_write(&p, &configPlayerModel, sizeof(u8)); @@ -107,7 +107,7 @@ void network_send_join(struct Packet* joinRequestPacket) { } char version[MAX_VERSION_LENGTH] = { 0 }; - snprintf(version, MAX_VERSION_LENGTH, "%s", get_version()); + snprintf(version, MAX_VERSION_LENGTH, "%s", get_real_version()); LOG_INFO("sending version: %s", version); struct Packet p = { 0 }; @@ -143,7 +143,7 @@ void network_receive_join(struct Packet* p) { gOverrideEeprom = eeprom; char version[MAX_VERSION_LENGTH] = { 0 }; - snprintf(version, MAX_VERSION_LENGTH, "%s", get_version()); + snprintf(version, MAX_VERSION_LENGTH, "%s", get_real_version()); LOG_INFO("client has version: %s", version); char remoteVersion[MAX_VERSION_LENGTH] = { 0 }; diff --git a/src/pc/network/packets/packet_mod_list.c b/src/pc/network/packets/packet_mod_list.c index 23a4411d2..28e8ed05a 100644 --- a/src/pc/network/packets/packet_mod_list.c +++ b/src/pc/network/packets/packet_mod_list.c @@ -20,7 +20,7 @@ void network_send_mod_list_request(void) { struct Packet p = { 0 }; packet_init(&p, PACKET_MOD_LIST_REQUEST, true, PLMT_NONE); char version[MAX_VERSION_LENGTH] = { 0 }; - snprintf(version, MAX_VERSION_LENGTH, "%s", get_version()); + snprintf(version, MAX_VERSION_LENGTH, "%s", get_real_version()); packet_write(&p, &version, sizeof(u8) * MAX_VERSION_LENGTH); network_send_to(PACKET_DESTINATION_SERVER, &p); @@ -47,7 +47,7 @@ void network_send_mod_list(void) { packet_init(&p, PACKET_MOD_LIST, true, PLMT_NONE); char version[MAX_VERSION_LENGTH] = { 0 }; - snprintf(version, MAX_VERSION_LENGTH, "%s", get_version()); + snprintf(version, MAX_VERSION_LENGTH, "%s", get_real_version()); LOG_INFO("sending version: %s", version); packet_write(&p, &version, sizeof(u8) * MAX_VERSION_LENGTH); packet_write(&p, &gActiveMods.entryCount, sizeof(u16)); @@ -135,7 +135,7 @@ void network_receive_mod_list(struct Packet* p) { } char version[MAX_VERSION_LENGTH] = { 0 }; - snprintf(version, MAX_VERSION_LENGTH, "%s", get_version()); + snprintf(version, MAX_VERSION_LENGTH, "%s", get_real_version()); LOG_INFO("client has version: %s", version); // verify version diff --git a/src/pc/network/version.c b/src/pc/network/version.c index fd792dc0a..f8b64c575 100644 --- a/src/pc/network/version.c +++ b/src/pc/network/version.c @@ -4,7 +4,7 @@ static char sVersionString[MAX_VERSION_LENGTH] = { 0 }; -const char* get_version(void) { +const char* get_real_version(void) { #if defined(VERSION_US) snprintf(sVersionString, MAX_VERSION_LENGTH, "%s", SM64COOPDX_VERSION); #else @@ -13,6 +13,10 @@ const char* get_version(void) { return sVersionString; } +const char* get_version(void) { + return configExCoopTheme ? EX_VERSION : get_real_version(); +} + #ifdef COMPILE_TIME const char* get_version_with_build_date(void) { #if defined(VERSION_US) diff --git a/src/pc/network/version.h b/src/pc/network/version.h index 9bda5050c..decc17b13 100644 --- a/src/pc/network/version.h +++ b/src/pc/network/version.h @@ -8,6 +8,10 @@ #define VERSION_NUMBER 41 #define MINOR_VERSION_NUMBER 1 +#define STR(x) #x +#define _EX_VERSION(major, minor) STR(major) "." STR(minor) +#define EX_VERSION "v" _EX_VERSION(VERSION_NUMBER, MINOR_VERSION_NUMBER) + #if defined(VERSION_JP) #define VERSION_REGION "JP" #elif defined(VERSION_EU) @@ -29,8 +33,11 @@ #define WINDOW_NAME "Super Mario 64 Coop Deluxe" #endif +#define EX_WINDOW_NAME "sm64ex-coop:" + #define MAX_VERSION_LENGTH 128 +const char* get_real_version(void); const char* get_version(void); #ifdef COMPILE_TIME const char* get_version_with_build_date(void); diff --git a/src/pc/pc_main.h b/src/pc/pc_main.h index 384bcc8dc..37482c80f 100644 --- a/src/pc/pc_main.h +++ b/src/pc/pc_main.h @@ -54,9 +54,9 @@ extern "C" { #endif #ifdef GIT_HASH -#define TITLE ({ char title[96] = ""; snprintf(title, 96, "%s %s, [%s]", WINDOW_NAME, get_version(), GIT_HASH); title; }) +#define TITLE ({ char title[96] = ""; snprintf(title, 96, "%s %s, [%s]", configExCoopTheme ? EX_WINDOW_NAME : WINDOW_NAME, get_version(), GIT_HASH); title; }) #else -#define TITLE ({ char title[96] = ""; snprintf(title, 96, "%s %s", WINDOW_NAME, get_version()); title; }) +#define TITLE ({ char title[96] = ""; snprintf(title, 96, "%s %s", configExCoopTheme ? EX_WINDOW_NAME : WINDOW_NAME, get_version()); title; }) #endif #define AT_STARTUP __attribute__((constructor)) diff --git a/src/pc/update_checker.c b/src/pc/update_checker.c index 77d21abb5..13cbd6bf3 100644 --- a/src/pc/update_checker.c +++ b/src/pc/update_checker.c @@ -23,7 +23,20 @@ downloading and parsing a source file. */ static char sVersionUpdateTextBuffer[256] = { 0 }; -static char sRemoteVersion[8] = { 0 }; +static char sRemoteVersionStr[10] = { 0 }; + +struct Version { + int maj, min, fix; +}; + +bool is_version_newer(struct Version old, struct Version new) { + if (new.maj != old.maj) return new.maj > old.maj; + if (new.min != old.min) return new.min > old.min; + return new.fix > old.fix; +} + +static struct Version sClientVersion = { 0 }; +static struct Version sRemoteVersion = { 0 }; bool gUpdateMessage = false; @@ -51,6 +64,16 @@ size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata) { } #endif +void parse_to_version(const char *str, struct Version *ver) { + printf("%s\n", str); + char* end; + ver->maj = strtol(str+1, &end, 10); + if (end) ver->min = strtol(end+1, &end, 10); + if (end) ver->fix = strtol(end+1, &end, 10); + + printf("v%i.%i.%i\n", ver->maj, ver->min, ver->fix); +} + void parse_version(const char *data) { const char *version = strstr(data, VERSION_IDENTIFIER); if (version == NULL) { return; } @@ -58,14 +81,17 @@ void parse_version(const char *data) { version += len; const char *end = strchr(version, '"'); size_t versionLength = (size_t)(end - version); - if (versionLength > sizeof(sRemoteVersion) - 1) { return; } - memcpy(sRemoteVersion, version, versionLength); - sRemoteVersion[versionLength] = '\0'; + if (versionLength > sizeof(sRemoteVersionStr) - 1) { return; } + memcpy(sRemoteVersionStr, version, versionLength); + sRemoteVersionStr[versionLength] = '\0'; + + parse_to_version(sRemoteVersionStr, &sRemoteVersion); + parse_to_version(SM64COOPDX_VERSION, &sClientVersion); } // function to download a text file from the internet void get_version_remote(void) { - sRemoteVersion[0] = '\0'; + sRemoteVersionStr[0] = '\0'; #if defined(_WIN32) || defined(_WIN64) char buffer[0xFF] = { 0 }; @@ -145,13 +171,21 @@ void check_for_updates(void) { LOADING_SCREEN_MUTEX(loading_screen_set_segment_text("Checking For Updates")); get_version_remote(); - if (sRemoteVersion[0] == 'v' && strcmp(sRemoteVersion, get_version())) { + if (sRemoteVersionStr[0] == 'v' && is_version_newer(sClientVersion, sRemoteVersion)) { + if (configExCoopTheme) { + snprintf( + sRemoteVersionStr, 10, + "v%i.%i", + sRemoteVersion.min + 37, + sRemoteVersion.fix + ); + } snprintf( sVersionUpdateTextBuffer, 256, "\\#ffffa0\\%s\n\\#dcdcdc\\%s: %s\n%s: %s", DLANG(NOTIF, UPDATE_AVAILABLE), DLANG(NOTIF, LATEST_VERSION), - sRemoteVersion, + sRemoteVersionStr, DLANG(NOTIF, YOUR_VERSION), get_version() );