Allowed Drag & Drop importing of mods and DynOS packs
This commit is contained in:
parent
0d21c66037
commit
9c6fef9ecd
2
Makefile
2
Makefile
|
@ -534,7 +534,7 @@ SRC_DIRS := src src/engine src/game src/audio src/bass_audio src/menu src/buffer
|
|||
BIN_DIRS := bin bin/$(VERSION)
|
||||
|
||||
# PC files
|
||||
SRC_DIRS += src/pc src/pc/gfx src/pc/audio src/pc/controller src/pc/fs src/pc/fs/packtypes src/pc/mods src/pc/network src/pc/network/packets src/pc/network/socket src/pc/utils src/pc/djui src/pc/lua src/pc/lua/utils
|
||||
SRC_DIRS += src/pc src/pc/gfx src/pc/audio src/pc/controller src/pc/fs src/pc/fs/packtypes src/pc/mods src/pc/network src/pc/network/packets src/pc/network/socket src/pc/utils src/pc/utils/miniz src/pc/djui src/pc/lua src/pc/lua/utils
|
||||
|
||||
#ifeq ($(DISCORDRPC),1)
|
||||
# SRC_DIRS += src/pc/discord
|
||||
|
|
|
@ -26,6 +26,7 @@ bool dynos_warp_exit_level(s32 aDelay);
|
|||
bool dynos_warp_to_castle(s32 aLevel);
|
||||
|
||||
// -- dynos packs -- //
|
||||
void dynos_packs_init(void);
|
||||
int dynos_pack_get_count(void);
|
||||
const char* dynos_pack_get_name(s32 index);
|
||||
bool dynos_pack_get_enabled(s32 index);
|
||||
|
|
|
@ -67,6 +67,11 @@ bool dynos_warp_to_castle(s32 aLevel) {
|
|||
|
||||
// -- dynos packs -- //
|
||||
|
||||
void dynos_packs_init(void) {
|
||||
DynOS_Gfx_Init();
|
||||
DynOS_Pack_Init();
|
||||
}
|
||||
|
||||
int dynos_pack_get_count(void) {
|
||||
return DynOS_Pack_GetCount();
|
||||
}
|
||||
|
|
|
@ -15,6 +15,10 @@ DISCONNECT_CLOSED = "\\#ffa0a0\\Disconnected:\\#c8c8c8\\ Host has closed the con
|
|||
DISCONNECT_BIG_MOD = "Server had too large of a mod.\nQuitting."
|
||||
DIED = "@ died"
|
||||
DEBUG_FLY = "@ entered the debug free fly state"
|
||||
IMPORT_MOD_SUCCESS = "\\#a0ffa0\\Imported mod\n\\#c8c8c8\\'@'"
|
||||
IMPORT_DYNOS_SUCCESS = "\\#a0ffa0\\Imported DynOS pack\n\\#c8c8c8\\'@'"
|
||||
IMPORT_FAIL = "\\#ffa0a0\\Failed to import\n\\#c8c8c8\\'@'"
|
||||
IMPORT_FAIL_INGAME = "\\#ffa0a0\\Can not import while in-game"
|
||||
|
||||
[CHAT]
|
||||
KICKING = "Kicking '@'!"
|
||||
|
|
|
@ -15,6 +15,10 @@ DISCONNECT_CLOSED = "\\#ffa0a0\\Déconnecté:\\#c8c8c8\\ L'hôte s'est déconnec
|
|||
DISCONNECT_BIG_MOD = "Le mod utilisé est trop volumineux.\nDéconnexion."
|
||||
DIED = "@ est mort"
|
||||
DEBUG_FLY = "@ a activé le mode vol (débug) "
|
||||
IMPORT_MOD_SUCCESS = "\\#a0ffa0\\Imported mod\n\\#c8c8c8\\'@'"
|
||||
IMPORT_DYNOS_SUCCESS = "\\#a0ffa0\\Imported DynOS pack\n\\#c8c8c8\\'@'"
|
||||
IMPORT_FAIL = "\\#ffa0a0\\Failed to import\n\\#c8c8c8\\'@'"
|
||||
IMPORT_FAIL_INGAME = "\\#ffa0a0\\Can not import while in-game"
|
||||
|
||||
[CHAT]
|
||||
KICKING = "Vous avez expulsé '@' !"
|
||||
|
|
|
@ -15,6 +15,10 @@ DISCONNECT_CLOSED = "\\#ffa0a0\\Verbindung getrennt:\\#c8c8c8\\ Der Servereigent
|
|||
DISCONNECT_BIG_MOD = "Der Server besaß eine modifikation, die zu Groß war.\nDie Verbindung wird geschlossen."
|
||||
DIED = "@ starb"
|
||||
DEBUG_FLY = "@ trat in den Debug-Free-Fly-Zustand ein"
|
||||
IMPORT_MOD_SUCCESS = "\\#a0ffa0\\Imported mod\n\\#c8c8c8\\'@'"
|
||||
IMPORT_DYNOS_SUCCESS = "\\#a0ffa0\\Imported DynOS pack\n\\#c8c8c8\\'@'"
|
||||
IMPORT_FAIL = "\\#ffa0a0\\Failed to import\n\\#c8c8c8\\'@'"
|
||||
IMPORT_FAIL_INGAME = "\\#ffa0a0\\Can not import while in-game"
|
||||
|
||||
[CHAT]
|
||||
KICKING = "'@' wird rausgeschmissen!"
|
||||
|
|
|
@ -15,6 +15,10 @@ DISCONNECT_CLOSED = "\\#ffa0a0\\Disconnected:\\#c8c8c8\\ O host fechou a conexã
|
|||
DISCONNECT_BIG_MOD = "o server tem um mod muito grande.\nQuitting."
|
||||
DIED = "@ morreu"
|
||||
DEBUG_FLY = "@ entrou no estado de debug para voar"
|
||||
IMPORT_MOD_SUCCESS = "\\#a0ffa0\\Imported mod\n\\#c8c8c8\\'@'"
|
||||
IMPORT_DYNOS_SUCCESS = "\\#a0ffa0\\Imported DynOS pack\n\\#c8c8c8\\'@'"
|
||||
IMPORT_FAIL = "\\#ffa0a0\\Failed to import\n\\#c8c8c8\\'@'"
|
||||
IMPORT_FAIL_INGAME = "\\#ffa0a0\\Can not import while in-game"
|
||||
|
||||
[CHAT]
|
||||
KICKING = "Expulso '@'!"
|
||||
|
|
|
@ -15,6 +15,10 @@ DISCONNECT_CLOSED = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ El anfitrión ha cerrad
|
|||
DISCONNECT_BIG_MOD = "El servidor tenía un mod demasiado pesado.\nSaliendo."
|
||||
DIED = "@ ha muerto"
|
||||
DEBUG_FLY = "@ está en estado de vuelo libre debug"
|
||||
IMPORT_MOD_SUCCESS = "\\#a0ffa0\\Imported mod\n\\#c8c8c8\\'@'"
|
||||
IMPORT_DYNOS_SUCCESS = "\\#a0ffa0\\Imported DynOS pack\n\\#c8c8c8\\'@'"
|
||||
IMPORT_FAIL = "\\#ffa0a0\\Failed to import\n\\#c8c8c8\\'@'"
|
||||
IMPORT_FAIL_INGAME = "\\#ffa0a0\\Can not import while in-game"
|
||||
|
||||
[CHAT]
|
||||
KICKING = "¡Expulsando a '@'!"
|
||||
|
|
|
@ -275,13 +275,7 @@ static void enable_mod_read(char** tokens, UNUSED int numTokens) {
|
|||
strncat(combined, tokens[i], 255);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < gLocalMods.entryCount; i++) {
|
||||
struct Mod* mod = gLocalMods.entries[i];
|
||||
if (!strcmp(combined, mod->relativePath)) {
|
||||
mod->enabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mods_enable(combined);
|
||||
}
|
||||
|
||||
static void enable_mod_write(FILE* file) {
|
||||
|
@ -447,7 +441,7 @@ const char *configfile_backup_name(void) {
|
|||
}
|
||||
|
||||
// Loads the config file specified by 'filename'
|
||||
void configfile_load(const char *filename, bool* error) {
|
||||
static void configfile_load_internal(const char *filename, bool* error) {
|
||||
fs_file_t *file;
|
||||
char *line;
|
||||
unsigned int temp;
|
||||
|
@ -563,6 +557,16 @@ NEXT_OPTION:
|
|||
#endif
|
||||
}
|
||||
|
||||
void configfile_load(void) {
|
||||
bool configReadError = false;
|
||||
configfile_load_internal(configfile_name(), &configReadError);
|
||||
if (configReadError) {
|
||||
configfile_load_internal(configfile_backup_name(), &configReadError);
|
||||
} else {
|
||||
configfile_save(configfile_backup_name());
|
||||
}
|
||||
}
|
||||
|
||||
// Writes the config file to 'filename'
|
||||
void configfile_save(const char *filename) {
|
||||
FILE *file;
|
||||
|
|
|
@ -112,7 +112,7 @@ extern bool configDebugInfo;
|
|||
extern bool configDebugError;
|
||||
extern char configLanguage[];
|
||||
|
||||
void configfile_load(const char *filename, bool* error);
|
||||
void configfile_load(void);
|
||||
void configfile_save(const char *filename);
|
||||
const char *configfile_name(void);
|
||||
const char *configfile_backup_name(void);
|
||||
|
|
|
@ -42,8 +42,14 @@ static void _debuglog_print_log(char* logType, char* filename) {
|
|||
_debuglog_print_short_filename(filename);
|
||||
}
|
||||
|
||||
#if defined(DISABLE_MODULE_LOG)
|
||||
#define LOG_DEBUG(...)
|
||||
#define LOG_INFO(...)
|
||||
#define LOG_ERROR(...)
|
||||
#else
|
||||
#define LOG_DEBUG(...) (configDebugPrint ? ( _debuglog_print_log("DEBUG", __FILE__), printf(__VA_ARGS__), printf("\n") ) : 0)
|
||||
#define LOG_INFO(...) (configDebugInfo ? ( _debuglog_print_log("INFO", __FILE__), printf(__VA_ARGS__), printf("\n") ) : 0)
|
||||
#define LOG_ERROR(...) (configDebugError ? ( _debuglog_print_log("ERROR", __FILE__), printf(__VA_ARGS__), printf("\n") ) : 0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -10,6 +10,8 @@ static void djui_panel_dynos_apply(struct DjuiBase* caller) {
|
|||
}
|
||||
|
||||
void djui_panel_dynos_create(struct DjuiBase* caller) {
|
||||
dynos_packs_init();
|
||||
|
||||
int packCount = dynos_pack_get_count();
|
||||
struct DjuiThreePanel* panel = djui_panel_menu_create(DLANG(DYNOS, DYNOS));
|
||||
struct DjuiBase* body = djui_three_panel_get_body(panel);
|
||||
|
|
|
@ -90,6 +90,8 @@ static void djui_panel_host_mods_destroy(struct DjuiBase* base) {
|
|||
void djui_panel_host_mods_create(struct DjuiBase* caller) {
|
||||
bool isRomHacks = (caller->tag == 1);
|
||||
|
||||
|
||||
mods_refresh_local();
|
||||
mods_update_selectable();
|
||||
|
||||
struct DjuiThreePanel* panel = djui_panel_menu_create(isRomHacks
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "src/pc/controller/controller_sdl.h"
|
||||
#include "src/pc/controller/controller_bind_mapping.h"
|
||||
#include "pc/utils/misc.h"
|
||||
#include "pc/mods/mod_import.h"
|
||||
|
||||
// TODO: figure out if this shit even works
|
||||
#ifdef VERSION_EU
|
||||
|
@ -163,6 +164,10 @@ static void gfx_sdl_onkeyup(int scancode) {
|
|||
kb_key_up(translate_sdl_scancode(scancode));
|
||||
}
|
||||
|
||||
static void gfx_sdl_ondropfile(char* path) {
|
||||
mod_import_file(path);
|
||||
}
|
||||
|
||||
static void gfx_sdl_handle_events(void) {
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
|
@ -192,6 +197,9 @@ static void gfx_sdl_handle_events(void) {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case SDL_DROPFILE:
|
||||
gfx_sdl_ondropfile(event.drop.file);
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
game_exit();
|
||||
break;
|
||||
|
|
|
@ -60,9 +60,9 @@ static void _logfile_print_log(enum LogFileType logFileType, char* logType, char
|
|||
}
|
||||
|
||||
#if defined(DEBUG) && defined(DISABLE_MODULE_LOG)
|
||||
#define LOGFILE_DEBUG(_LFT, ...) ( _logfile_print_log(_LFT, "DEBUG", __FILE__, __LINE__), fprintf(gLogFiles[_LFT].file, __VA_ARGS__), fprintf(gLogFiles[_LFT].file, "\n"))
|
||||
#define LOGFILE_INFO(_LFT, ...) ( _logfile_print_log(_LFT, "INFO", __FILE__, __LINE__), fprintf(gLogFiles[_LFT].file, __VA_ARGS__), fprintf(gLogFiles[_LFT].file, "\n"))
|
||||
#define LOGFILE_ERROR(_LFT, ...) ( _logfile_print_log(_LFT, "ERROR", __FILE__, __LINE__), fprintf(gLogFiles[_LFT].file, __VA_ARGS__), fprintf(gLogFiles[_LFT].file, "\n"), LOG_ERROR(__VA_ARGS__))
|
||||
#define LOGFILE_DEBUG(_LFT, ...)
|
||||
#define LOGFILE_INFO(_LFT, ...)
|
||||
#define LOGFILE_ERROR(_LFT, ...)
|
||||
#elif defined(DEBUG) && !defined(DISABLE_MODULE_LOG)
|
||||
#define LOGFILE_DEBUG(_LFT, ...) ( _logfile_print_log(_LFT, "DEBUG", __FILE__, __LINE__), fprintf(gLogFiles[_LFT].file, __VA_ARGS__), fprintf(gLogFiles[_LFT].file, "\n"), LOG_DEBUG(__VA_ARGS__))
|
||||
#define LOGFILE_INFO(_LFT, ...) ( _logfile_print_log(_LFT, "INFO", __FILE__, __LINE__), fprintf(gLogFiles[_LFT].file, __VA_ARGS__), fprintf(gLogFiles[_LFT].file, "\n"), LOG_INFO (__VA_ARGS__))
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#define DISABLE_MODULE_LOG 1
|
||||
#include "pc/debuglog.h"
|
||||
#include "mod_cache.h"
|
||||
#include "mods.h"
|
||||
#include "mod.h"
|
||||
#include "mods_utils.h"
|
||||
#define DISABLE_MODULE_LOG 1
|
||||
#include "pc/debuglog.h"
|
||||
#include "pc/utils/md5.h"
|
||||
|
||||
#define MOD_CACHE_FILENAME "mod.cache"
|
||||
|
|
|
@ -0,0 +1,210 @@
|
|||
#include "PR/ultratypes.h"
|
||||
#include <types.h>
|
||||
#include "pc/platform.h"
|
||||
#include "pc/utils/miniz/miniz.h"
|
||||
#include "pc/debuglog.h"
|
||||
#include "data/dynos.c.h"
|
||||
#include "pc/djui/djui_language.h"
|
||||
#include "pc/djui/djui_popup.h"
|
||||
#include "mods.h"
|
||||
#include "mods_utils.h"
|
||||
|
||||
static bool mod_import_lua(char* src) {
|
||||
char dst[SYS_MAX_PATH] = { 0 };
|
||||
if (!concat_path(dst, (char*)fs_get_write_path(MOD_DIRECTORY), path_basename(src))) {
|
||||
LOG_ERROR("Failed to concat path for lua mod import");
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE* fin = fopen(src, "rb");
|
||||
if (fin == NULL) {
|
||||
LOG_ERROR("Failed to open src path for lua mod import");
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE* fout = fopen(dst, "wb");
|
||||
if (fout == NULL) {
|
||||
LOG_ERROR("Failed to open dst path for lua mod import");
|
||||
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));
|
||||
|
||||
if (wbytes) {
|
||||
LOG_ERROR("Write error on lua mod import");
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(fout);
|
||||
fclose(fin);
|
||||
|
||||
LOG_INFO("Imported lua mod: '%s' -> '%s'", src, dst);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mod_import_zip(char* path, bool* isLua, bool* isDynos) {
|
||||
LOG_INFO("Importing zip mod: %s", path);
|
||||
|
||||
mz_zip_archive zip_archive = { 0 };
|
||||
mz_bool status = mz_zip_reader_init_file(&zip_archive, path, 0);
|
||||
if (!status) {
|
||||
LOG_ERROR("mz_zip_reader_init_file() failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Figure out if its a dynos pack or a mod
|
||||
*isLua = false;
|
||||
*isDynos = false;
|
||||
for (int i = 0; i < (int)mz_zip_reader_get_num_files(&zip_archive); i++) {
|
||||
mz_zip_archive_file_stat file_stat;
|
||||
if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) {
|
||||
LOG_ERROR("mz_zip_reader_file_stat() failed!");
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (str_ends_with(file_stat.m_filename, ".lua")) {
|
||||
*isLua = true;
|
||||
break;
|
||||
} else if (str_ends_with(file_stat.m_filename, ".tex")) {
|
||||
*isDynos = true;
|
||||
} else if (str_ends_with(file_stat.m_filename, ".png")) {
|
||||
*isDynos = true;
|
||||
} else if (str_ends_with(file_stat.m_filename, ".bin")) {
|
||||
*isDynos = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Figure out dst directory
|
||||
char dstDirectory[SYS_MAX_PATH] = { 0 };
|
||||
char dst[SYS_MAX_PATH] = { 0 };
|
||||
if (*isLua) {
|
||||
snprintf(dstDirectory, SYS_MAX_PATH, "%s", (char*)fs_get_write_path(MOD_DIRECTORY));
|
||||
} else if (*isDynos) {
|
||||
snprintf(dstDirectory, SYS_MAX_PATH, "%s", (char*)fs_get_write_path(DYNOS_PACKS_FOLDER));
|
||||
} else {
|
||||
LOG_ERROR("Could not figure out what type of mod this is");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extract the archive
|
||||
for (int i = 0; i < (int)mz_zip_reader_get_num_files(&zip_archive); i++) {
|
||||
mz_zip_archive_file_stat file_stat;
|
||||
if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) {
|
||||
LOG_ERROR("mz_zip_reader_file_stat() failed!");
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Build dst path
|
||||
if (!concat_path(dst, dstDirectory, file_stat.m_filename)) {
|
||||
LOG_ERROR("Failed to concat path for zip mod import");
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_INFO("Filename: \"%s\", Comment: \"%s\", Uncompressed size: %u, Compressed size: %u, Is Dir: %u", file_stat.m_filename, file_stat.m_comment, (u32)file_stat.m_uncomp_size, (u32)file_stat.m_comp_size, mz_zip_reader_is_file_a_directory(&zip_archive, i));
|
||||
|
||||
// If it's a directory, make it
|
||||
if (mz_zip_reader_is_file_a_directory(&zip_archive, i)) {
|
||||
// Remove the directory
|
||||
if (fs_sys_dir_exists(dst)) {
|
||||
mods_delete_folder(dst);
|
||||
}
|
||||
|
||||
if (!fs_sys_mkdir(dst)) {
|
||||
LOG_ERROR("Failed to mkdir for zip mod import");
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to extract all the files to the heap.
|
||||
size_t uncompSize;
|
||||
const char* p = mz_zip_reader_extract_file_to_heap(&zip_archive, file_stat.m_filename, &uncompSize, 0);
|
||||
if (!p) {
|
||||
LOG_ERROR("mz_zip_reader_extract_file_to_heap() failed!");
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Make sure the extraction really succeeded.
|
||||
if (uncompSize != file_stat.m_uncomp_size) {
|
||||
LOG_ERROR("mz_zip_reader_extract_file_to_heap() failed to extract the proper data");
|
||||
mz_free((void*)p);
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Write the data
|
||||
FILE* fout = fopen(dst, "wb");
|
||||
if (fout == NULL) {
|
||||
LOG_ERROR("Failed to open dst path for zip mod import");
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t wbytes = fwrite(p, 1, uncompSize, fout);
|
||||
if (wbytes != uncompSize) {
|
||||
LOG_ERROR("Write error on zip mod import");
|
||||
}
|
||||
|
||||
fclose(fout);
|
||||
|
||||
LOG_INFO("Successfully extracted file \"%s\", size %u", file_stat.m_filename, (u32)uncompSize);
|
||||
|
||||
// We're done.
|
||||
mz_free((void*)p);
|
||||
}
|
||||
// Close the archive, freeing any resources it was using
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mod_import_file(char* path) {
|
||||
bool isLua = false;
|
||||
bool isDynos = false;
|
||||
bool ret = false;
|
||||
|
||||
if (gNetworkType != NT_NONE) {
|
||||
djui_popup_create(DLANG(NOTIF, IMPORT_FAIL_INGAME), 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (str_ends_with(path, ".lua")) {
|
||||
isLua = true;
|
||||
ret = mod_import_lua(path);
|
||||
} else if (str_ends_with(path, ".zip")) {
|
||||
ret = mod_import_zip(path, &isLua, &isDynos);
|
||||
}
|
||||
|
||||
char msg[SYS_MAX_PATH] = { 0 };
|
||||
char* basename = path_basename(path);
|
||||
|
||||
if (ret) {
|
||||
if (isLua) {
|
||||
djui_language_replace(DLANG(NOTIF, IMPORT_MOD_SUCCESS), msg, SYS_MAX_PATH, '@', basename);
|
||||
djui_popup_create(msg, 1);
|
||||
} else if (isDynos) {
|
||||
dynos_packs_init();
|
||||
djui_language_replace(DLANG(NOTIF, IMPORT_DYNOS_SUCCESS), msg, SYS_MAX_PATH, '@', basename);
|
||||
djui_popup_create(msg, 1);
|
||||
}
|
||||
} else {
|
||||
djui_language_replace(DLANG(NOTIF, IMPORT_FAIL), msg, SYS_MAX_PATH, '@', basename);
|
||||
djui_popup_create(msg, 1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef MOD_IMPORT_H
|
||||
#define MOD_IMPORT_H
|
||||
|
||||
bool mod_import_file(char* path);
|
||||
|
||||
#endif
|
|
@ -5,7 +5,6 @@
|
|||
#include "data/dynos.c.h"
|
||||
#include "pc/debuglog.h"
|
||||
|
||||
#define MOD_DIRECTORY "mods"
|
||||
#define MAX_SESSION_CHARS 7
|
||||
|
||||
struct Mods gLocalMods = { 0 };
|
||||
|
@ -14,6 +13,43 @@ struct Mods gActiveMods = { 0 };
|
|||
|
||||
char gRemoteModsBasePath[SYS_MAX_PATH] = { 0 };
|
||||
|
||||
struct LocalEnabledPath {
|
||||
char* relativePath;
|
||||
struct LocalEnabledPath* next;
|
||||
};
|
||||
|
||||
struct LocalEnabledPath* sLocalEnabledPaths = NULL;
|
||||
|
||||
static void mods_local_store_enabled(void) {
|
||||
assert(sLocalEnabledPaths == NULL);
|
||||
struct LocalEnabledPath* prev = NULL;
|
||||
struct Mods* mods = &gLocalMods;
|
||||
|
||||
for (int i = 0; i < mods->entryCount; i ++) {
|
||||
if (!mods->entries[i]->enabled) { continue; }
|
||||
|
||||
struct LocalEnabledPath* n = calloc(1, sizeof(struct LocalEnabledPath));
|
||||
n->relativePath = sys_strdup(mods->entries[i]->relativePath);
|
||||
if (!prev) {
|
||||
sLocalEnabledPaths = n;
|
||||
} else {
|
||||
prev->next = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mods_local_restore_enabled(void) {
|
||||
struct LocalEnabledPath* n = sLocalEnabledPaths;
|
||||
while (n) {
|
||||
struct LocalEnabledPath* next = n->next;
|
||||
mods_enable(n->relativePath);
|
||||
free(n->relativePath);
|
||||
free(n);
|
||||
n = next;
|
||||
}
|
||||
sLocalEnabledPaths = NULL;
|
||||
}
|
||||
|
||||
bool mods_generate_remote_base_path(void) {
|
||||
srand(time(0));
|
||||
|
||||
|
@ -137,9 +173,8 @@ static void mods_load(struct Mods* mods, char* modsBasePath) {
|
|||
|
||||
}
|
||||
|
||||
void mods_init(void) {
|
||||
// load mod cache
|
||||
mod_cache_load();
|
||||
void mods_refresh_local(void) {
|
||||
mods_local_store_enabled();
|
||||
|
||||
// figure out user path
|
||||
bool hasUserPath = true;
|
||||
|
@ -172,6 +207,26 @@ void mods_init(void) {
|
|||
struct Mod* mod = gLocalMods.entries[i];
|
||||
gLocalMods.size += mod->size;
|
||||
}
|
||||
|
||||
mods_local_restore_enabled();
|
||||
}
|
||||
|
||||
void mods_enable(char* relativePath) {
|
||||
if (!relativePath) { return; }
|
||||
|
||||
for (unsigned int i = 0; i < gLocalMods.entryCount; i++) {
|
||||
struct Mod* mod = gLocalMods.entries[i];
|
||||
if (!strcmp(relativePath, mod->relativePath)) {
|
||||
mod->enabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mods_init(void) {
|
||||
// load mod cache
|
||||
mod_cache_load();
|
||||
mods_refresh_local();
|
||||
}
|
||||
|
||||
void mods_clear(struct Mods* mods) {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "mod.h"
|
||||
|
||||
#define MAX_MOD_SIZE (35 * 1048576) // 35MB
|
||||
#define MOD_DIRECTORY "mods"
|
||||
#define TMP_DIRECTORY "tmp"
|
||||
|
||||
struct Mods {
|
||||
|
@ -24,6 +25,9 @@ extern char gRemoteModsBasePath[];
|
|||
bool mods_generate_remote_base_path(void);
|
||||
void mods_activate(struct Mods* mods);
|
||||
void mods_clear(struct Mods* mods);
|
||||
void mods_delete_folder(char* path);
|
||||
void mods_refresh_local(void);
|
||||
void mods_enable(char* relativePath);
|
||||
void mods_init(void);
|
||||
void mods_shutdown(void);
|
||||
|
||||
|
|
|
@ -78,8 +78,8 @@ void mods_update_selectable(void) {
|
|||
mods_size_enforce(&gLocalMods);
|
||||
}
|
||||
|
||||
static void mods_delete_folder(char* path) {
|
||||
LOG_INFO("Deleting tmp folder '%s'", path);
|
||||
void mods_delete_folder(char* path) {
|
||||
LOG_INFO("Deleting folder '%s'", path);
|
||||
struct dirent* dir;
|
||||
DIR* d = opendir(path);
|
||||
if (!d) { return; }
|
||||
|
@ -94,7 +94,7 @@ static void mods_delete_folder(char* path) {
|
|||
mods_delete_folder(fullPath);
|
||||
} else if (fs_sys_file_exists(fullPath)) {
|
||||
if (unlink(fullPath) == -1) {
|
||||
LOG_ERROR("Failed to remove tmp file '%s'", fullPath);
|
||||
LOG_ERROR("Failed to remove file '%s'", fullPath);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -280,17 +280,11 @@ void main_func(void) {
|
|||
mods_init();
|
||||
|
||||
// load config
|
||||
bool configReadError = false;
|
||||
configfile_load(configfile_name(), &configReadError);
|
||||
if (configReadError) {
|
||||
configfile_load(configfile_backup_name(), &configReadError);
|
||||
} else {
|
||||
configfile_save(configfile_backup_name());
|
||||
}
|
||||
|
||||
configfile_load();
|
||||
if (!djui_language_init(configLanguage)) {
|
||||
snprintf(configLanguage, MAX_CONFIG_STRING, "%s", "");
|
||||
}
|
||||
|
||||
dynos_pack_init();
|
||||
|
||||
// If coop_custom_palette_* values are not found in sm64config.txt, the custom palette config will use the default values (Mario's palette)
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
Copyright 2013-2014 RAD Game Tools and Valve Software
|
||||
Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
|
||||
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue