From 9e12283d90ece2bfb1d4c3d5f0df5e863f8ad155 Mon Sep 17 00:00:00 2001 From: EmeraldLockdown <86802223+EmeraldLoc@users.noreply.github.com> Date: Fri, 13 Mar 2026 21:19:44 -0500 Subject: [PATCH] Allow themes to be imported --- lang/English.ini | 1 + src/pc/mods/mod_import.c | 88 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 83 insertions(+), 6 deletions(-) diff --git a/lang/English.ini b/lang/English.ini index 49faf6443..ba3b0cc94 100644 --- a/lang/English.ini +++ b/lang/English.ini @@ -18,6 +18,7 @@ DEBUG_FLY = "@ entered debug free-fly mode" IMPORT_MOD_SUCCESS = "\\#a0ffa0\\Imported mod\n\\#dcdcdc\\'@'" IMPORT_DYNOS_SUCCESS = "\\#a0ffa0\\Imported DynOS pack\n\\#dcdcdc\\'@'" IMPORT_PALETTE_SUCCESS = "\\#a0ffa0\\Imported palette preset\n\\#dcdcdc\\'@'" +IMPORT_THEME_SUCCESS = "\\#a0ffa0\\Imported theme\n\\#dcdcdc\\'@'" IMPORT_FAIL = "\\#ffa0a0\\Failed to import\n\\#dcdcdc\\'@'" IMPORT_FAIL_INGAME = "\\#ffa0a0\\Can not import while in-game" COOPNET_CONNECTION_FAILED = "\\#ffa0a0\\Could not connect to CoopNet!" diff --git a/src/pc/mods/mod_import.c b/src/pc/mods/mod_import.c index ad9de35c7..ff99c8d13 100644 --- a/src/pc/mods/mod_import.c +++ b/src/pc/mods/mod_import.c @@ -1,5 +1,6 @@ #include "PR/ultratypes.h" #include "types.h" +#include "pc/ini.h" #include "pc/platform.h" #include "pc/utils/miniz/miniz.h" #include "pc/debuglog.h" @@ -102,6 +103,86 @@ static bool mod_import_palette(char* src) { return true; } +static bool mod_import_theme(char* src) { + const char* themesDirectory = fs_get_write_path(THEMES_DIRECTORY); + fs_sys_mkdir(themesDirectory); + + char dst[SYS_MAX_PATH] = { 0 }; + if (!concat_path(dst, (char*)themesDirectory, path_basename(src))) { + LOG_ERROR("Failed to concat path for theme ini import"); + return false; + } + + FILE* fin = fopen(src, "rb"); + if (fin == NULL) { + LOG_ERROR("Failed to open src path for theme ini import"); + return false; + } + + FILE* fout = fopen(dst, "wb"); + if (fout == NULL) { + LOG_ERROR("Failed to open dst path for theme ini import"); + fclose(fin); + return false; + } + + size_t rbytes; + size_t wbytes; + unsigned char buff[8192]; + do { + rbytes = fread(buff, 1, sizeof(buff), fin); + if (rbytes > 0) { + wbytes = fwrite(buff, 1, rbytes, fout); + } else { + wbytes = 0; + } + } while ((rbytes > 0) && (rbytes == wbytes)); + + fclose(fout); + fclose(fin); + + if (wbytes) { + LOG_ERROR("Write error on theme ini import"); + return false; + } + + LOG_INFO("Imported theme ini: '%s' -> '%s'", src, dst); + // nuke current themes and load them back + for (int i = DJUI_THEME_COUNT; i < MAX_DJUI_THEMES; i++) { + free(gDjuiThemes[i]); + gDjuiThemes[i] = NULL; + } + djui_themes_load(); + + return true; +} + +static bool mod_import_ini(char* src) { + struct ini_t* importIni = ini_load(src); + bool ret = false; + + char msg[SYS_MAX_PATH] = { 0 }; + char* basename = path_basename(src); + + // bit hacky, but works + if (ini_get(importIni, "PALETTE", "PANTS_R") != NULL) { + ret = mod_import_palette(src); + if (ret) { + djui_language_replace(DLANG(NOTIF, IMPORT_PALETTE_SUCCESS), msg, SYS_MAX_PATH, '@', basename); + djui_popup_create(msg, 2); + } + } else if (ini_get(importIni, "THEME", "theme_header_font") != NULL) { + ret = mod_import_theme(src); + if (ret) { + djui_language_replace(DLANG(NOTIF, IMPORT_THEME_SUCCESS), msg, SYS_MAX_PATH, '@', basename); + djui_popup_create(msg, 2); + } + } + + ini_free(importIni); + return ret; +} + static bool mod_import_zip(char* path, bool* isLua, bool* isDynos) { LOG_INFO("Importing zip mod: %s", path); @@ -255,7 +336,6 @@ static bool mod_import_zip(char* path, bool* isLua, bool* isDynos) { bool mod_import_file(char* path) { bool isLua = false; bool isDynos = false; - bool isPalette = false; bool ret = false; if (gNetworkType != NT_NONE && !path_ends_with(path, ".ini")) { @@ -267,8 +347,7 @@ bool mod_import_file(char* path) { isLua = true; ret = mod_import_lua(path); } else if (path_ends_with(path, ".ini")) { - isPalette = true; - ret = mod_import_palette(path); + ret = mod_import_ini(path); } else if (path_ends_with(path, ".zip")) { ret = mod_import_zip(path, &isLua, &isDynos); } @@ -285,9 +364,6 @@ bool mod_import_file(char* path) { dynos_gfx_init(); djui_language_replace(DLANG(NOTIF, IMPORT_DYNOS_SUCCESS), msg, SYS_MAX_PATH, '@', basename); djui_popup_create(msg, 2); - } else if (isPalette) { - djui_language_replace(DLANG(NOTIF, IMPORT_PALETTE_SUCCESS), msg, SYS_MAX_PATH, '@', basename); - djui_popup_create(msg, 2); } } else { djui_language_replace(DLANG(NOTIF, IMPORT_FAIL), msg, SYS_MAX_PATH, '@', basename);