134 lines
4.6 KiB
C
134 lines
4.6 KiB
C
#include <Windows.h>
|
|
#include <stdio.h>
|
|
|
|
#include "../lib/mice/mice.h"
|
|
#include "locate.h"
|
|
#include "spawn.h"
|
|
|
|
bool debug_wait = false;
|
|
int boot_delay = 0;
|
|
char exe_name[MAX_PATH + 1] = "";
|
|
char commandline[MAX_PATH + 1] = "";
|
|
|
|
void print_help(char* exe) {
|
|
log_info(plfBoot, "Usage: %s [-h] [-t] [-b executable.exe] [-d]", exe);
|
|
log_info(plfBoot, " -h: Print this help message and exit");
|
|
log_info(plfBoot, " -b: Specify the game binary to use");
|
|
log_info(plfBoot, " --mice-d: Wait for a debugger to attach when starting");
|
|
log_info(plfBoot, " --mice.<config>=<setting>: Set launcher options");
|
|
exit(0);
|
|
}
|
|
|
|
bool parse_cmdline(int argc, char* argv[]) {
|
|
for (int i = 1; i < argc; i++) {
|
|
if (strcmp(argv[i], "-h") == 0) {
|
|
print_help(argv[0]);
|
|
} else if (strcmp(argv[i], "-b") == 0) {
|
|
if (i + 1 == argc) print_help(argv[0]);
|
|
char* val = argv[++i];
|
|
memcpy(exe_name, val, strlen(val) + 1);
|
|
} else if (strcmp(argv[i], "--mice-d") == 0) {
|
|
debug_wait = true;
|
|
} else if (strncmp(argv[i], "--mice.", strlen("--mice.")) == 0) {
|
|
char key[256];
|
|
char value[256];
|
|
key[0] = value[0] = '\0';
|
|
|
|
char* arg = argv[i] + strlen("--mice.");
|
|
int j = 0;
|
|
for (; j < _countof(key) - 2; j++) {
|
|
if (arg[j] == '\0') break;
|
|
if (arg[j] == '=') {
|
|
strcpy_s(value, _countof(value), arg + j + 1);
|
|
break;
|
|
}
|
|
key[j] = arg[j];
|
|
}
|
|
key[j] = '\0';
|
|
bool handled = false;
|
|
|
|
for (j = 0; j < _countof(mxspawns); j++) {
|
|
if (strcmp(key, mxspawns[j].name) != 0) continue;
|
|
handled = true;
|
|
|
|
if (strcmp(value, "no") == 0)
|
|
mxspawns[j].mode = SPAWN_NONE;
|
|
else if (strcmp(value, "mx") == 0)
|
|
mxspawns[j].mode |= SPAWN_REAL;
|
|
else if (strcmp(value, "md") == 0)
|
|
mxspawns[j].mode |= SPAWN_DUMMY;
|
|
else {
|
|
log_error(plfBoot, "Unknown spawn mode: %s=%s", key, value);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!handled) {
|
|
log_error(plfBoot, "Unknown launcher config: %s=%s", key, value);
|
|
return false;
|
|
}
|
|
} else {
|
|
if (commandline[0] == 0)
|
|
snprintf(commandline, sizeof commandline, "%s", argv[i]);
|
|
else
|
|
snprintf(commandline, sizeof commandline, "%s %s", commandline, argv[i]);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
int main(int argc, char* argv[]) {
|
|
load_mice_config();
|
|
setup_logging();
|
|
|
|
log_info(plfBoot, "Micetools version: %s", MICE_VERSION);
|
|
|
|
CHAR workDir[MAX_PATH + 1];
|
|
GetCurrentDirectory(MAX_PATH, workDir);
|
|
log_info(plfBoot, "Current directory: %s", workDir);
|
|
|
|
if (!parse_cmdline(argc, argv)) return 0;
|
|
|
|
if (exe_name[0] == '\0' && MiceConfig.launcher.game_binary[0] != '\0') {
|
|
snprintf(exe_name, sizeof exe_name, "%s", MiceConfig.launcher.game_binary);
|
|
}
|
|
if (MiceConfig.launcher.wait_for_debugger) debug_wait = true;
|
|
boot_delay = MiceConfig.launcher.startup_delay;
|
|
|
|
if (exe_name[0] == '\0') {
|
|
if (!locate_game(exe_name, MAX_PATH + 1)) {
|
|
log_error(plfBoot, "Fatal: Failed to locate a game");
|
|
return 0;
|
|
}
|
|
} else {
|
|
DWORD dwAttrib = GetFileAttributes(exe_name);
|
|
if (dwAttrib == INVALID_FILE_ATTRIBUTES || dwAttrib & FILE_ATTRIBUTE_DIRECTORY) {
|
|
log_error(plfBoot, "Fatal: %s: no such file found", exe_name);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
spawn_pcp_processes();
|
|
|
|
log_info(plfBoot, "exec: %s %s", exe_name, commandline);
|
|
|
|
char micepath[MAX_PATH + 1];
|
|
if (!locate_library(micepath, MAX_PATH + 1)) {
|
|
log_error(plfBoot, "Fatal: Failed to locate micelib. Check your mice_dll setting!");
|
|
return 0;
|
|
}
|
|
|
|
char* extra_injections = MiceConfig.launcher.inject;
|
|
HANDLE game_proc =
|
|
start_and_inject(exe_name, commandline, micepath, debug_wait, boot_delay, extra_injections, 0);
|
|
if (!game_proc) return -1;
|
|
|
|
if (FAILED(WaitForSingleObject(game_proc, INFINITE))) {
|
|
log_error(plfBoot, "Fatal: WaitForSingleObject failed: %03x", GetLastError());
|
|
} else {
|
|
log_info(plfBoot, "Shutting down");
|
|
CloseHandle(game_proc);
|
|
}
|
|
return 0;
|
|
}
|