1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

load game data from shared dir

kambala-decapitator/vcmi#15
This commit is contained in:
Andrey Filipenkov 2021-03-18 17:02:02 +03:00
parent 5f97bf0be8
commit 2fc4d48215
4 changed files with 60 additions and 37 deletions

View File

@ -7,10 +7,25 @@
* Full text of license available in license.txt file, in main folder * Full text of license available in license.txt file, in main folder
* *
*/ */
#include <TargetConditionals.h>
#ifdef __OBJC__
@class NSURL;
#endif
extern const char *ios_documentsPath(); extern const char *ios_documentsPath();
extern const char *ios_cachesPath(); extern const char *ios_cachesPath();
#ifdef __OBJC__
NSURL *sharedContainerURL();
NSURL *sharedGameDataURL();
#endif
extern const char *ios_sharedDataPath();
#if TARGET_OS_SIMULATOR
extern const char *ios_hostApplicationSupportPath();
#endif
extern const char *ios_bundlePath(); extern const char *ios_bundlePath();
extern const char *ios_frameworksPath(); extern const char *ios_frameworksPath();

View File

@ -12,15 +12,46 @@
@import Foundation; @import Foundation;
static const char *standardPath(NSSearchPathDirectory directory) static NSString *standardPathNative(NSSearchPathDirectory directory)
{ {
return [NSFileManager.defaultManager URLForDirectory:directory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:NULL].path.UTF8String; return [NSFileManager.defaultManager URLForDirectory:directory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:NULL].path;
} }
static const char *standardPath(NSSearchPathDirectory directory) { return standardPathNative(directory).fileSystemRepresentation; }
const char *ios_documentsPath() { return standardPath(NSDocumentDirectory); } const char *ios_documentsPath() { return standardPath(NSDocumentDirectory); }
const char *ios_cachesPath() { return standardPath(NSCachesDirectory); } const char *ios_cachesPath() { return standardPath(NSCachesDirectory); }
const char *ios_bundlePath() { return NSBundle.mainBundle.bundlePath.UTF8String; } NSURL *sharedContainerURL()
const char *ios_frameworksPath() { return [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"Frameworks"].UTF8String; } // TODO: sharedFrameworksPath? {
static NSURL *sharedPathURL;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
__auto_type bundleID = NSBundle.mainBundle.bundleIdentifier;
__auto_type lastDotPos = [bundleID rangeOfString:@"." options:NSBackwardsSearch].location;
__auto_type groupID = [NSString stringWithFormat:@"group.%@.vcmi", [bundleID substringToIndex:lastDotPos]];
sharedPathURL = [NSFileManager.defaultManager containerURLForSecurityApplicationGroupIdentifier:groupID];
});
return sharedPathURL;
}
NSURL *sharedGameDataURL() { return [sharedContainerURL() URLByAppendingPathComponent:@"GameData"]; }
const char *ios_sharedDataPath() { return sharedGameDataURL().fileSystemRepresentation; }
#if TARGET_OS_SIMULATOR
const char *ios_hostApplicationSupportPath()
{
static NSString *applicationSupportPath;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
__auto_type cachesPath = standardPathNative(NSCachesDirectory);
__auto_type afterMacOsHomeDirPos = [cachesPath rangeOfString:@"Library/Developer"].location;
NSCAssert(afterMacOsHomeDirPos != NSNotFound, @"simulator directory location is not under user's home directory: %@", cachesPath);
applicationSupportPath = [[cachesPath substringToIndex:afterMacOsHomeDirPos] stringByAppendingPathComponent:@"Library/Application Support/vcmi"].stringByResolvingSymlinksInPath;
});
return applicationSupportPath.fileSystemRepresentation;
}
#endif
const char *ios_bundlePath() { return NSBundle.mainBundle.bundlePath.fileSystemRepresentation; }
const char *ios_frameworksPath() { return NSBundle.mainBundle.privateFrameworksPath.fileSystemRepresentation; }
const char *ios_bundleIdentifier() { return NSBundle.mainBundle.bundleIdentifier.UTF8String; } const char *ios_bundleIdentifier() { return NSBundle.mainBundle.bundleIdentifier.UTF8String; }

View File

@ -402,9 +402,9 @@ std::vector<bfs::path> VCMIDirsIOS::dataPaths() const
{ {
return { return {
#ifdef VCMI_IOS_SIM #ifdef VCMI_IOS_SIM
// fixme ios {ios_hostApplicationSupportPath()},
{"/Users/kambala/Library/Application Support/vcmi"},
#endif #endif
{ios_sharedDataPath()},
binaryPath(), binaryPath(),
userDataPath(), userDataPath(),
}; };

View File

@ -11,11 +11,11 @@
#include "../Global.h" #include "../Global.h"
#include "CVCMIServer.h" #include "CVCMIServer.h"
extern "C" {
#define SHARED_DATA_DIR @"GameData" #import "../lib/CIOSUtils.h"
}
@interface ViewController : UIViewController @interface ViewController : UIViewController
@property (nonatomic, copy) NSURL *sharedPathURL;
@property (nonatomic, copy) NSArray<NSURL *> *dataDirsInDocuments; @property (nonatomic, copy) NSArray<NSURL *> *dataDirsInDocuments;
@end @end
@ -35,29 +35,13 @@
[startServerButton.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor], [startServerButton.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor],
]]; ]];
auto bundleID = NSBundle.mainBundle.bundleIdentifier;
auto lastDotPos = [bundleID rangeOfString:@"." options:NSBackwardsSearch].location;
auto groupID = [NSString stringWithFormat:@"group.%@.vcmi", [bundleID substringToIndex:lastDotPos]];
auto fm = NSFileManager.defaultManager; auto fm = NSFileManager.defaultManager;
self.sharedPathURL = [fm containerURLForSecurityApplicationGroupIdentifier:groupID]; auto sharedGameDataUrl = sharedGameDataURL();
if (!self.sharedPathURL) if (!sharedGameDataUrl || [fm fileExistsAtPath:sharedGameDataUrl.path])
{
NSLog(@"shared path for group '%@' not available", groupID);
return; return;
}
auto dirEnumerator = [fm enumeratorAtURL:self.sharedPathURL includingPropertiesForKeys:@[NSURLNameKey] options:NSDirectoryEnumerationSkipsSubdirectoryDescendants errorHandler:nil];
for (NSURL *fileURL in dirEnumerator)
{
NSString *filename;
if ([fileURL getResourceValue:&filename forKey:NSURLNameKey error:nullptr] && [filename caseInsensitiveCompare:SHARED_DATA_DIR] == NSOrderedSame) {
NSLog(SHARED_DATA_DIR @" dir already exists in the shared path");
return;
}
}
auto documentsURL = [fm URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nullptr]; auto documentsURL = [fm URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nullptr];
dirEnumerator = [fm enumeratorAtURL:documentsURL includingPropertiesForKeys:@[NSURLNameKey] options:NSDirectoryEnumerationSkipsSubdirectoryDescendants errorHandler:nil]; auto dirEnumerator = [fm enumeratorAtURL:documentsURL includingPropertiesForKeys:@[NSURLNameKey] options:NSDirectoryEnumerationSkipsSubdirectoryDescendants errorHandler:nil];
auto dataDirs = [NSMutableArray<NSURL *> arrayWithCapacity:3]; auto dataDirs = [NSMutableArray<NSURL *> arrayWithCapacity:3];
for (NSURL *fileURL in dirEnumerator) for (NSURL *fileURL in dirEnumerator)
{ {
@ -68,10 +52,7 @@
[dataDirs addObject:fileURL]; [dataDirs addObject:fileURL];
} }
if (dataDirs.count < 3) if (dataDirs.count < 3)
{
NSLog(@"not all required dirs are present, found only: %@", dataDirs);
return; return;
}
self.dataDirsInDocuments = dataDirs; self.dataDirsInDocuments = dataDirs;
auto moveDataButton = [UIButton buttonWithType:UIButtonTypeSystem]; auto moveDataButton = [UIButton buttonWithType:UIButtonTypeSystem];
@ -100,17 +81,13 @@
- (void)moveDataToSharedDir:(UIButton *)button - (void)moveDataToSharedDir:(UIButton *)button
{ {
button.enabled = NO; [button removeFromSuperview];
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{ dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
auto fm = NSFileManager.defaultManager; auto fm = NSFileManager.defaultManager;
auto destinationURL = [self.sharedPathURL URLByAppendingPathComponent:SHARED_DATA_DIR]; auto destinationURL = sharedGameDataURL();
[fm createDirectoryAtURL:destinationURL withIntermediateDirectories:YES attributes:nil error:nullptr]; [fm createDirectoryAtURL:destinationURL withIntermediateDirectories:YES attributes:nil error:nullptr];
for (NSURL *dirURL in self.dataDirsInDocuments) for (NSURL *dirURL in self.dataDirsInDocuments)
[fm moveItemAtURL:dirURL toURL:[destinationURL URLByAppendingPathComponent:dirURL.lastPathComponent] error:nullptr]; [fm moveItemAtURL:dirURL toURL:[destinationURL URLByAppendingPathComponent:dirURL.lastPathComponent] error:nullptr];
dispatch_sync(dispatch_get_main_queue(), ^{
[button removeFromSuperview];
});
}); });
} }