Skip to content

Commit 70a8905

Browse files
few changes, launch game option in installer
1 parent 54ab949 commit 70a8905

8 files changed

Lines changed: 158 additions & 14 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
*.dSYM
33
assets
44
release
5+
staging
56
launcherv2
67
natives
78
AppBundleExe

installer/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ LDFLAGS =
1717

1818
FRAMEWORKS = -framework CoreFoundation -framework Foundation
1919

20-
SOURCES = installer.c utilities.c
20+
SOURCES = installer.c utilities.c native.m
2121

2222
all: $(TARGET)
2323

installer/installer.c

Lines changed: 98 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,16 @@ typedef enum _nextaction_t {
2323
A_StartVerify,
2424
A_StartUninstall,
2525
A_ClearNavmesh,
26+
A_LaunchGame,
2627
} nextaction_t;
2728

29+
int launch_game_native(const char *path);
30+
2831
void StartTerminalWindow() {
2932
printf(TmTitle "BO3MacFix Installer" TmEnd);
3033
printf(TmClear TmStartPos);
3134

32-
printf(TmBold TmUnderline "BO3MacFix Installer v1.0\n\n" TmReset);
35+
printf(TmBold TmUnderline "BO3MacFix Installer v1.2\n\n" TmReset);
3336
}
3437

3538
nextaction_t Error_NotInRightDirectory() {
@@ -50,13 +53,16 @@ nextaction_t MainMenuUninstalled() {
5053
StartTerminalWindow();
5154

5255
printf("1) Install BO3MacFix\n\n");
56+
printf("9) Launch game with fix\n\n");
5357
printf("0) Exit\n\n");
5458

5559
printf("Select an option: ");
5660

5761
char c = (char)getchar();
5862
if (c == '1')
5963
return A_StartInstall;
64+
if (c == '9')
65+
return A_LaunchGame;
6066
if (c == '0')
6167
return A_Exit;
6268
return A_ShowMainMenuUninstalled;
@@ -66,19 +72,20 @@ nextaction_t MainMenuInstalled() {
6672
StartTerminalWindow();
6773

6874
//printf("1) Verify BO3MacFix Install\n");
69-
printf("1) Uninstall BO3MacFix\n\n");
70-
//printf("3) Clear Workshop Navmeshes\n\n");
75+
printf("1) Update/reinstall BO3MacFix\n");
76+
printf("2) Uninstall BO3MacFix\n\n");
77+
printf("9) Launch game with fix\n\n");
7178
printf("0) Exit\n\n");
7279

7380
printf("Select an option: ");
7481

7582
char c = (char)getchar();
76-
//if (c == '1')
77-
// return A_StartVerify;
7883
if (c == '1')
84+
return A_StartVerify;
85+
if (c == '2')
7986
return A_StartUninstall;
80-
//if (c == '3')
81-
// return A_ClearNavmesh;
87+
if (c == '9')
88+
return A_LaunchGame;
8289
if (c == '0')
8390
return A_Exit;
8491
return A_ShowMainMenuInstalled;
@@ -170,6 +177,86 @@ nextaction_t StartInstall() {
170177
return A_ShowMainMenuInstalled;
171178
}
172179

180+
nextaction_t StartVerify() {
181+
char sourcePath[PATH_MAX] = {0};
182+
char targetPath[PATH_MAX] = {0};
183+
184+
StartTerminalWindow();
185+
186+
printf("Reinstalling BO3MacFix...\n\n");
187+
188+
printf("Copying new launcher...");
189+
memset(sourcePath, 0, PATH_MAX);
190+
strncat(sourcePath, baseDirPath, PATH_MAX);
191+
strncat(sourcePath, "AppBundleExe", PATH_MAX);
192+
memset(targetPath, 0, PATH_MAX);
193+
strncat(targetPath, baseDirPath, PATH_MAX);
194+
strncat(targetPath, "../CoDBlkOps3.app/Contents/MacOS/AppBundleExe", PATH_MAX);
195+
int r = copyfile(sourcePath, targetPath, 0, COPYFILE_ALL);
196+
if (r != 0) {
197+
printf("failed (%i, %i).\n\n", r, errno);
198+
printf("Press ENTER to continue.\n");
199+
printf("You might have to repair game files in Steam...\n");
200+
getchar();
201+
return A_ShowMainMenuUninstalled;
202+
}
203+
printf("done!\n");
204+
205+
printf("Fixing permissions on launcher...");
206+
memset(sourcePath, 0, PATH_MAX);
207+
strncat(sourcePath, baseDirPath, PATH_MAX);
208+
strncat(sourcePath, "../CoDBlkOps3.app/Contents/MacOS/AppBundleExe", PATH_MAX);
209+
if (chmod(sourcePath, 0755) != 0) { // rwxr-xr-x
210+
printf("failed (chmod: %i).\n\n", errno);
211+
printf("Press ENTER to continue.\n");
212+
printf("You might have to repair game files in Steam...\n");
213+
getchar();
214+
return A_ShowMainMenuUninstalled;
215+
}
216+
if (removexattr(sourcePath, "com.apple.quarantine", 0) != 0 && errno != ENOATTR) {
217+
printf("failed (xattr: %i).\n\n", errno);
218+
printf("Press ENTER to continue.\n");
219+
printf("You might have to repair game files in Steam...\n");
220+
getchar();
221+
return A_ShowMainMenuUninstalled;
222+
}
223+
printf("done!\n");
224+
225+
printf("Fixing permissions on BO3MacFix...");
226+
memset(sourcePath, 0, PATH_MAX);
227+
strncat(sourcePath, baseDirPath, PATH_MAX);
228+
strncat(sourcePath, "BO3MacFix.dylib", PATH_MAX);
229+
if (chmod(sourcePath, 0644) != 0) { // rwxr-xr-x
230+
printf("failed (chmod: %i).\n\n", errno);
231+
printf("Press ENTER to continue.\n");
232+
getchar();
233+
return A_ShowMainMenuUninstalled;
234+
}
235+
if (removexattr(sourcePath, "com.apple.quarantine", 0) != 0 && errno != ENOATTR) {
236+
printf("failed (xattr: %i).\n\n", errno);
237+
printf("Press ENTER to continue.\n");
238+
getchar();
239+
return A_ShowMainMenuUninstalled;
240+
}
241+
printf("done!\n");
242+
243+
printf("Installation complete!\n\n");
244+
245+
printf("Press ENTER to continue.\n");
246+
getchar();
247+
return A_ShowMainMenuInstalled;
248+
}
249+
250+
nextaction_t LaunchGame() {
251+
StartTerminalWindow();
252+
253+
printf("Launching game with fix...\n\n");
254+
255+
launch_game_native(baseDirPath);
256+
257+
return A_Exit;
258+
}
259+
173260
nextaction_t StartUninstall() {
174261
char sourcePath[PATH_MAX] = {0};
175262
char targetPath[PATH_MAX] = {0};
@@ -262,8 +349,7 @@ int main(int argc, char **argv) {
262349
act = StartInstall();
263350
break;
264351
case A_StartVerify:
265-
printf("A_StartVerify\n");
266-
act = A_Exit;
352+
act = StartVerify();
267353
break;
268354
case A_StartUninstall:
269355
act = StartUninstall();
@@ -272,6 +358,9 @@ int main(int argc, char **argv) {
272358
printf("A_ClearNavmesh\n");
273359
act = A_Exit;
274360
break;
361+
case A_LaunchGame:
362+
act = LaunchGame();
363+
break;
275364
default:
276365
act = A_Exit;
277366
break;

installer/native.m

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include <string.h>
2+
#include <strings.h>
3+
#include <stdio.h>
4+
#include <Foundation/Foundation.h>
5+
6+
int launch_game_native(const char *path) {
7+
NSTask *gameProc = [[NSTask alloc] init];
8+
// copy our current working directory and pass it onto the child process
9+
NSProcessInfo *currentProcess = [NSProcessInfo processInfo];
10+
NSString *pwd = [NSString stringWithUTF8String:path];
11+
NSLog(@"%@\n", pwd);
12+
NSURL *fixDirectoryUrl = [NSURL fileURLWithPath:pwd];
13+
NSLog(@"%@\n", fixDirectoryUrl);
14+
NSURL *gameDirectoryUrl = [fixDirectoryUrl URLByAppendingPathComponent:@"../CoDBlkOps3.app/Contents/MacOS/"];
15+
NSLog(@"%@\n", gameDirectoryUrl);
16+
gameProc.currentDirectoryURL = gameDirectoryUrl;
17+
// set the game executable path
18+
gameProc.executableURL = [gameProc.currentDirectoryURL URLByAppendingPathComponent:@"CoDBlkOps3_Exe"];
19+
20+
// add the fix dylib to DYLD_INSERT_LIBRARIES of the new process
21+
NSURL *dylibUrl = [gameProc.currentDirectoryURL URLByAppendingPathComponent:@"../../../BO3MacFix/BO3MacFix.dylib"];
22+
NSMutableDictionary *newEnvironment = [[currentProcess environment] mutableCopy];
23+
// if we already have dyld_insert_libraries set (by Steam), append our dylib to that
24+
if ([[currentProcess environment] objectForKey:@"DYLD_INSERT_LIBRARIES"]) {
25+
newEnvironment[@"DYLD_INSERT_LIBRARIES"] = [NSString stringWithFormat:@"%@:%@",[dylibUrl path],[currentProcess environment][@"DYLD_INSERT_LIBRARIES"]];
26+
} else { // otherwise just set it by itself
27+
newEnvironment[@"DYLD_INSERT_LIBRARIES"] = [dylibUrl path];
28+
}
29+
newEnvironment[@"WINEPREFIX"] = [[gameProc.currentDirectoryURL URLByAppendingPathComponent:@"../../../BO3MacFix/pfx"] path];
30+
newEnvironment[@"SteamAppId"] = @"311210";
31+
gameProc.environment = newEnvironment;
32+
33+
NSLog(@"Launching game...\n");
34+
NSLog(@" Executable: %@\n", gameProc.executableURL);
35+
NSLog(@" Working Directory: %@\n", gameProc.currentDirectoryURL);
36+
NSLog(@" DYLD_INSERT_LIBRARIES: %@\n", newEnvironment[@"DYLD_INSERT_LIBRARIES"]);
37+
NSLog(@" WINEPREFIX: %@\n", newEnvironment[@"WINEPREFIX"]);
38+
39+
// launch the game executable
40+
[gameProc launch];
41+
[gameProc waitUntilExit];
42+
return 0;
43+
}

scripts/package.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ cp BO3MacFix.dylib staging/BO3MacFix/BO3MacFix.dylib
1212
cp installer/Install_BO3MacFix staging/BO3MacFix/Install_BO3MacFix
1313
cp launcher/AppBundleExe staging/BO3MacFix/AppBundleExe
1414

15-
# copy the binary assets (c2m)
15+
# copy the binary assets (c2m, zone)
1616
echo Copying assets...
1717
cp -r assets/* staging/BO3MacFix
1818

source/bo3macfix.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#ifdef MACFIX_DEBUG
2828
#define Version_Prefix "[BO3MacFix DEBUG]"
2929
#else
30-
#define Version_Prefix "[BO3MacFix v1.1-beta]"
30+
#define Version_Prefix "[BO3MacFix " MACFIX_VERSION "]"
3131
#endif
3232
#define Error_Prefix "^7[^6BO3MacFix^7] "
3333

@@ -341,6 +341,11 @@ static void network_version_patch() {
341341
// set the LPC category version to match PC
342342
uint32_t newcategory = 0x0528;
343343
DobbyCodePatch((void *)(game_base_address + ADDR_LPC_GetRemoteManifest_Category_Inst + 6), (uint8_t *)&newcategory, sizeof(uint32_t));
344+
// set the CL version to match PC
345+
uint8_t mov_eax = 0xB8;
346+
int new_cl_version = 0xD3FC12;
347+
DobbyCodePatch((void *)(game_base_address + ADDR_LobbyHostMsg_SendJoinRequest_GetChangelistCall), &mov_eax, sizeof(uint8_t));
348+
DobbyCodePatch((void *)(game_base_address + ADDR_LobbyHostMsg_SendJoinRequest_GetChangelistCall + 1), (uint8_t *)&new_cl_version, sizeof(int));
344349
}
345350

346351
void set_network_password(const char *password)
@@ -469,6 +474,7 @@ install_hook_name(hks_load_dll, bool, void *s, const char *filename, const char
469474

470475
// so we can bundle support for workshop mods retroactively where the creator might not be able to / is unwilling to add a dylib
471476
// we check /BO3MacFix/natives/[dll name]-[dll hash].dylib
477+
// NOTE(Emma): might want to change to [dll name]-[workshop id].dylib for workshop mods to avoid updates breaking it if changes are insignificant enough
472478
char test_native_path[1024];
473479
uint8_t file_sha1_hash[0x14];
474480
char file_sha1_hash_str[(0x14 * 2) + 1];

source/offsets.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,5 @@
3737
#define ADDR_Lua_CoD_LuaCall_GetProtocolVersion_Inst 0xE1FCA8 // mid-func
3838
#define ADDR_LPC_GetRemoteManifest_Category_Inst 0xEA8C04 // mid-func
3939
#define ADDR_Live_SystemInfo_LarpInstr 0x129dbcc // mid-func
40+
#define ADDR_LobbyHostMsg_SendJoinRequest_GetChangelistCall 0x1232458 // mid-func
4041
// -- END OFFSETS

source/utilities.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,12 @@ bool is_macos_dylib(const char *path) {
132132
uint8_t file_magic[4] = {0};
133133
if (fread(file_magic, 1, 4, fp) == 4) {
134134
// 0xFEEDFACF - 64-bit Mach-O
135-
static const uint8_t macho_header[4] = {0xcf, 0xfa, 0xed, 0xfe};
136-
if (memcmp(file_magic, macho_header, 4) == 0)
135+
static const uint8_t macho_header_64bit[4] = {0xcf, 0xfa, 0xed, 0xfe};
136+
if (memcmp(file_magic, macho_header_64bit, 4) == 0)
137+
return true;
138+
// 0xCAFEBABE - fat Mach-O
139+
static const uint8_t macho_header_fat[4] = {0xca, 0xfe, 0xba, 0xbe};
140+
if (memcmp(file_magic, macho_header_fat, 4) == 0)
137141
return true;
138142
}
139143
fclose(fp);

0 commit comments

Comments
 (0)