bool mm_LoadMetamodLibrary(MetamodBackend backend, char *buffer, size_t maxlength) { size_t len, temp_len; char mm_path[PLATFORM_MAX_PATH * 2]; /* Get our path */ if (!mm_GetFileOfAddress((void*)mm_GetFileOfAddress, mm_path, sizeof(mm_path))) return false; len = strlen(mm_path); temp_len = strlen("server" LIBRARY_EXT); if (len < temp_len) return false; /* Build log file name */ mm_path[len - temp_len] = '\0'; mm_Format(mm_fatal_logfile, sizeof(mm_fatal_logfile), "%smetamod-fatal.log", mm_path); /* Replace server.dll with the new binary we want */ mm_Format(&mm_path[len - temp_len], sizeof(mm_path) - (len - temp_len), "metamod.%s" LIBRARY_MINEXT, backend_names[backend]); mm_library = (HMODULE)mm_LoadLibrary(mm_path, buffer, maxlength); return (mm_library != NULL); }
void * mm_LoadLibrary(const char *path, char *buffer, size_t maxlength) { void *lib; #if defined _WIN32 lib = (void*)LoadLibrary(path); if (lib == NULL) { mm_GetPlatformError(buffer, maxlength); return NULL; } #elif defined __linux__ || defined __APPLE__ lib = dlopen(path, RTLD_NOW); if (lib == NULL) { mm_Format(buffer, maxlength, "%s", dlerror()); return NULL; } #endif return lib; }
static bool mm_DetectGameInformation() { char game_path[PLATFORM_MAX_PATH]; if (game_info_detected) return game_info_detected == 1 ? true : false; game_info_detected = -1; mm_GetGameName(game_name, sizeof(game_name)); if (!mm_GetFileOfAddress((void*)mm_DetectGameInformation, mm_path, sizeof(mm_path))) { mm_LogFatal("Could not locate Metamod loader library path"); return false; } if (!mm_ResolvePath(game_name, game_path, sizeof(game_path))) { mm_LogFatal("Could not resolve path: %s", game_name); return false; } FILE *fp; char gameinfo_path[PLATFORM_MAX_PATH]; mm_PathFormat(gameinfo_path, sizeof(gameinfo_path), "%s/gameinfo.txt", game_path); if ((fp = fopen(gameinfo_path, "rt")) == NULL) { mm_LogFatal("Could not read file: %s", gameinfo_path); return false; } char temp_path[PLATFORM_MAX_PATH]; char cur_path[PLATFORM_MAX_PATH]; getcwd(cur_path, sizeof(cur_path)); char *ptr; const char *lptr; bool search = false; char buffer[255], key[128], val[128]; while (!feof(fp) && fgets(buffer, sizeof(buffer), fp) != NULL) { mm_TrimComments(buffer); mm_TrimLeft(buffer); mm_TrimRight(buffer); if (stricmp(buffer, "SearchPaths") == 0) search = true; if (!search) continue; mm_KeySplit(buffer, key, sizeof(key) - 1, val, sizeof(val) - 1); if (stricmp(key, "Game") != 0 && stricmp(key, "GameBin") != 0) continue; if (strncmp(val, "|gameinfo_path|", sizeof("|gameinfo_path|") - 1) == 0) { ptr = &val[sizeof("|gameinfo_path|") - 1]; if (ptr[0] == '.') ptr++; lptr = game_path; } else { ptr = val; lptr = cur_path; } if (stricmp(key, "GameBin") == 0) mm_PathFormat(temp_path, sizeof(temp_path), "%s/%s/" SERVER_NAME, lptr, ptr); else if (!ptr[0]) mm_PathFormat(temp_path, sizeof(temp_path), "%s/bin/" SERVER_NAME, lptr); else mm_PathFormat(temp_path, sizeof(temp_path), "%s/%s/bin/" SERVER_NAME, lptr, ptr); if (mm_PathCmp(mm_path, temp_path)) continue; FILE *exists = fopen(temp_path, "rb"); if (!exists) continue; fclose(exists); /* exists is still non-NULL... use this as a flag */ for (unsigned int i = 0; i < gamedll_path_count; i++) { if (mm_PathCmp(gamedll_paths[i], temp_path)) { exists = NULL; break; } } if (!exists) continue; mm_Format(gamedll_paths[gamedll_path_count], PLATFORM_MAX_PATH, "%s", temp_path); gamedll_path_count++; if (gamedll_path_count == MAX_GAMEDLL_PATHS) break; } fclose(fp); game_info_detected = 1; if (gamedll_path_count == 0) { mm_LogFatal("Could not detect any valid game paths in gameinfo.txt"); return false; } return true; }