Add an auto updater (#1231)
Some checks are pending
Build coop / build-linux (push) Waiting to run
Build coop / build-steamos (push) Waiting to run
Build coop / build-windows (push) Waiting to run
Build coop / build-macos-arm (push) Waiting to run
Build coop / build-macos-intel (push) Waiting to run

* Add builtin updater to macos

* Compile using trimmed build

* Implement windows

* Add coopdx updater binary

* idk what this is

* Dont need that

* Undo temp code, close stdin, stdout, and stderror so we dont print to error

* Add intel

* Linux

* Finalize

Co-authored-by: AgentXLP <44549182+AgentXLP@users.noreply.github.com>

* Update updater executables (cross compiled, need to test)

* Update windows exec

* Update mac libs

* Update windows lib

* Address review

---------

Co-authored-by: AgentXLP <44549182+AgentXLP@users.noreply.github.com>
This commit is contained in:
EmeraldLockdown 2026-05-10 21:46:35 -05:00 committed by GitHub
parent 388536b385
commit 1d71c4e8de
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 95 additions and 1 deletions

1
.gitignore vendored
View file

@ -22,6 +22,7 @@
# Executables
*.exe
!updater/*/*.exe
*.out
*.app
*.hex

View file

@ -46,6 +46,8 @@ ENHANCE_LEVEL_TEXTURES ?= 1
DISCORD_SDK ?= 1
# Enable CoopNet SDK (used for CoopNet server hosting)
COOPNET ?= 1
# Enable Updater (used for automatic updates)
UPDATER ?= 1
# Enable docker build workarounds
DOCKERBUILD ?= 0
# Sets your optimization level for building.
@ -924,6 +926,22 @@ else
endif
endif
# Updater
UPDATER_EXEC :=
ifeq ($(UPDATER),1)
ifeq ($(WINDOWS_BUILD),1)
UPDATER_EXEC += ./updater/win64/coopdx-updater.exe
else ifeq ($(OSX_BUILD),1)
ifeq ($(shell uname -m),arm64)
UPDATER_EXEC += ./updater/mac_arm/coopdx-updater
else
UPDATER_EXEC += ./updater/mac_intel/coopdx-updater
endif
else ifeq ($(TARGET_RPI),0)
UPDATER_EXEC += ./updater/linux/coopdx-updater
endif
endif
IS_DEV_OR_DEBUG := $(or $(filter 1,$(DEVELOPMENT)),$(filter 1,$(DEBUG)),0)
ifeq ($(IS_DEV_OR_DEBUG),0)
CFLAGS += -fno-ident -fno-common -ffile-prefix-map="$(PWD)"=. -D__DATE__="\"\"" -D__TIME__="\"\"" -Wno-builtin-macro-redefined
@ -1126,6 +1144,9 @@ $(BUILD_DIR)/$(DISCORD_SDK_LIBS):
$(BUILD_DIR)/$(COOPNET_LIBS):
@$(CP) -f $(COOPNET_LIBS) $(BUILD_DIR)
$(BUILD_DIR)/$(UPDATER_EXEC):
@$(CP) -f $(UPDATER_EXEC) $(BUILD_DIR)
$(BUILD_DIR)/$(LANG_DIR):
@$(CP) -f -r $(LANG_DIR) $(BUILD_DIR)
@ -1474,7 +1495,7 @@ ifeq ($(TARGET_N64),1)
$(BUILD_DIR)/$(TARGET).objdump: $(ELF)
$(OBJDUMP) -D $< > $@
else
$(EXE): $(O_FILES) $(MIO0_FILES:.mio0=.o) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(BUILD_DIR)/$(RPC_LIBS) $(BUILD_DIR)/$(DISCORD_SDK_LIBS) $(BUILD_DIR)/$(COOPNET_LIBS) $(BUILD_DIR)/$(LANG_DIR) $(BUILD_DIR)/$(MOD_DIR) $(BUILD_DIR)/$(PALETTES_DIR)
$(EXE): $(O_FILES) $(MIO0_FILES:.mio0=.o) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(BUILD_DIR)/$(RPC_LIBS) $(BUILD_DIR)/$(DISCORD_SDK_LIBS) $(BUILD_DIR)/$(COOPNET_LIBS) $(BUILD_DIR)/$(UPDATER_EXEC) $(BUILD_DIR)/$(LANG_DIR) $(BUILD_DIR)/$(MOD_DIR) $(BUILD_DIR)/$(PALETTES_DIR)
@$(PRINT) "$(GREEN)Linking executable: $(BLUE)$@ $(NO_COL)\n"
$(V)$(LD) $(PROF_FLAGS) -L $(BUILD_DIR) -o $@ $(O_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(LDFLAGS)
endif
@ -1512,6 +1533,7 @@ all:
cp build/us_pc/discord_game_sdk.dylib $(APP_MACOS_DIR); \
cp build/us_pc/libdiscord_game_sdk.dylib $(APP_MACOS_DIR); \
cp build/us_pc/libcoopnet.dylib $(APP_MACOS_DIR); \
cp build/us_pc/coopdx-updater $(APP_MACOS_DIR); \
cp build/us_pc/libjuice.1.6.2.dylib $(APP_MACOS_DIR); \
cp $(SDL2_LIB) $(APP_MACOS_DIR)/libSDL2.dylib; \
install_name_tool -change $(BREW_PREFIX)/lib/libSDL2-2.0.0.dylib @executable_path/libSDL2.dylib $(APP_MACOS_DIR)/sm64coopdx > /dev/null 2>&1; \

View file

@ -5,6 +5,7 @@
#include "djui_panel_pause.h"
#include "djui_panel_join.h"
#include "djui_panel_join_message.h"
#include "djui_panel_confirm.h"
#include "djui_ctx_display.h"
#include "djui_fps_display.h"
#include "djui_lua_profiler.h"
@ -152,6 +153,17 @@ void djui_connect_menu_open(void) {
djui_panel_join_message_create(NULL);
}
static void djui_update_game(UNUSED struct DjuiBase *caller) {
update_game();
}
void djui_open_update_panel(void) {
djui_panel_shutdown();
gDjuiInMainMenu = true;
djui_panel_main_create(NULL);
djui_panel_confirm_create(NULL, "UPDATE", "An update is available. Would you like to install it?", djui_update_game);
}
void djui_lua_error(char* text, struct DjuiColor color) {
if (!sDjuiLuaError) { return; }
djui_base_set_color(&sDjuiLuaError->base, color.r, color.g, color.b, color.a);

View file

@ -46,6 +46,7 @@ extern bool gDjuiDisabled;
void djui_init(void);
void djui_init_late(void);
void djui_connect_menu_open(void);
void djui_open_update_panel(void);
void djui_lua_error(char* text, struct DjuiColor color);
void djui_lua_error_clear(void);
void djui_render(void);

View file

@ -577,6 +577,10 @@ int main(int argc, char *argv[]) {
show_update_popup();
if (can_update_game()) {
djui_open_update_panel();
}
// initialize network
if (gCLIOpts.network == NT_CLIENT) {
network_set_system(NS_SOCKET);

View file

@ -1,3 +1,9 @@
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <PR/ultratypes.h>
@ -14,6 +20,7 @@
#include "engine/math_util.h"
#include "pc/configfile.h"
#include "pc/pc_main.h"
#include "pc/update_checker.h"
float smooth_step(float edge0, float edge1, float x) {
float t = (x - edge0) / (edge1 - edge0);
@ -594,3 +601,47 @@ void str_seperator_concat(char *output_buffer, int buffer_size, char** strings,
}
}
}
static char *get_update_path(void) {
#ifdef _WIN32
char updateExecFilename[] = "coopdx-updater.exe";
#else
char updateExecFilename[] = "coopdx-updater";
#endif
static char sUpdateExecFilePath[SYS_MAX_PATH];
// this may truncate as sys_exe_path_dir is allocated to be of size SYS_MAX_SIZE, nonetheless such a limit should not be hit during normal use.
snprintf(sUpdateExecFilePath, sizeof(sUpdateExecFilePath), "%s%s%s", sys_exe_path_dir(), PATH_SEPARATOR, updateExecFilename);
return sUpdateExecFilePath;
}
bool can_update_game(void) {
// the file is not guaranteed to exist, so make sure we have the updater installed
return fs_sys_file_exists(get_update_path()) && gUpdateMessage;
}
void update_game(void) {
const char *updateExecFilePath = get_update_path();
#ifdef _WIN32
STARTUPINFOA si = { 0 };
PROCESS_INFORMATION pi = { 0 };
si.cb = sizeof(si);
char commandBuf[SYS_MAX_PATH];
// this can truncate, but under normal use, SYS_MAX_PATH should not ever be filled up
snprintf(commandBuf, sizeof(commandBuf), "%s --game-update", updateExecFilePath);
if (CreateProcessA(NULL, commandBuf, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
exit(0);
#else
fclose(stdin);
fclose(stdout);
fclose(stderr);
execl(updateExecFilePath, "coopdx-updater", "--game-update", NULL);
exit(1);
#endif
}

View file

@ -38,4 +38,7 @@ void detect_and_skip_mtx_interpolation(Mtx** mtxPrev, Mtx** mtx);
void str_seperator_concat(char *output_buffer, int buffer_size, char** strings, int num_strings, char* seperator);
bool can_update_game(void);
void update_game(void);
#endif

BIN
updater/linux/coopdx-updater Executable file

Binary file not shown.

BIN
updater/mac_arm/coopdx-updater Executable file

Binary file not shown.

BIN
updater/mac_intel/coopdx-updater Executable file

Binary file not shown.

BIN
updater/win64/coopdx-updater.exe Executable file

Binary file not shown.