34#import "MyOpenGLView.h"
63@interface ResourceManager (OOPrivate)
65+ (void) checkOXPMessagesInPath:(NSString *)path;
66+ (void) checkPotentialPath:(NSString *)path :(NSMutableArray *)searchPaths;
67+ (BOOL) validateManifest:(NSDictionary*)manifest forOXP:(NSString *)path;
68+ (BOOL) areRequirementsFulfilled:(NSDictionary*)requirements forOXP:(NSString *)path andFile:(NSString *)file;
69+ (void) filterSearchPathsForConflicts:(NSMutableArray *)searchPaths;
70+ (BOOL) filterSearchPathsForRequirements:(NSMutableArray *)searchPaths;
71+ (void) filterSearchPathsToExcludeScenarioOnlyPaths:(NSMutableArray *)searchPaths;
72+ (void) filterSearchPathsByScenario:(NSMutableArray *)searchPaths;
73+ (BOOL) manifestAllowedByScenario:(NSDictionary *)manifest;
74+ (BOOL) manifestAllowedByScenario:(NSDictionary *)manifest withIdentifier:(NSString *)identifier;
75+ (BOOL) manifestAllowedByScenario:(NSDictionary *)manifest withTag:(NSString *)tag;
77+ (void) addErrorWithKey:(NSString *)descriptionKey param1:(
id)param1 param2:(
id)param2;
78+ (BOOL) checkCacheUpToDateForPaths:(NSArray *)searchPaths;
80+ (void) mergeRoleCategories:(NSDictionary *)catData intoDictionary:(NSMutableDictionary *)category;
82+ (void) preloadFileListFromOXZ:(NSString *)path forFolders:(NSArray *)folders;
83+ (void) preloadFileListFromFolder:(NSString *)path forFolders:(NSArray *)folders;
84+ (void) preloadFilePathFor:(NSString *)fileName inFolder:(NSString *)subFolder atPath:(NSString *)path;
123+ (void) resetManifestKnowledgeForOXZManager
135 NSArray *error =
nil;
137 NSMutableArray *result =
nil;
138 NSString *errStr =
nil;
140 count = [sErrors count];
144 result = [NSMutableArray arrayWithCapacity:count];
145 for (i = 0; i !=
count; ++i)
147 error = [sErrors objectAtIndex:i];
148 errStr = [UNIVERSE descriptionForKey:[error oo_stringAtIndex:0]];
151 errStr = [NSString stringWithFormat:errStr, [error objectAtIndex:1], [error objectAtIndex:2]];
152 [result addObject:errStr];
159 return [result componentsJoinedByString:@"\n"];
163+ (NSArray *)rootPaths
165 static NSArray *sRootPaths =
nil;
166 if (sRootPaths ==
nil) {
170 sRootPaths = [[sRootPaths arrayByAddingObjectsFromArray:[
self userRootPaths]] retain];
176+ (NSArray *)userRootPaths
178 static NSArray *sUserRootPaths =
nil;
180 if (sUserRootPaths ==
nil)
183 NSArray *defaultAddOnsPaths = [NSArray arrayWithObjects:
185 [[[[NSHomeDirectory() stringByAppendingPathComponent:@"Library"]
186 stringByAppendingPathComponent:@"Application Support"]
187 stringByAppendingPathComponent:@"Oolite"]
188 stringByAppendingPathComponent:@"AddOns"],
189 [[[[NSBundle mainBundle] bundlePath]
190 stringByDeletingLastPathComponent]
191 stringByAppendingPathComponent:@"AddOns"],
198 OOLog(
@"searchPaths.debug",
@"%@",sUserRootPaths);
199 return sUserRootPaths;
203+ (NSString *)builtInPath
211 return [[NSBundle mainBundle] resourcePath];
216+ (NSArray *)pathsWithAddOns
222 sUseAddOns = [[NSString alloc] initWithString:SCENARIO_OXP_DEFINITION_ALL];
223 sUseAddOnsParts = [[sUseAddOns componentsSeparatedByString:@";"] retain];
230 return (NSArray *)[NSArray arrayWithObject:[
self builtInPath]];
236 NSFileManager *fmgr = [NSFileManager defaultManager];
237 NSArray *rootPaths =
nil;
238 NSMutableArray *existingRootPaths =
nil;
239 NSString *root =
nil;
240 NSDirectoryEnumerator *dirEnum =
nil;
241 NSString *subPath =
nil;
242 NSString *path =
nil;
246 rootPaths = [
self rootPaths];
247 existingRootPaths = [NSMutableArray arrayWithCapacity:[rootPaths count]];
248 foreach (root, rootPaths)
250 if ([fmgr fileExistsAtPath:root isDirectory:&isDirectory] && isDirectory)
252 [existingRootPaths addObject:root];
259 foreach (path, existingRootPaths)
261 [
self checkPotentialPath:path :sSearchPaths];
265 foreach (root, existingRootPaths)
268 if ([fmgr fileExistsAtPath:root isDirectory:&isDirectory] && isDirectory)
270 for (dirEnum = [fmgr enumeratorAtPath:root]; (subPath = [dirEnum nextObject]); )
273 path = [root stringByAppendingPathComponent:subPath];
274 if ([fmgr fileExistsAtPath:path isDirectory:&isDirectory])
279 if ([[[path pathExtension] lowercaseString] isEqualToString:
@"oxp"])
281 [
self checkPotentialPath:path :sSearchPaths];
287 [dirEnum skipDescendents];
293 if ([[[path pathExtension] lowercaseString] isEqualToString:
@"oxz"])
295 [
self checkPotentialPath:path :sSearchPaths];
306 [
self checkPotentialPath:path :sSearchPaths];
315 [
self filterSearchPathsToExcludeScenarioOnlyPaths:sSearchPaths];
324 [
self filterSearchPathsForConflicts:sSearchPaths];
336 while (![
self filterSearchPathsForRequirements:
sSearchPaths]) {}
343 [
self filterSearchPathsByScenario:sSearchPaths];
346 [
self checkCacheUpToDateForPaths:sSearchPaths];
354 NSString *path =
nil;
355 NSEnumerator *pathEnum =
nil;
358 NSArray *folders = [NSArray arrayWithObjects:@"AIs",@"Images",@"Models",@"Music",@"Scenarios",@"Scripts",@"Shaders",@"Sounds",@"Textures",nil];
360 for (pathEnum = [[
ResourceManager paths] reverseObjectEnumerator]; (path = [pathEnum nextObject]); )
362 if ([path hasSuffix:
@".oxz"])
364 [
self preloadFileListFromOXZ:path forFolders:folders];
368 [
self preloadFileListFromFolder:path forFolders:folders];
374+ (void) preloadFileListFromOXZ:(NSString *)path forFolders:(NSArray *)folders
377 const char* zipname = [path UTF8String];
378 char componentName[512];
386 OOLog(
@"resourceManager.error",
@"Could not open .oxz at %@ as zip file",path);
397 NSString *zipEntry = [NSString stringWithUTF8String:componentName];
398 NSArray *pathBits = [zipEntry pathComponents];
399 if ([pathBits
count] >= 2)
401 NSString *folder = [pathBits oo_stringAtIndex:0];
402 if ([folders containsObject:folder])
405 bitRange.location = 1;
406 bitRange.length = [pathBits count]-1;
407 NSString *file = [NSString pathWithComponents:[pathBits subarrayWithRange:bitRange]];
408 NSString *fullPath = [[path stringByAppendingPathComponent:folder] stringByAppendingPathComponent:file];
410 [
self preloadFilePathFor:file inFolder:folder atPath:fullPath];
421+ (void) preloadFileListFromFolder:(NSString *)path forFolders:(NSArray *)folders
423 NSFileManager *fmgr = [NSFileManager defaultManager];
424 NSString *subFolder =
nil;
425 NSString *subFolderPath =
nil;
426 NSArray *fileList =
nil;
427 NSString *fileName =
nil;
430 foreach (subFolder, folders)
432 subFolderPath = [path stringByAppendingPathComponent:subFolder];
433 fileList = [fmgr oo_directoryContentsAtPath:subFolderPath];
434 foreach (fileName, fileList)
436 [
self preloadFilePathFor:fileName inFolder:subFolder atPath:[subFolderPath stringByAppendingPathComponent:fileName]];
442+ (void) preloadFilePathFor:(NSString *)fileName inFolder:(NSString *)subFolder atPath:(NSString *)path
445 NSString *cacheKey = [NSString stringWithFormat:@"%@/%@", subFolder, fileName];
450 OOLog(
@"resourceManager.foundFile.preLoad",
@"Found %@/%@ at %@", subFolder, fileName, path);
462 return [
self pathsWithAddOns];
466+ (NSArray *)maskUserNameInPathArray:(NSArray *)inputPathArray
468 NSString *path =
nil;
469 NSMutableArray *maskedArray = [NSMutableArray arrayWithCapacity:[inputPathArray count]];
470 const char *userNamePathEnvVar =
472 SDL_getenv(
"USERPROFILE");
476 NSString *userName = [[NSString stringWithFormat:@"%s", userNamePathEnvVar] lastPathComponent];
477 foreach (path, inputPathArray)
479 path = [
self maskUserName:userName inPath:path];
480 [maskedArray addObject:path];
486+ (NSString *)maskUserName:(NSString *)name inPath:(NSString *)path
488 NSMutableString *result = [NSMutableString stringWithString:path];
489 if (result && name) [result replaceOccurrencesOfString:name withString:@"*"
490 options:NSLiteralSearch
491 range:NSMakeRange(0, [result length])
493 return [NSString stringWithString:result];
497+ (NSString *)useAddOns
503+ (void)setUseAddOns:(NSString *)useAddOns
512 sUseAddOnsParts = [[sUseAddOns componentsSeparatedByString:@";"] retain];
533 [
self checkCacheUpToDateForPaths:[
self paths]];
537 [
self preloadFileLists];
543+ (void) addExternalPath:(NSString *)path
548 [sSearchPaths addObject:path];
551 [sExternalPaths addObject:path];
556+ (NSEnumerator *)pathEnumerator
558 return [[
self paths] objectEnumerator];
562+ (NSEnumerator *)reversePathEnumerator
564 return [[
self paths] reverseObjectEnumerator];
568+ (NSArray *)OXPsWithMessagesFound
570 return [[sOXPsWithMessagesFound copy] autorelease];
574+ (NSDictionary *)manifestForIdentifier:(NSString *)identifier
576 return [sOXPManifests objectForKey:identifier];
580+ (void) checkOXPMessagesInPath:(NSString *)path
582 NSArray *OXPMessageArray =
OOArrayFromFile([path stringByAppendingPathComponent:
@"OXPMessages.plist"]);
584 if ([OXPMessageArray
count] > 0)
587 for (i = 0; i < [OXPMessageArray count]; i++)
589 NSString *oxpMessage = [OXPMessageArray oo_stringAtIndex:i];
592 OOLog(
@"oxp.message",
@"%@: %@", path, oxpMessage);
596 [sOXPsWithMessagesFound addObject:[path lastPathComponent]];
602+ (void)checkPotentialPath:(NSString *)path :(NSMutableArray *)searchPaths
604 NSDictionary *requirements =
nil;
605 NSDictionary *manifest =
nil;
606 BOOL requirementsMet = YES;
608 if (![[[path pathExtension] lowercaseString] isEqualToString:
@"oxz"])
612 requirementsMet = [
self areRequirementsFulfilled:requirements forOXP:path andFile:@"requires.plist"];
614 if (!requirementsMet)
616 NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
617 OOLog(
@"oxp.versionMismatch",
@"OXP %@ is incompatible with version %@ of Oolite.", path, version);
618 [
self addErrorWithKey:@"oxp-is-incompatible" param1:[path lastPathComponent] param2:version];
625 if ([[[path pathExtension] lowercaseString] isEqualToString:
@"oxz"])
627 OOLog(
@"oxp.noManifest",
@"OXZ %@ has no manifest.plist", path);
628 [
self addErrorWithKey:@"oxz-lacks-manifest" param1:[path lastPathComponent] param2:nil];
633 if ([[[path pathExtension] lowercaseString] isEqualToString:
@"oxp"])
635 OOStandardsError([NSString stringWithFormat:
@"OXP %@ has no manifest.plist", path]);
638 [
self addErrorWithKey:@"oxp-lacks-manifest" param1:[path lastPathComponent] param2:nil];
643 manifest = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"__oolite.tmp.%@",path],kOOManifestIdentifier,@"1",kOOManifestVersion,@"OXP without manifest",kOOManifestTitle,@"1",kOOManifestRequiredOoliteVersion,nil];
647 requirementsMet = [
self validateManifest:manifest forOXP:path];
652 [searchPaths addObject:path];
657+ (BOOL) validateManifest:(NSDictionary*)manifest forOXP:(NSString *)path
661 sOXPManifests = [[NSMutableDictionary alloc] initWithCapacity:32];
665 NSString *identifier = [manifest oo_stringForKey:kOOManifestIdentifier defaultValue:nil];
666 NSString *version = [manifest oo_stringForKey:kOOManifestVersion defaultValue:nil];
667 NSString *required = [manifest oo_stringForKey:kOOManifestRequiredOoliteVersion defaultValue:nil];
668 NSString *title = [manifest oo_stringForKey:kOOManifestTitle defaultValue:nil];
670 if (identifier ==
nil)
673 [
self addErrorWithKey:@"oxp-manifest-incomplete" param1:title param2:kOOManifestIdentifier];
679 [
self addErrorWithKey:@"oxp-manifest-incomplete" param1:title param2:kOOManifestVersion];
685 [
self addErrorWithKey:@"oxp-manifest-incomplete" param1:title param2:kOOManifestRequiredOoliteVersion];
691 [
self addErrorWithKey:@"oxp-manifest-incomplete" param1:title param2:kOOManifestTitle];
698 OK = [
self checkVersionCompatibility:manifest forOXP:title];
702 NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
703 OOLog(
@"oxp.versionMismatch",
@"OXP %@ is incompatible with version %@ of Oolite.", path, version);
704 [
self addErrorWithKey:@"oxp-is-incompatible" param1:[path lastPathComponent] param2:version];
708 NSDictionary *duplicate = [sOXPManifests objectForKey:identifier];
709 if (duplicate !=
nil)
711 OOLog(
@"oxp.duplicate",
@"OXP %@ has the same identifier (%@) as %@ which has already been loaded.",path,identifier,[duplicate oo_stringForKey:
kOOManifestFilePath]);
712 [
self addErrorWithKey:@"oxp-manifest-duplicate" param1:path param2:[duplicate oo_stringForKey:kOOManifestFilePath]];
715 NSMutableDictionary *mData = [NSMutableDictionary dictionaryWithDictionary:manifest];
716 [mData setObject:path forKey:kOOManifestFilePath];
718 [sOXPManifests setObject:mData forKey:identifier];
723+ (BOOL) checkVersionCompatibility:(NSDictionary *)manifest forOXP:(NSString *)title
725 NSString *required = [manifest oo_stringForKey:kOOManifestRequiredOoliteVersion defaultValue:nil];
726 NSString *maxRequired = [manifest oo_stringForKey:kOOManifestMaximumOoliteVersion defaultValue:nil];
728 if (maxRequired ==
nil || [maxRequired length] == 0)
730 return [
self areRequirementsFulfilled:[NSDictionary dictionaryWithObjectsAndKeys:required, @"version", nil] forOXP:title andFile:@"manifest.plist"];
734 return [
self areRequirementsFulfilled:[NSDictionary dictionaryWithObjectsAndKeys:required, @"version", maxRequired, @"max_version", nil] forOXP:title andFile:@"manifest.plist"];
739+ (BOOL) areRequirementsFulfilled:(NSDictionary*)requirements forOXP:(NSString *)path andFile:(NSString *)file
742 NSString *requiredVersion =
nil;
743 NSString *maxVersion =
nil;
744 unsigned conditionsHandled = 0;
745 static NSArray *ooVersionComponents =
nil;
746 NSArray *oxpVersionComponents =
nil;
748 if (requirements ==
nil)
return YES;
750 if (ooVersionComponents ==
nil)
753 [ooVersionComponents retain];
760 requiredVersion = [requirements objectForKey:@"version"];
761 if (requiredVersion !=
nil)
764 if ([requiredVersion isKindOfClass:[NSString class]])
767 if (NSOrderedAscending ==
CompareVersions(ooVersionComponents, oxpVersionComponents)) OK = NO;
771 OOLog(
@"requirements.wrongType",
@"Expected %@ entry \"%@\
" to be string, but got %@ in OXP %@.", file,
@"version", [requirements
class], [path lastPathComponent]);
781 maxVersion = [requirements objectForKey:@"max_version"];
782 if (maxVersion !=
nil)
785 if ([maxVersion isKindOfClass:[NSString class]])
788 if (NSOrderedDescending ==
CompareVersions(ooVersionComponents, oxpVersionComponents)) OK = NO;
792 OOLog(
@"requirements.wrongType",
@"Expected %@ entry \"%@\
" to be string, but got %@ in OXP %@.", file,
@"max_version", [requirements
class], [path lastPathComponent]);
798 if (OK && conditionsHandled < [requirements
count])
801 OOLog(
@"requirements.unknown",
@"requires.plist for OXP %@ contains unknown keys, rejecting.", [path lastPathComponent]);
809+ (BOOL) manifestHasConflicts:(NSDictionary *)manifest logErrors:(BOOL)logErrors
811 NSDictionary *conflicting =
nil;
812 NSDictionary *conflictManifest =
nil;
813 NSString *conflictID =
nil;
814 NSArray *conflicts =
nil;
816 conflicts = [manifest oo_arrayForKey:kOOManifestConflictOXPs defaultValue:nil];
818 if (conflicts !=
nil && [conflicts
count] > 0)
821 foreach (conflicting, conflicts)
823 conflictID = [conflicting oo_stringForKey:kOOManifestRelationIdentifier];
824 conflictManifest = [sOXPManifests objectForKey:conflictID];
826 if (conflictManifest !=
nil)
829 if ([
self matchVersions:conflicting withVersion:[conflictManifest oo_stringForKey:
kOOManifestVersion]])
833 [
self addErrorWithKey:@"oxp-conflict" param1:[manifest oo_stringForKey:kOOManifestTitle] param2:[conflictManifest oo_stringForKey:kOOManifestTitle]];
834 OOLog(
@"oxp.conflict",
@"OXP %@ conflicts with %@ and was removed from the loading list",[[manifest oo_stringForKey:
kOOManifestFilePath] lastPathComponent],[[conflictManifest oo_stringForKey:
kOOManifestFilePath] lastPathComponent]);
845+ (void) filterSearchPathsForConflicts:(NSMutableArray *)searchPaths
847 NSDictionary *manifest =
nil;
848 NSString *identifier =
nil;
849 NSArray *identifiers = [sOXPManifests allKeys];
853 foreach (identifier, identifiers)
855 manifest = [sOXPManifests objectForKey:identifier];
858 if ([
self manifestHasConflicts:manifest logErrors:YES])
861 [searchPaths removeObject:[manifest oo_stringForKey:kOOManifestFilePath]];
862 [sOXPManifests removeObjectForKey:identifier];
869+ (BOOL) manifestHasMissingDependencies:(NSDictionary *)manifest logErrors:(BOOL)logErrors
871 NSDictionary *required =
nil;
872 NSArray *requireds =
nil;
874 requireds = [manifest oo_arrayForKey:kOOManifestRequiresOXPs defaultValue:nil];
876 if (requireds !=
nil && [requireds
count] > 0)
879 foreach (required, requireds)
881 if ([
ResourceManager manifest:manifest HasUnmetDependency:required logErrors:logErrors])
891+ (BOOL) manifest:(NSDictionary *)manifest HasUnmetDependency:(NSDictionary *)required logErrors:(BOOL)logErrors
893 NSString *requiredID = [required oo_stringForKey:kOOManifestRelationIdentifier];
894 NSMutableDictionary *requiredManifest = [sOXPManifests objectForKey:requiredID];
896 BOOL requirementsMet = NO;
897 if (requiredManifest !=
nil)
900 if ([
self matchVersions:required withVersion:[requiredManifest oo_stringForKey:
kOOManifestVersion]])
902 requirementsMet = YES;
905 NSSet *reqby = [requiredManifest oo_setForKey:kOOManifestRequiredBy defaultValue:[NSSet set]];
906 NSUInteger reqbycount = [reqby count];
910 reqby = [reqby setByAddingObject:[manifest oo_stringForKey:kOOManifestIdentifier]];
912 reqby = [reqby setByAddingObjectsFromSet:[manifest oo_setForKey:kOOManifestRequiredBy]];
913 if (reqbycount < [reqby
count])
922 [requiredManifest setObject:reqby forKey:kOOManifestRequiredBy];
925 if (!requirementsMet)
929 [
self addErrorWithKey:@"oxp-required" param1:[manifest oo_stringForKey:kOOManifestTitle] param2:[required oo_stringForKey:kOOManifestRelationDescription defaultValue:[required oo_stringForKey:kOOManifestRelationIdentifier]]];
930 OOLog(
@"oxp.requirementMissing",
@"OXP %@ had unmet requirements and was removed from the loading list",[[manifest oo_stringForKey:
kOOManifestFilePath] lastPathComponent]);
938+ (BOOL) filterSearchPathsForRequirements:(NSMutableArray *)searchPaths
940 NSDictionary *manifest =
nil;
941 NSString *identifier =
nil;
942 NSArray *identifiers = [sOXPManifests allKeys];
948 foreach (identifier, identifiers)
950 manifest = [sOXPManifests objectForKey:identifier];
953 if ([
self manifestHasMissingDependencies:manifest logErrors:YES])
956 [searchPaths removeObject:[manifest oo_stringForKey:kOOManifestFilePath]];
957 [sOXPManifests removeObjectForKey:identifier];
967+ (BOOL) matchVersions:(NSDictionary *)rangeDict withVersion:(NSString *)version
969 NSString *minimum = [rangeDict oo_stringForKey:kOOManifestRelationVersion defaultValue:nil];
970 NSString *maximum = [rangeDict oo_stringForKey:kOOManifestRelationMaxVersion defaultValue:nil];
972 NSArray *reqVersionComponents =
nil;
976 if (NSOrderedAscending ==
CompareVersions(isVersionComponents, reqVersionComponents))
985 if (NSOrderedDescending ==
CompareVersions(isVersionComponents, reqVersionComponents))
996+ (void) filterSearchPathsToExcludeScenarioOnlyPaths:(NSMutableArray *)searchPaths
998 NSDictionary *manifest =
nil;
999 NSString *identifier =
nil;
1000 NSArray *identifiers = [sOXPManifests allKeys];
1004 foreach (identifier, identifiers)
1006 manifest = [sOXPManifests objectForKey:identifier];
1007 if (manifest !=
nil)
1011 [searchPaths removeObject:[manifest oo_stringForKey:kOOManifestFilePath]];
1012 [sOXPManifests removeObjectForKey:identifier];
1020+ (void) filterSearchPathsByScenario:(NSMutableArray *)searchPaths
1022 NSDictionary *manifest =
nil;
1023 NSString *identifier =
nil;
1024 NSArray *identifiers = [sOXPManifests allKeys];
1028 foreach (identifier, identifiers)
1030 manifest = [sOXPManifests objectForKey:identifier];
1031 if (manifest !=
nil)
1036 [searchPaths removeObject:[manifest oo_stringForKey:kOOManifestFilePath]];
1037 [sOXPManifests removeObjectForKey:identifier];
1044+ (BOOL) manifestAllowedByScenario:(NSDictionary *)manifest
1051 OOLog(
@"scenario.check",
@"%@",
@"Checked scenario allowances in all state - this is an internal error; please report this");
1056 OOLog(
@"scenario.check",
@"%@",
@"Checked scenario allowances in none state - this is an internal error; please report this");
1066 NSString *uaoBit =
nil;
1083+ (BOOL) manifestAllowedByScenario:(NSDictionary *)manifest withIdentifier:(NSString *)identifier
1101+ (BOOL) manifestAllowedByScenario:(NSDictionary *)manifest withTag:(NSString *)tag
1110 NSSet *reqby = [manifest oo_setForKey:kOOManifestRequiredBy];
1113 NSString *identifier =
nil;
1114 foreach (identifier, reqby)
1116 NSDictionary *reqManifest = [sOXPManifests oo_dictionaryForKey:identifier defaultValue:nil];
1118 if (reqManifest !=
nil && [[reqManifest oo_arrayForKey:
kOOManifestTags] containsObject:tag])
1130+ (void) addErrorWithKey:(NSString *)descriptionKey param1:(
id)param1 param2:(
id)param2
1132 if (descriptionKey !=
nil)
1135 [sErrors addObject:[NSArray arrayWithObjects:descriptionKey, param1 ?: (id)@"", param2 ?: (id)@"", nil]];
1140+ (BOOL)checkCacheUpToDateForPaths:(NSArray *)searchPaths
1149 NSFileManager *fmgr = [NSFileManager defaultManager];
1150 BOOL upToDate = YES;
1152 NSMutableArray *modDates =
nil;
1153 NSString *path =
nil;
1156 if (
EXPECT_NOT([[NSUserDefaults standardUserDefaults] boolForKey:
@"always-flush-cache"]))
1167 oldPaths = [cacheMgr
objectForKey:kOOCacheKeySearchPaths
inCache:kOOCacheSearchPathModDates];
1168 if (upToDate && ![oldPaths isEqual:searchPaths])
1177 modDates = [NSMutableArray arrayWithCapacity:[searchPaths count]];
1178 foreach (path, searchPaths)
1180 modDate = [[fmgr oo_fileAttributesAtPath:path traverseLink:YES] objectForKey:NSFileModificationDate];
1184 modDate = [NSNumber numberWithDouble:[modDate timeIntervalSince1970]];
1185 [modDates addObject:modDate];
1215+ (BOOL) corePlist:(NSString *)fileName excludedAt:(NSString *)path
1217 if (![path isEqualToString:[
self builtInPath]])
1222 NSString *uaoBit =
nil;
1227 NSString *plist = [uaoBit substringFromIndex:[SCENARIO_OXP_DEFINITION_NOPLIST length]];
1228 if ([plist isEqualToString:fileName])
1240+ (NSDictionary *)dictionaryFromFilesNamed:(NSString *)fileName
1241 inFolder:(NSString *)folderName
1242 andMerge:(BOOL) mergeFiles
1244 return [
ResourceManager dictionaryFromFilesNamed:fileName inFolder:folderName mergeMode:mergeFiles ? MERGE_BASIC : MERGE_NONE cache:YES];
1248+ (NSDictionary *)dictionaryFromFilesNamed:(NSString *)fileName
1249 inFolder:(NSString *)folderName
1254 NSMutableArray *results =
nil;
1255 NSString *cacheKey =
nil;
1256 NSString *mergeType =
nil;
1258 NSEnumerator *enumerator =
nil;
1259 NSString *path =
nil;
1260 NSString *dictPath =
nil;
1261 NSDictionary *dict =
nil;
1263 if (fileName ==
nil)
return nil;
1268 mergeType =
@"none";
1272 mergeType =
@"basic";
1276 mergeType =
@"smart";
1279 if (mergeType ==
nil)
1281 OOLog(
kOOLogParameterError,
@"Unknown dictionary merge mode %u for %@. (This is an internal programming error, please report it.)", mergeMode, fileName);
1288 if (folderName !=
nil)
1290 cacheKey = [NSString stringWithFormat:@"%@/%@ merge:%@", folderName, fileName, mergeType];
1294 cacheKey = [NSString stringWithFormat:@"%@ merge:%@", fileName, mergeType];
1297 if (result !=
nil)
return result;
1303 for (enumerator = [
ResourceManager reversePathEnumerator]; (path = [enumerator nextObject]); )
1305 if (folderName !=
nil)
1307 dictPath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
1309 if (dict !=
nil)
break;
1311 dictPath = [path stringByAppendingPathComponent:fileName];
1313 if (dict !=
nil)
break;
1320 results = [NSMutableArray array];
1321 for (enumerator = [
ResourceManager pathEnumerator]; (path = [enumerator nextObject]); )
1327 dictPath = [path stringByAppendingPathComponent:fileName];
1329 if (dict !=
nil) [results addObject:dict];
1330 if (folderName !=
nil)
1332 dictPath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
1334 if (dict !=
nil) [results addObject:dict];
1338 if ([results
count] == 0)
return nil;
1341 result = [NSMutableDictionary dictionary];
1343 for (enumerator = [results objectEnumerator]; (dict = [enumerator nextObject]); )
1345 if (mergeMode ==
MERGE_SMART) [result mergeEntriesFromDictionary:dict];
1346 else [result addEntriesFromDictionary:dict];
1348 result = [[result copy] autorelease];
1357+ (NSArray *) arrayFromFilesNamed:(NSString *)fileName inFolder:(NSString *)folderName andMerge:(BOOL) mergeFiles
1359 return [
self arrayFromFilesNamed:fileName inFolder:folderName andMerge:mergeFiles cache:YES];
1363+ (NSArray *) arrayFromFilesNamed:(NSString *)fileName inFolder:(NSString *)folderName andMerge:(BOOL) mergeFiles cache:(BOOL)useCache
1366 NSMutableArray *results =
nil;
1367 NSString *cacheKey =
nil;
1369 NSEnumerator *enumerator =
nil;
1370 NSString *path =
nil;
1371 NSString *arrayPath =
nil;
1372 NSMutableArray *array =
nil;
1373 NSArray *arrayNonEditable =
nil;
1375 if (fileName ==
nil)
return nil;
1379 cacheKey = [NSString stringWithFormat:@"%@%@ merge:%@", (folderName != nil) ? [folderName stringByAppendingString:@"/"] : (NSString *)@"", fileName, mergeFiles ? @"yes" : @"no"];
1381 if (result !=
nil)
return result;
1387 for (enumerator = [
ResourceManager reversePathEnumerator]; (path = [enumerator nextObject]); )
1389 if (folderName !=
nil)
1391 arrayPath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
1393 if (arrayNonEditable !=
nil)
break;
1395 arrayPath = [path stringByAppendingPathComponent:fileName];
1397 if (arrayNonEditable !=
nil)
break;
1399 result = arrayNonEditable;
1404 results = [NSMutableArray array];
1405 for (enumerator = [
ResourceManager pathEnumerator]; (path = [enumerator nextObject]); )
1412 arrayPath = [path stringByAppendingPathComponent:fileName];
1413 array = [[OOArrayFromFile(arrayPath) mutableCopy] autorelease];
1414 if (array !=
nil) [results addObject:array];
1422 if ([array
count] != 0 && ([[fileName lowercaseString] isEqualToString:
@"nebulatextures.plist"] ||
1423 [[fileName lowercaseString] isEqualToString:
@"startextures.plist"]))
1424 [
self handleStarNebulaListMerging:results];
1426 if ([array
count] != 0 && [[array objectAtIndex:0] isKindOfClass:[NSArray class]])
1428 if ([[fileName lowercaseString] isEqualToString:
@"equipment.plist"])
1429 [
self handleEquipmentListMerging:results forLookupIndex:3];
1431 if (folderName !=
nil)
1433 arrayPath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
1434 array = [[OOArrayFromFile(arrayPath) mutableCopy] autorelease];
1435 if (array !=
nil) [results addObject:array];
1437 if ([array
count] != 0 && ([[fileName lowercaseString] isEqualToString:
@"nebulatextures.plist"] ||
1438 [[fileName lowercaseString] isEqualToString:
@"startextures.plist"]))
1439 [
self handleStarNebulaListMerging:results];
1441 if ([array
count] != 0 && [[array objectAtIndex:0] isKindOfClass:[NSArray class]])
1443 if ([[fileName lowercaseString] isEqualToString:
@"equipment.plist"])
1444 [
self handleEquipmentListMerging:results forLookupIndex:3];
1449 if ([results
count] == 0)
return nil;
1452 result = [NSMutableArray array];
1454 for (enumerator = [results objectEnumerator]; (array = [enumerator nextObject]); )
1456 [result addObjectsFromArray:array];
1459 if ([[fileName lowercaseString] isEqualToString:
@"equipment.plist"])
1461 [
self handleEquipmentOverrides:result];
1463 result = [[result copy] autorelease];
1468 return [NSArray arrayWithArray:result];
1475+ (void) handleEquipmentListMerging: (NSMutableArray *)arrayToProcess forLookupIndex:(
unsigned)lookupIndex
1478 NSMutableArray *refArray = [arrayToProcess objectAtIndex:[arrayToProcess count] - 1];
1482 for (i = 0; i < [refArray count]; i++)
1484 for (j = 0; j < [arrayToProcess count] - 1; j++)
1486 NSUInteger
count = [[arrayToProcess oo_arrayAtIndex:j] count];
1487 if (
count == 0)
continue;
1489 for (k=0; k <
count; k++)
1491 id processValue = [[[arrayToProcess oo_arrayAtIndex:j] oo_arrayAtIndex:k] oo_objectAtIndex:lookupIndex defaultValue:nil];
1492 id refValue = [[refArray oo_arrayAtIndex:i] oo_objectAtIndex:lookupIndex defaultValue:nil];
1494 if ([processValue isEqual:refValue])
1496 [[arrayToProcess objectAtIndex:j] replaceObjectAtIndex:k withObject:[refArray objectAtIndex:i]];
1497 [refArray removeObjectAtIndex:i];
1510+ (void) handleEquipmentOverrides: (NSMutableArray *)arrayToProcess
1512 NSEnumerator *equipKeyEnum =
nil;
1513 NSString *equipKey =
nil;
1514 NSDictionary *overrides =
nil;
1515 NSDictionary *overridesEntry =
nil;
1524 for (equipKeyEnum = [overrides keyEnumerator]; (equipKey = [equipKeyEnum nextObject]); )
1526 overridesEntry = [overrides objectForKey:equipKey];
1528 for (i = 0; i < [arrayToProcess count]; i++)
1530 NSMutableArray *equipArray = [[[arrayToProcess objectAtIndex:i] mutableCopy] autorelease];
1531 id refValue = [equipArray oo_objectAtIndex:EQUIPMENT_KEY_INDEX defaultValue:nil];
1533 if ([equipKey isEqual:refValue])
1535 NSEnumerator *infoKeyEnum =
nil;
1538 for (infoKeyEnum = [overridesEntry keyEnumerator]; (infoKey = [infoKeyEnum nextObject]); )
1541 if ([infoKey isEqualToString:
@"techlevel"])
1543 else if ([infoKey isEqualToString:
@"price"])
1544 [equipArray replaceObjectAtIndex:
EQUIPMENT_PRICE_INDEX withObject:[overridesEntry objectForKey:infoKey]];
1545 else if ([infoKey isEqualToString:
@"short_description"])
1547 else if ([infoKey isEqualToString:
@"name"])
1549 else if ([infoKey isEqualToString:
@"long_description"])
1551 else if ([infoKey isEqualToString:
@"description"])
1555 NSMutableDictionary *extra =
nil;
1561 extra = [NSMutableDictionary dictionary];
1565 extra = [[equipArray oo_dictionaryAtIndex:EQUIPMENT_EXTRA_INFO_INDEX] mutableCopy];
1568 if ([infoKey isEqualToString:
@"weapon_info"] || [infoKey isEqualToString:
@"script_info"])
1570 NSEnumerator *subEnum =
nil;
1572 NSMutableDictionary *subInfo =
nil;
1573 NSDictionary *subOverrides =
nil;
1575 if (![extra oo_dictionaryForKey:infoKey])
1578 subInfo = [NSMutableDictionary dictionary];
1582 subInfo = [[extra oo_dictionaryForKey:infoKey] mutableCopy];
1584 subOverrides = [overridesEntry oo_dictionaryForKey:infoKey];
1586 for (subEnum = [subOverrides keyEnumerator]; (subKey = [subEnum nextObject]); )
1588 [subInfo setObject:[subOverrides objectForKey:subKey] forKey:subKey];
1590 [extra setObject:[[subInfo copy] autorelease] forKey:infoKey];
1595 [extra setObject:[overridesEntry objectForKey:infoKey] forKey:infoKey];
1597 [equipArray replaceObjectAtIndex:EQUIPMENT_EXTRA_INFO_INDEX withObject:[[extra copy] autorelease]];
1600 [arrayToProcess replaceObjectAtIndex:i withObject:equipArray];
1609+ (void) handleStarNebulaListMerging: (NSMutableArray *)arrayToProcess
1612 NSMutableArray *refArray = [arrayToProcess objectAtIndex:[arrayToProcess count] - 1];
1615 for (i = 0; i < [refArray count]; i++)
1617 for (j = 0; j < [arrayToProcess count] - 1; j++)
1619 NSUInteger
count = [[arrayToProcess oo_arrayAtIndex:j] count];
1620 if (
count == 0)
continue;
1622 for (k = 0; k <
count; k++)
1624 id processValue = [[arrayToProcess oo_arrayAtIndex:j] oo_objectAtIndex:k defaultValue:nil];
1625 id refValue = [refArray oo_objectAtIndex:i defaultValue:nil];
1626 NSString *key1 =
nil;
1627 NSString *key2 =
nil;
1629 if ([processValue isKindOfClass:[NSString class]])
1631 key1 = processValue;
1633 else if ([processValue isKindOfClass:[NSDictionary class]])
1635 if (![processValue objectForKey:
@"key"])
1637 key1 = [processValue objectForKey:@"texture"];
1641 key1 = [processValue objectForKey:@"key"];
1644 if (!key1)
continue;
1646 if ([refValue isKindOfClass:[NSString class]])
1650 else if ([refValue isKindOfClass:[NSDictionary class]])
1652 if (![refValue objectForKey:
@"key"])
1654 key2 = [refValue objectForKey:@"texture"];
1658 key2 = [refValue objectForKey:@"key"];
1661 if (!key2)
continue;
1663 if ([key1 isEqual:key2])
1665 [[arrayToProcess objectAtIndex:j] replaceObjectAtIndex:k withObject:[refArray objectAtIndex:i]];
1666 [refArray removeObjectAtIndex:i];
1676+ (NSDictionary *) whitelistDictionary
1678 static id whitelistDictionary =
nil;
1680 if (whitelistDictionary ==
nil)
1682 NSString *path = [[[
ResourceManager builtInPath] stringByAppendingPathComponent:@"Config"] stringByAppendingPathComponent:@"whitelist.plist"];
1683 whitelistDictionary = [NSDictionary dictionaryWithContentsOfFile:path];
1684 if (whitelistDictionary ==
nil) whitelistDictionary = [NSNull null];
1686 [whitelistDictionary retain];
1689 if (whitelistDictionary == [NSNull
null])
return nil;
1690 return whitelistDictionary;
1694static NSString *LogClassKeyRoot(NSString *key)
1696 NSRange dot = [key rangeOfString:@"."];
1697 if (dot.location != NSNotFound)
1699 return [key substringToIndex:dot.location];
1708+ (NSDictionary *) logControlDictionary
1712 stringByAppendingPathComponent:@"logcontrol.plist"];
1713 NSMutableDictionary *logControl = [NSMutableDictionary dictionaryWithDictionary:OODictionaryFromFile(path)];
1714 if (logControl ==
nil) logControl = [NSMutableDictionary dictionary];
1717 NSMutableSet *coreRoots = [NSMutableSet set];
1718 NSString *key =
nil;
1721 [coreRoots addObject:LogClassKeyRoot(key)];
1724 NSArray *rootPaths = [
self rootPaths];
1725 NSString *configPath =
nil;
1726 NSDictionary *dict =
nil;
1729 foreach (path, [
self pathEnumerator])
1731 if ([rootPaths containsObject:path]) continue;
1733 configPath = [[path stringByAppendingPathComponent:@"Config"]
1734 stringByAppendingPathComponent:@"logcontrol.plist"];
1738 configPath = [path stringByAppendingPathComponent:@"logcontrol.plist"];
1743 if (![coreRoots containsObject:LogClassKeyRoot(key)])
1745 [logControl setObject:[dict objectForKey:key] forKey:key];
1751 foreach (path, rootPaths)
1753 configPath = [[path stringByAppendingPathComponent:@"Config"]
1754 stringByAppendingPathComponent:@"logcontrol.plist"];
1758 configPath = [path stringByAppendingPathComponent:@"logcontrol.plist"];
1763 [logControl setObject:[dict objectForKey:key] forKey:key];
1768 dict = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"logging-enable"];
1769 if (dict !=
nil) [logControl addEntriesFromDictionary:dict];
1775+ (NSDictionary *) roleCategoriesDictionary
1777 NSMutableDictionary *roleCategories = [NSMutableDictionary dictionaryWithCapacity:16];
1779 NSString *path =
nil;
1780 NSString *configPath =
nil;
1781 NSDictionary *categories =
nil;
1783 foreach (path, [
self pathEnumerator])
1785 if ([
ResourceManager corePlist:
@"role-categories.plist" excludedAt:path])
1790 configPath = [[path stringByAppendingPathComponent:@"Config"]
1791 stringByAppendingPathComponent:@"role-categories.plist"];
1793 if (categories !=
nil)
1807 return [[roleCategories copy] autorelease];
1811+ (void) mergeRoleCategories:(NSDictionary *)catData intoDictionary:(NSMutableDictionary *)categories
1813 NSMutableSet *contents =
nil;
1814 NSArray *catDataEntry =
nil;
1818 contents = [categories objectForKey:key];
1819 if (contents ==
nil)
1821 contents = [NSMutableSet setWithCapacity:16];
1822 [categories setObject:contents forKey:key];
1824 catDataEntry = [catData oo_arrayForKey:key];
1825 OOLog(
@"shipData.load.roleCategories",
@"Adding %ld entries for category %@", (
unsigned long)[catDataEntry
count], key);
1826 [contents addObjectsFromArray:catDataEntry];
1833 OOLog(
@"resourceManager.planetinfo.load",
@"%@",
@"Initialising manager");
1836 NSString *path =
nil;
1837 NSString *configPath =
nil;
1838 NSDictionary *categories =
nil;
1839 NSString *systemKey =
nil;
1841 foreach (path, [
self pathEnumerator])
1847 configPath = [[path stringByAppendingPathComponent:@"Config"]
1848 stringByAppendingPathComponent:@"planetinfo.plist"];
1850 if (categories !=
nil)
1854 NSDictionary *values = [categories oo_dictionaryForKey:systemKey defaultValue:nil];
1873 OOLog(
@"resourceManager.planetinfo.load",
@"%@",
@"Caching routes");
1875 OOLog(
@"resourceManager.planetinfo.load",
@"%@",
@"Initialised manager");
1876 return [manager autorelease];
1881+ (NSDictionary *) shaderBindingTypesDictionary
1883 static id shaderBindingTypesDictionary =
nil;
1885 if (shaderBindingTypesDictionary ==
nil)
1887 NSAutoreleasePool *pool = [NSAutoreleasePool new];
1889 NSString *path = [[[
ResourceManager builtInPath] stringByAppendingPathComponent:@"Config"] stringByAppendingPathComponent:@"shader-uniform-bindings.plist"];
1890 NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:path];
1891 NSArray *keys = [dict allKeys];
1894 unsigned changeCount = 0;
1897 NSString *key =
nil;
1900 NSDictionary *value = [dict oo_dictionaryForKey:key];
1901 NSString *inheritKey = [value oo_stringForKey:@"$inherit"];
1902 if (inheritKey !=
nil)
1905 NSMutableDictionary *mutableValue = [[value mutableCopy] autorelease];
1906 [mutableValue removeObjectForKey:@"$inherit"];
1907 NSDictionary *inherited = [dict oo_dictionaryForKey:inheritKey];
1908 if (inherited !=
nil)
1910 [mutableValue addEntriesFromDictionary:inherited];
1913 [dict setObject:[[mutableValue copy] autorelease] forKey:key];
1916 }
while (changeCount != 0);
1918 shaderBindingTypesDictionary = [dict copy];
1923 return shaderBindingTypesDictionary;
1927+ (NSString *) pathForFileNamed:(NSString *)fileName inFolder:(NSString *)folderName
1929 return [
self pathForFileNamed:fileName inFolder:folderName cache:YES];
1934+ (NSString *) pathForFileNamed:(NSString *)fileName inFolder:(NSString *)folderName cache:(BOOL)useCache
1936 NSString *result =
nil;
1937 NSString *cacheKey =
nil;
1939 NSString *path =
nil;
1940 NSString *filePath =
nil;
1941 NSFileManager *fmgr =
nil;
1943 if (fileName ==
nil)
return nil;
1947 if (folderName !=
nil) cacheKey = [NSString stringWithFormat:@"%@/%@", folderName, fileName];
1948 else cacheKey = fileName;
1950 if (result !=
nil)
return result;
1954 fmgr = [NSFileManager defaultManager];
1958 filePath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
1959 if ([fmgr oo_oxzFileExistsAtPath:filePath])
1965 filePath = [path stringByAppendingPathComponent:fileName];
1966 if ([fmgr oo_oxzFileExistsAtPath:filePath])
1975 OOLog(
@"resourceManager.foundFile",
@"Found %@/%@ at %@", folderName, fileName, filePath);
1987+ (id) retrieveFileNamed:(NSString *)fileName
1988 inFolder:(NSString *)folderName
1989 cache:(NSMutableDictionary **)ioCache
1992 usePathCache:(BOOL)useCache
1995 NSString *path =
nil;
1999 if (key ==
nil) key = [NSString stringWithFormat:@"%@:%@", folderName, fileName];
2000 if (*ioCache !=
nil)
2003 result = [*ioCache objectForKey:key];
2004 if (result)
return result;
2008 path = [
self pathForFileNamed:fileName inFolder:folderName cache:useCache];
2009 if (path !=
nil) result = [[[class alloc] initWithContentsOfFile:path] autorelease];
2011 if (result !=
nil && ioCache != NULL)
2013 if (*ioCache ==
nil) *ioCache = [[NSMutableDictionary alloc] init];
2014 [*ioCache setObject:result forKey:key];
2021+ (
OOMusic *) ooMusicNamed:(NSString *)fileName inFolder:(NSString *)folderName
2023 return [
self retrieveFileNamed:fileName
2026 key:[NSString stringWithFormat:@"OOMusic:%@:%@", folderName, fileName]
2032+ (
OOSound *) ooSoundNamed:(NSString *)fileName inFolder:(NSString *)folderName
2034 return [
self retrieveFileNamed:fileName
2037 key:[NSString stringWithFormat:@"OOSound:%@:%@", folderName, fileName]
2043+ (NSString *) stringFromFilesNamed:(NSString *)fileName inFolder:(NSString *)folderName
2045 return [
self stringFromFilesNamed:fileName inFolder:folderName cache:YES];
2049+ (NSString *) stringFromFilesNamed:(NSString *)fileName inFolder:(NSString *)folderName cache:(BOOL)useCache
2052 NSString *path =
nil;
2053 NSString *key =
nil;
2057 key = [NSString stringWithFormat:@"%@:%@", folderName, fileName];
2061 result = [sStringCache objectForKey:key];
2062 if (result)
return result;
2066 path = [
self pathForFileNamed:fileName inFolder:folderName cache:YES];
2067 if (path !=
nil) result = [NSString stringWithContentsOfUnicodeFile:path];
2069 if (result !=
nil && useCache)
2072 [sStringCache setObject:result forKey:key];
2079+ (NSDictionary *)loadScripts
2081 NSMutableDictionary *loadedScripts =
nil;
2082 NSArray *results =
nil;
2083 NSArray *paths =
nil;
2084 NSString *path =
nil;
2086 NSString *name =
nil;
2087 NSAutoreleasePool *pool =
nil;
2089 OOLog(
@"script.load.world.begin",
@"%@",
@"Loading world scripts...");
2091 loadedScripts = [NSMutableDictionary dictionary];
2093 foreach (path, paths)
2098 if (![
ResourceManager corePlist:
@"world-scripts.plist" excludedAt:path])
2100 pool = [[NSAutoreleasePool alloc] init];
2108 foreach (script, results)
2110 name = [script
name];
2111 if (name !=
nil) [loadedScripts setObject:script forKey:name];
2112 else OOLog(
@"script.load.unnamed",
@"Discarding anonymous script %@", script);
2116 @catch (NSException *exception)
2118 OOLog(
@"script.load.exception",
@"***** %s encountered exception %@ (%@) while trying to load script from %@ -- ignoring this location.", __PRETTY_FUNCTION__, [exception name], [exception reason], path);
2128 NSUInteger
count = [loadedScripts count];
2131 NSMutableArray *displayNames =
nil;
2133 NSString *displayString =
nil;
2135 displayNames = [NSMutableArray arrayWithCapacity:count];
2137 foreach (script, [loadedScripts allValues])
2142 displayString = [[displayNames sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] componentsJoinedByString:@"\n "];
2143 OOLog(
@"script.load.world.listAll",
@"Loaded %llu world scripts:\n %@",
count, displayString);
2147 OOLog(
@"script.load.world.listAll",
@"%@",
@"*** No world scripts loaded.");
2151 return loadedScripts;
2155+ (BOOL) writeDiagnosticData:(NSData *)data toFileNamed:(NSString *)name
2157 if (data ==
nil || name ==
nil)
return NO;
2159 NSString *directory = [
self diagnosticFileLocation];
2160 if (directory ==
nil)
return NO;
2162 NSArray *nameComponents = [name componentsSeparatedByString:@"/"];
2163 NSUInteger
count = [nameComponents count];
2166 name = [nameComponents lastObject];
2168 for (NSUInteger i = 0; i <
count - 1; i++)
2170 NSString *component = [nameComponents objectAtIndex:i];
2171 if ([component hasPrefix:
@"."])
2173 component = [@"!" stringByAppendingString:[component substringFromIndex:1]];
2175 directory = [directory stringByAppendingPathComponent:component];
2176 [[NSFileManager defaultManager] oo_createDirectoryAtPath:directory attributes:nil];
2180 return [data writeToFile:[directory stringByAppendingPathComponent:name] atomically:YES];
2184+ (BOOL) writeDiagnosticString:(NSString *)string toFileNamed:(NSString *)name
2186 return [
self writeDiagnosticData:[string dataUsingEncoding:NSUTF8StringEncoding] toFileNamed:name];
2190+ (BOOL) writeDiagnosticPList:(
id)plist toFileNamed:(NSString *)name
2192 NSData *data = [plist oldSchoolPListFormatWithErrorDescription:NULL];
2193 if (data ==
nil) [NSPropertyListSerialization dataFromPropertyList:plist format:NSPropertyListXMLFormat_v1_0 errorDescription:NULL];
2194 if (data ==
nil)
return NO;
2196 return [
self writeDiagnosticData:data toFileNamed:name];
2200+ (NSDictionary *) materialDefaults
2202 return [
self dictionaryFromFilesNamed:@"material-defaults.plist" inFolder:@"Config" andMerge:YES];
2206+ (BOOL)directoryExists:(NSString *)inPath create:(BOOL)inCreate
2208 BOOL exists, directory;
2209 NSFileManager *fmgr = [NSFileManager defaultManager];
2211 exists = [fmgr fileExistsAtPath:inPath isDirectory:&directory];
2213 if (exists && !directory)
2215 OOLog(
@"resourceManager.write.buildPath.failed",
@"Expected %@ to be a folder, but it is a file.", inPath);
2220 if (!inCreate)
return NO;
2221 if (![fmgr oo_createDirectoryAtPath:inPath attributes:
nil])
2223 OOLog(
@"resourceManager.write.buildPath.failed",
@"Could not create folder %@.", inPath);
2232+ (NSString *) diagnosticFileLocation
2240 NSMutableArray *displayPaths =
nil;
2241 NSString *path =
nil;
2244 displayPaths = [NSMutableArray arrayWithCapacity:[sSearchPaths count]];
2247 [displayPaths addObject:[[path stringByStandardizingPath] stringByAbbreviatingWithTildeInPath]];
2250 OOLog(
@"searchPaths.dumpAll",
@"Resource paths: %@\n %@",
sUseAddOns, [displayPaths componentsJoinedByString:
@"\n "]);
2257 [sSoundCache release];
2259 [sStringCache release];
void OOHUDResetTextEngine(void)
#define foreachkey(VAR, DICT)
void OOStandardsDeprecated(NSString *message)
BOOL OOEnforceStandards(void)
void OOStandardsError(NSString *message)
NSString * OOLogHandlerGetLogBasePath(void)
BOOL OOLogWillDisplayMessagesInClass(NSString *inMessageClass)
#define OOLog(class, format,...)
NSString *const kOOLogParameterError
static NSString *const kOOManifestTags
static NSString *const kOOManifestRequiredOoliteVersion
static NSString *const kOOManifestTitle
static NSString *const kOOManifestTagScenarioOnly
static NSString *const kOOManifestIdentifier
static NSString *const kOOManifestVersion
static NSString *const kOOManifestRequiredBy
static NSString *const kOOManifestFilePath
NSDictionary * OODictionaryFromFile(NSString *path)
NSArray * OOArrayFromFile(NSString *path)
NSArray * ComponentsFromVersionString(NSString *string)
NSComparisonResult CompareVersions(NSArray *version1, NSArray *version2)
#define SCENARIO_OXP_DEFINITION_BYID
#define SCENARIO_OXP_DEFINITION_NONE
#define SCENARIO_OXP_DEFINITION_NOPLIST
#define SCENARIO_OXP_DEFINITION_ALL
#define SCENARIO_OXP_DEFINITION_BYTAG
static NSMutableArray * sErrors
static NSString *const kOOLogCacheUpToDate
static NSArray * sUseAddOnsParts
static NSString *const kOOLogCacheStalePaths
static NSMutableArray * sSearchPaths
static NSString *const kOOCacheSearchPathModDates
static NSString *const kOOLogCacheStaleDates
static NSString *const kOOCacheKeySearchPaths
static NSMutableDictionary * sOXPManifests
static NSMutableDictionary * sSoundCache
static NSMutableArray * sOXPsWithMessagesFound
static NSString * sUseAddOns
static NSMutableDictionary * sStringCache
static NSString *const kOOLogCacheExplicitFlush
static NSString *const kOOCacheKeyModificationDates
NSDictionary * ParseOOSScripts(NSString *script)
static NSMutableArray * sExternalPaths
#define PLANETINFO_UNIVERSAL_KEY
@ EQUIPMENT_SHORT_DESC_INDEX
@ EQUIPMENT_LONG_DESC_INDEX
@ EQUIPMENT_TECH_LEVEL_INDEX
@ EQUIPMENT_EXTRA_INFO_INDEX
#define PLANETINFO_INTERSTELLAR_KEY
void setObject:forKey:inCache:(id inElement,[forKey] NSString *inKey,[inCache] NSString *inCacheKey)
void setAllowCacheWrites:(BOOL flag)
id objectForKey:inCache:(NSString *inKey,[inCache] NSString *inCacheKey)
OOCacheManager * sharedCache()
NSString * extractAddOnsPath()
OOOXZManager * sharedManager()
NSArray * additionalAddOnsPaths()
NSArray * worldScriptsAtPath:(NSString *path)
void setUniversalProperties:(NSDictionary *properties)
void setProperties:forSystemKey:(NSDictionary *properties,[forSystemKey] NSString *key)
void setInterstellarProperties:(NSDictionary *properties)
NSArray * pathsWithAddOns()
BOOL manifestAllowedByScenario:withTag:(NSDictionary *manifest, [withTag] NSString *tag)
NSArray * arrayFromFilesNamed:inFolder:andMerge:(NSString *fileName,[inFolder] NSString *folderName,[andMerge] BOOL mergeFiles)
void mergeRoleCategories:intoDictionary:(NSDictionary *catData, [intoDictionary] NSMutableDictionary *categories)
BOOL manifestAllowedByScenario:withIdentifier:(NSDictionary *manifest, [withIdentifier] NSString *identifier)
NSDictionary * dictionaryFromFilesNamed:inFolder:mergeMode:cache:(NSString *fileName,[inFolder] NSString *folderName,[mergeMode] OOResourceMergeMode mergeMode,[cache] BOOL useCache)
int ZEXPORT unzGetCurrentFileInfo64(unzFile file, unz_file_info64 *pfile_info, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize)
int ZEXPORT unzGoToFirstFile(unzFile file)
unzFile ZEXPORT unzOpen64(const void *path)
int ZEXPORT unzGoToNextFile(unzFile file)
int ZEXPORT unzClose(unzFile file)