This commit is contained in:
LimeGradient 2025-04-02 22:01:35 -04:00 committed by GitHub
commit e7d57f4cd9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 75 additions and 3 deletions

View file

@ -68,6 +68,7 @@ elseif (GEODE_TARGET_PLATFORM STREQUAL "MacOS")
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15)
target_link_libraries(${PROJECT_NAME} INTERFACE
"-framework AVFoundation"
"-framework Cocoa"
"-framework OpenGL"
"-framework SystemConfiguration"

View file

@ -216,5 +216,9 @@ int geodeEntry(void* platformData) {
// also log after entry so that users are more likely to notice
tryLogForwardCompat();
#ifdef GEODE_IS_MACOS
checkPermissionPlist();
#endif
return 0;
}

View file

@ -1,3 +1,10 @@
#pragma once
#include <Geode/platform/cplatform.h>
bool safeModeCheck();
int geodeEntry(void* platformData);
int geodeEntry(void* platformData);
#ifdef GEODE_IS_MACOS
void checkPermissionPlist();
#endif

View file

@ -23,4 +23,18 @@ bool safeModeCheck() {
return false;
}
void checkPermissionPlist() {
std::thread([] {
// Load the plist and check for microphone key
std::string plistPath = (dirs::getGameDir() / "Info.plist").string();
NSString* nsPlistPath = [NSString stringWithUTF8String:plistPath.c_str()];
NSMutableDictionary* plist = [NSMutableDictionary dictionaryWithContentsOfFile:nsPlistPath];
if (![plist objectForKey:@"NSMicrophoneUsageDescription"]) {
// If the microphone key doesn't exist, create it
[plist setObject:@"A mod you installed is requesting microphone access" forKey:@"NSMicrophoneUsageDescription"];
[plist writeToFile:nsPlistPath atomically:YES];
}
}).detach();
}
#endif

View file

@ -5,6 +5,7 @@ using namespace geode::prelude;
#include <Geode/loader/Dirs.hpp>
#import <AppKit/AppKit.h>
#import <AVFoundation/AVFoundation.h>
#include <Geode/Utils.hpp>
#include <Geode/binding/GameManager.hpp>
#include <objc/runtime.h>
@ -336,11 +337,56 @@ Result<void*> geode::hook::replaceObjcMethod(std::string const& className, std::
}
bool geode::utils::permission::getPermissionStatus(Permission permission) {
return true; // unimplemented
switch (permission) {
case Permission::RecordAudio: {
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
switch (status) {
case AVAuthorizationStatusRestricted: return false;
case AVAuthorizationStatusNotDetermined: return false;
case AVAuthorizationStatusDenied: return false;
case AVAuthorizationStatusAuthorized: return true;
}
} break;
}
return false;
}
static std::function<void(bool)> g_permissionCallback;
void geode::utils::permission::requestPermission(Permission permission, std::function<void(bool)> callback) {
callback(true); // unimplemented
g_permissionCallback = std::move(callback);
switch (permission) {
case Permission::RecordAudio: {
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
switch (status) {
case AVAuthorizationStatusNotDetermined: {
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
g_permissionCallback(granted);
g_permissionCallback = {};
}];
} break;
case AVAuthorizationStatusRestricted: {
g_permissionCallback(false);
g_permissionCallback = {};
} break;
case AVAuthorizationStatusDenied: {
g_permissionCallback(false);
g_permissionCallback = {};
} break;
case AVAuthorizationStatusAuthorized: {
g_permissionCallback(true);
g_permissionCallback = {};
} break;
}
} break;
default: {
g_permissionCallback(false);
g_permissionCallback = {};
} break;
};
}
#include "../../utils/thread.hpp"