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)
184 sUserRootPaths = [[NSArray alloc] initWithObjects:
187 [[[[NSHomeDirectory() stringByAppendingPathComponent:@"Library"]
188 stringByAppendingPathComponent:@"Application Support"]
189 stringByAppendingPathComponent:@"Oolite"]
190 stringByAppendingPathComponent:@"AddOns"],
191 [[[[NSBundle mainBundle] bundlePath]
192 stringByDeletingLastPathComponent]
193 stringByAppendingPathComponent:@"AddOns"],
203 stringByAppendingPathComponent:@".Oolite"]
204 stringByAppendingPathComponent:@"AddOns"],
209 OOLog(
@"searchPaths.debug",
@"%@",sUserRootPaths);
210 return sUserRootPaths;
214+ (NSString *)builtInPath
222 return [[NSBundle mainBundle] resourcePath];
227+ (NSArray *)pathsWithAddOns
233 sUseAddOns = [[NSString alloc] initWithString:SCENARIO_OXP_DEFINITION_ALL];
234 sUseAddOnsParts = [[sUseAddOns componentsSeparatedByString:@";"] retain];
241 return (NSArray *)[NSArray arrayWithObject:[
self builtInPath]];
247 NSFileManager *fmgr = [NSFileManager defaultManager];
248 NSArray *rootPaths =
nil;
249 NSMutableArray *existingRootPaths =
nil;
250 NSEnumerator *pathEnum =
nil;
251 NSString *root =
nil;
252 NSDirectoryEnumerator *dirEnum =
nil;
253 NSString *subPath =
nil;
254 NSString *path =
nil;
258 rootPaths = [
self rootPaths];
259 existingRootPaths = [NSMutableArray arrayWithCapacity:[rootPaths count]];
260 for (pathEnum = [rootPaths objectEnumerator]; (root = [pathEnum nextObject]); )
262 if ([fmgr fileExistsAtPath:root isDirectory:&isDirectory] && isDirectory)
264 [existingRootPaths addObject:root];
271 foreach(path, existingRootPaths)
273 [
self checkPotentialPath:path :sSearchPaths];
277 for (pathEnum = [existingRootPaths objectEnumerator]; (root = [pathEnum nextObject]); )
280 if ([fmgr fileExistsAtPath:root isDirectory:&isDirectory] && isDirectory)
282 for (dirEnum = [fmgr enumeratorAtPath:root]; (subPath = [dirEnum nextObject]); )
285 path = [root stringByAppendingPathComponent:subPath];
286 if ([fmgr fileExistsAtPath:path isDirectory:&isDirectory])
291 if ([[[path pathExtension] lowercaseString] isEqualToString:
@"oxp"])
293 [
self checkPotentialPath:path :sSearchPaths];
294 if ([
sSearchPaths containsObject:path]) [
self checkOXPMessagesInPath:path];
299 [dirEnum skipDescendents];
305 if ([[[path pathExtension] lowercaseString] isEqualToString:
@"oxz"])
307 [
self checkPotentialPath:path :sSearchPaths];
308 if ([
sSearchPaths containsObject:path]) [
self checkOXPMessagesInPath:path];
316 for (pathEnum = [
sExternalPaths objectEnumerator]; (path = [pathEnum nextObject]); )
318 [
self checkPotentialPath:path :sSearchPaths];
319 if ([
sSearchPaths containsObject:path]) [
self checkOXPMessagesInPath:path];
327 [
self filterSearchPathsToExcludeScenarioOnlyPaths:sSearchPaths];
336 [
self filterSearchPathsForConflicts:sSearchPaths];
348 while (![
self filterSearchPathsForRequirements:
sSearchPaths]) {}
355 [
self filterSearchPathsByScenario:sSearchPaths];
358 [
self checkCacheUpToDateForPaths:sSearchPaths];
366 NSString *path =
nil;
367 NSEnumerator *pathEnum =
nil;
370 NSArray *folders = [NSArray arrayWithObjects:@"AIs",@"Images",@"Models",@"Music",@"Scenarios",@"Scripts",@"Shaders",@"Sounds",@"Textures",nil];
372 for (pathEnum = [[
ResourceManager paths] reverseObjectEnumerator]; (path = [pathEnum nextObject]); )
374 if ([path hasSuffix:
@".oxz"])
376 [
self preloadFileListFromOXZ:path forFolders:folders];
380 [
self preloadFileListFromFolder:path forFolders:folders];
386+ (void) preloadFileListFromOXZ:(NSString *)path forFolders:(NSArray *)folders
389 const char* zipname = [path UTF8String];
390 char componentName[512];
398 OOLog(
@"resourceManager.error",
@"Could not open .oxz at %@ as zip file",path);
409 NSString *zipEntry = [NSString stringWithUTF8String:componentName];
410 NSArray *pathBits = [zipEntry pathComponents];
411 if ([pathBits
count] >= 2)
413 NSString *folder = [pathBits oo_stringAtIndex:0];
414 if ([folders containsObject:folder])
417 bitRange.location = 1;
418 bitRange.length = [pathBits count]-1;
419 NSString *file = [NSString pathWithComponents:[pathBits subarrayWithRange:bitRange]];
420 NSString *fullPath = [[path stringByAppendingPathComponent:folder] stringByAppendingPathComponent:file];
422 [
self preloadFilePathFor:file inFolder:folder atPath:fullPath];
434+ (void) preloadFileListFromFolder:(NSString *)path forFolders:(NSArray *)folders
436 NSFileManager *fmgr = [NSFileManager defaultManager];
437 NSString *subFolder =
nil;
438 NSString *subFolderPath =
nil;
439 NSArray *fileList =
nil;
440 NSString *fileName =
nil;
443 foreach (subFolder, folders)
445 subFolderPath = [path stringByAppendingPathComponent:subFolder];
446 fileList = [fmgr oo_directoryContentsAtPath:subFolderPath];
447 foreach (fileName, fileList)
449 [
self preloadFilePathFor:fileName inFolder:subFolder atPath:[subFolderPath stringByAppendingPathComponent:fileName]];
456+ (void) preloadFilePathFor:(NSString *)fileName inFolder:(NSString *)subFolder atPath:(NSString *)path
459 NSString *cacheKey = [NSString stringWithFormat:@"%@/%@", subFolder, fileName];
464 OOLog(
@"resourceManager.foundFile.preLoad",
@"Found %@/%@ at %@", subFolder, fileName, path);
477 return [
self pathsWithAddOns];
481+ (NSString *)useAddOns
487+ (void)setUseAddOns:(NSString *)useAddOns
496 sUseAddOnsParts = [[sUseAddOns componentsSeparatedByString:@";"] retain];
517 [
self checkCacheUpToDateForPaths:[
self paths]];
521 [
self preloadFileLists];
527+ (void) addExternalPath:(NSString *)path
532 [sSearchPaths addObject:path];
535 [sExternalPaths addObject:path];
540+ (NSEnumerator *)pathEnumerator
542 return [[
self paths] objectEnumerator];
546+ (NSEnumerator *)reversePathEnumerator
548 return [[
self paths] reverseObjectEnumerator];
552+ (NSArray *)OXPsWithMessagesFound
554 return [[sOXPsWithMessagesFound copy] autorelease];
558+ (NSDictionary *)manifestForIdentifier:(NSString *)identifier
560 return [sOXPManifests objectForKey:identifier];
564+ (void) checkOXPMessagesInPath:(NSString *)path
566 NSArray *OXPMessageArray =
OOArrayFromFile([path stringByAppendingPathComponent:
@"OXPMessages.plist"]);
568 if ([OXPMessageArray
count] > 0)
571 for (i = 0; i < [OXPMessageArray count]; i++)
573 NSString *oxpMessage = [OXPMessageArray oo_stringAtIndex:i];
576 OOLog(
@"oxp.message",
@"%@: %@", path, oxpMessage);
580 [sOXPsWithMessagesFound addObject:[path lastPathComponent]];
586+ (void)checkPotentialPath:(NSString *)path :(NSMutableArray *)searchPaths
588 NSDictionary *requirements =
nil;
589 NSDictionary *manifest =
nil;
590 BOOL requirementsMet = YES;
592 if (![[[path pathExtension] lowercaseString] isEqualToString:
@"oxz"])
596 requirementsMet = [
self areRequirementsFulfilled:requirements forOXP:path andFile:@"requires.plist"];
598 if (!requirementsMet)
600 NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
601 OOLog(
@"oxp.versionMismatch",
@"OXP %@ is incompatible with version %@ of Oolite.", path, version);
602 [
self addErrorWithKey:@"oxp-is-incompatible" param1:[path lastPathComponent] param2:version];
609 if ([[[path pathExtension] lowercaseString] isEqualToString:
@"oxz"])
611 OOLog(
@"oxp.noManifest",
@"OXZ %@ has no manifest.plist", path);
612 [
self addErrorWithKey:@"oxz-lacks-manifest" param1:[path lastPathComponent] param2:nil];
617 if ([[[path pathExtension] lowercaseString] isEqualToString:
@"oxp"])
619 OOStandardsError([NSString stringWithFormat:
@"OXP %@ has no manifest.plist", path]);
622 [
self addErrorWithKey:@"oxp-lacks-manifest" param1:[path lastPathComponent] param2:nil];
627 manifest = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"__oolite.tmp.%@",path],kOOManifestIdentifier,@"1",kOOManifestVersion,@"OXP without manifest",kOOManifestTitle,@"1",kOOManifestRequiredOoliteVersion,nil];
631 requirementsMet = [
self validateManifest:manifest forOXP:path];
636 [searchPaths addObject:path];
641+ (BOOL) validateManifest:(NSDictionary*)manifest forOXP:(NSString *)path
645 sOXPManifests = [[NSMutableDictionary alloc] initWithCapacity:32];
649 NSString *identifier = [manifest oo_stringForKey:kOOManifestIdentifier defaultValue:nil];
650 NSString *version = [manifest oo_stringForKey:kOOManifestVersion defaultValue:nil];
651 NSString *required = [manifest oo_stringForKey:kOOManifestRequiredOoliteVersion defaultValue:nil];
652 NSString *title = [manifest oo_stringForKey:kOOManifestTitle defaultValue:nil];
654 if (identifier ==
nil)
657 [
self addErrorWithKey:@"oxp-manifest-incomplete" param1:title param2:kOOManifestIdentifier];
663 [
self addErrorWithKey:@"oxp-manifest-incomplete" param1:title param2:kOOManifestVersion];
669 [
self addErrorWithKey:@"oxp-manifest-incomplete" param1:title param2:kOOManifestRequiredOoliteVersion];
675 [
self addErrorWithKey:@"oxp-manifest-incomplete" param1:title param2:kOOManifestTitle];
682 OK = [
self checkVersionCompatibility:manifest forOXP:title];
686 NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
687 OOLog(
@"oxp.versionMismatch",
@"OXP %@ is incompatible with version %@ of Oolite.", path, version);
688 [
self addErrorWithKey:@"oxp-is-incompatible" param1:[path lastPathComponent] param2:version];
692 NSDictionary *duplicate = [sOXPManifests objectForKey:identifier];
693 if (duplicate !=
nil)
695 OOLog(
@"oxp.duplicate",
@"OXP %@ has the same identifier (%@) as %@ which has already been loaded.",path,identifier,[duplicate oo_stringForKey:
kOOManifestFilePath]);
696 [
self addErrorWithKey:@"oxp-manifest-duplicate" param1:path param2:[duplicate oo_stringForKey:kOOManifestFilePath]];
699 NSMutableDictionary *mData = [NSMutableDictionary dictionaryWithDictionary:manifest];
700 [mData setObject:path forKey:kOOManifestFilePath];
702 [sOXPManifests setObject:mData forKey:identifier];
707+ (BOOL) checkVersionCompatibility:(NSDictionary *)manifest forOXP:(NSString *)title
709 NSString *required = [manifest oo_stringForKey:kOOManifestRequiredOoliteVersion defaultValue:nil];
710 NSString *maxRequired = [manifest oo_stringForKey:kOOManifestMaximumOoliteVersion defaultValue:nil];
712 if (maxRequired ==
nil || [maxRequired length] == 0)
714 return [
self areRequirementsFulfilled:[NSDictionary dictionaryWithObjectsAndKeys:required, @"version", nil] forOXP:title andFile:@"manifest.plist"];
718 return [
self areRequirementsFulfilled:[NSDictionary dictionaryWithObjectsAndKeys:required, @"version", maxRequired, @"max_version", nil] forOXP:title andFile:@"manifest.plist"];
723+ (BOOL) areRequirementsFulfilled:(NSDictionary*)requirements forOXP:(NSString *)path andFile:(NSString *)file
726 NSString *requiredVersion =
nil;
727 NSString *maxVersion =
nil;
728 unsigned conditionsHandled = 0;
729 static NSArray *ooVersionComponents =
nil;
730 NSArray *oxpVersionComponents =
nil;
732 if (requirements ==
nil)
return YES;
734 if (ooVersionComponents ==
nil)
737 [ooVersionComponents retain];
744 requiredVersion = [requirements objectForKey:@"version"];
745 if (requiredVersion !=
nil)
748 if ([requiredVersion isKindOfClass:[NSString
class]])
751 if (NSOrderedAscending ==
CompareVersions(ooVersionComponents, oxpVersionComponents)) OK = NO;
755 OOLog(
@"requirements.wrongType",
@"Expected %@ entry \"%@\
" to be string, but got %@ in OXP %@.", file,
@"version", [requirements
class], [path lastPathComponent]);
765 maxVersion = [requirements objectForKey:@"max_version"];
766 if (maxVersion !=
nil)
769 if ([maxVersion isKindOfClass:[NSString
class]])
772 if (NSOrderedDescending ==
CompareVersions(ooVersionComponents, oxpVersionComponents)) OK = NO;
776 OOLog(
@"requirements.wrongType",
@"Expected %@ entry \"%@\
" to be string, but got %@ in OXP %@.", file,
@"max_version", [requirements
class], [path lastPathComponent]);
782 if (OK && conditionsHandled < [requirements
count])
785 OOLog(
@"requirements.unknown",
@"requires.plist for OXP %@ contains unknown keys, rejecting.", [path lastPathComponent]);
793+ (BOOL) manifestHasConflicts:(NSDictionary *)manifest logErrors:(BOOL)logErrors
795 NSDictionary *conflicting =
nil;
796 NSDictionary *conflictManifest =
nil;
797 NSString *conflictID =
nil;
798 NSArray *conflicts =
nil;
800 conflicts = [manifest oo_arrayForKey:kOOManifestConflictOXPs defaultValue:nil];
802 if (conflicts !=
nil && [conflicts
count] > 0)
805 foreach (conflicting, conflicts)
807 conflictID = [conflicting oo_stringForKey:kOOManifestRelationIdentifier];
808 conflictManifest = [sOXPManifests objectForKey:conflictID];
810 if (conflictManifest !=
nil)
813 if ([
self matchVersions:conflicting withVersion:[conflictManifest oo_stringForKey:
kOOManifestVersion]])
817 [
self addErrorWithKey:@"oxp-conflict" param1:[manifest oo_stringForKey:kOOManifestTitle] param2:[conflictManifest oo_stringForKey:kOOManifestTitle]];
818 OOLog(
@"oxp.conflict",
@"OXP %@ conflicts with %@ and was removed from the loading list",[[manifest oo_stringForKey:
kOOManifestFilePath] lastPathComponent],[[conflictManifest oo_stringForKey:
kOOManifestFilePath] lastPathComponent]);
829+ (void) filterSearchPathsForConflicts:(NSMutableArray *)searchPaths
831 NSDictionary *manifest =
nil;
832 NSString *identifier =
nil;
833 NSArray *identifiers = [sOXPManifests allKeys];
837 foreach (identifier, identifiers)
839 manifest = [sOXPManifests objectForKey:identifier];
842 if ([
self manifestHasConflicts:manifest logErrors:YES])
845 [searchPaths removeObject:[manifest oo_stringForKey:kOOManifestFilePath]];
846 [sOXPManifests removeObjectForKey:identifier];
853+ (BOOL) manifestHasMissingDependencies:(NSDictionary *)manifest logErrors:(BOOL)logErrors
855 NSDictionary *required =
nil;
856 NSArray *requireds =
nil;
858 requireds = [manifest oo_arrayForKey:kOOManifestRequiresOXPs defaultValue:nil];
860 if (requireds !=
nil && [requireds
count] > 0)
863 foreach (required, requireds)
865 if ([
ResourceManager manifest:manifest HasUnmetDependency:required logErrors:logErrors])
875+ (BOOL) manifest:(NSDictionary *)manifest HasUnmetDependency:(NSDictionary *)required logErrors:(BOOL)logErrors
877 NSString *requiredID = [required oo_stringForKey:kOOManifestRelationIdentifier];
878 NSMutableDictionary *requiredManifest = [sOXPManifests objectForKey:requiredID];
880 BOOL requirementsMet = NO;
881 if (requiredManifest !=
nil)
884 if ([
self matchVersions:required withVersion:[requiredManifest oo_stringForKey:
kOOManifestVersion]])
886 requirementsMet = YES;
889 NSSet *reqby = [requiredManifest oo_setForKey:kOOManifestRequiredBy defaultValue:[NSSet set]];
890 NSUInteger reqbycount = [reqby count];
894 reqby = [reqby setByAddingObject:[manifest oo_stringForKey:kOOManifestIdentifier]];
896 reqby = [reqby setByAddingObjectsFromSet:[manifest oo_setForKey:kOOManifestRequiredBy]];
897 if (reqbycount < [reqby
count])
906 [requiredManifest setObject:reqby forKey:kOOManifestRequiredBy];
909 if (!requirementsMet)
913 [
self addErrorWithKey:@"oxp-required" param1:[manifest oo_stringForKey:kOOManifestTitle] param2:[required oo_stringForKey:kOOManifestRelationDescription defaultValue:[required oo_stringForKey:kOOManifestRelationIdentifier]]];
914 OOLog(
@"oxp.requirementMissing",
@"OXP %@ had unmet requirements and was removed from the loading list",[[manifest oo_stringForKey:
kOOManifestFilePath] lastPathComponent]);
922+ (BOOL) filterSearchPathsForRequirements:(NSMutableArray *)searchPaths
924 NSDictionary *manifest =
nil;
925 NSString *identifier =
nil;
926 NSArray *identifiers = [sOXPManifests allKeys];
932 foreach (identifier, identifiers)
934 manifest = [sOXPManifests objectForKey:identifier];
937 if ([
self manifestHasMissingDependencies:manifest logErrors:YES])
940 [searchPaths removeObject:[manifest oo_stringForKey:kOOManifestFilePath]];
941 [sOXPManifests removeObjectForKey:identifier];
951+ (BOOL) matchVersions:(NSDictionary *)rangeDict withVersion:(NSString *)version
953 NSString *minimum = [rangeDict oo_stringForKey:kOOManifestRelationVersion defaultValue:nil];
954 NSString *maximum = [rangeDict oo_stringForKey:kOOManifestRelationMaxVersion defaultValue:nil];
956 NSArray *reqVersionComponents =
nil;
960 if (NSOrderedAscending ==
CompareVersions(isVersionComponents, reqVersionComponents))
969 if (NSOrderedDescending ==
CompareVersions(isVersionComponents, reqVersionComponents))
980+ (void) filterSearchPathsToExcludeScenarioOnlyPaths:(NSMutableArray *)searchPaths
982 NSDictionary *manifest =
nil;
983 NSString *identifier =
nil;
984 NSArray *identifiers = [sOXPManifests allKeys];
988 foreach (identifier, identifiers)
990 manifest = [sOXPManifests objectForKey:identifier];
995 [searchPaths removeObject:[manifest oo_stringForKey:kOOManifestFilePath]];
996 [sOXPManifests removeObjectForKey:identifier];
1004+ (void) filterSearchPathsByScenario:(NSMutableArray *)searchPaths
1006 NSDictionary *manifest =
nil;
1007 NSString *identifier =
nil;
1008 NSArray *identifiers = [sOXPManifests allKeys];
1012 foreach (identifier, identifiers)
1014 manifest = [sOXPManifests objectForKey:identifier];
1015 if (manifest !=
nil)
1020 [searchPaths removeObject:[manifest oo_stringForKey:kOOManifestFilePath]];
1021 [sOXPManifests removeObjectForKey:identifier];
1028+ (BOOL) manifestAllowedByScenario:(NSDictionary *)manifest
1035 OOLog(
@"scenario.check",
@"%@",
@"Checked scenario allowances in all state - this is an internal error; please report this");
1040 OOLog(
@"scenario.check",
@"%@",
@"Checked scenario allowances in none state - this is an internal error; please report this");
1050 NSString *uaoBit =
nil;
1067+ (BOOL) manifestAllowedByScenario:(NSDictionary *)manifest withIdentifier:(NSString *)identifier
1085+ (BOOL) manifestAllowedByScenario:(NSDictionary *)manifest withTag:(NSString *)tag
1094 NSSet *reqby = [manifest oo_setForKey:kOOManifestRequiredBy];
1097 NSString *identifier =
nil;
1098 foreach (identifier, reqby)
1100 NSDictionary *reqManifest = [sOXPManifests oo_dictionaryForKey:identifier defaultValue:nil];
1102 if (reqManifest !=
nil && [[reqManifest oo_arrayForKey:
kOOManifestTags] containsObject:tag])
1114+ (void) addErrorWithKey:(NSString *)descriptionKey param1:(
id)param1 param2:(
id)param2
1116 if (descriptionKey !=
nil)
1119 [sErrors addObject:[NSArray arrayWithObjects:descriptionKey, param1 ?: (id)@"", param2 ?: (id)@"", nil]];
1124+ (BOOL)checkCacheUpToDateForPaths:(NSArray *)searchPaths
1133 NSFileManager *fmgr = [NSFileManager defaultManager];
1134 BOOL upToDate = YES;
1136 NSMutableArray *modDates =
nil;
1137 NSEnumerator *pathEnum =
nil;
1138 NSString *path =
nil;
1141 if (
EXPECT_NOT([[NSUserDefaults standardUserDefaults] boolForKey:
@"always-flush-cache"]))
1152 oldPaths = [cacheMgr
objectForKey:kOOCacheKeySearchPaths
inCache:kOOCacheSearchPathModDates];
1153 if (upToDate && ![oldPaths isEqual:searchPaths])
1162 modDates = [NSMutableArray arrayWithCapacity:[searchPaths count]];
1163 for (pathEnum = [searchPaths objectEnumerator]; (path = [pathEnum nextObject]); )
1165 modDate = [[fmgr oo_fileAttributesAtPath:path traverseLink:YES] objectForKey:NSFileModificationDate];
1169 modDate = [NSNumber numberWithDouble:[modDate timeIntervalSince1970]];
1170 [modDates addObject:modDate];
1200+ (BOOL) corePlist:(NSString *)fileName excludedAt:(NSString *)path
1202 if (![path isEqualToString:[
self builtInPath]])
1207 NSString *uaoBit =
nil;
1212 NSString *plist = [uaoBit substringFromIndex:[SCENARIO_OXP_DEFINITION_NOPLIST length]];
1213 if ([plist isEqualToString:fileName])
1225+ (NSDictionary *)dictionaryFromFilesNamed:(NSString *)fileName
1226 inFolder:(NSString *)folderName
1227 andMerge:(BOOL) mergeFiles
1229 return [
ResourceManager dictionaryFromFilesNamed:fileName inFolder:folderName mergeMode:mergeFiles ? MERGE_BASIC : MERGE_NONE cache:YES];
1233+ (NSDictionary *)dictionaryFromFilesNamed:(NSString *)fileName
1234 inFolder:(NSString *)folderName
1239 NSMutableArray *results =
nil;
1240 NSString *cacheKey =
nil;
1241 NSString *mergeType =
nil;
1243 NSEnumerator *enumerator =
nil;
1244 NSString *path =
nil;
1245 NSString *dictPath =
nil;
1246 NSDictionary *dict =
nil;
1248 if (fileName ==
nil)
return nil;
1253 mergeType =
@"none";
1257 mergeType =
@"basic";
1261 mergeType =
@"smart";
1264 if (mergeType ==
nil)
1266 OOLog(
kOOLogParameterError,
@"Unknown dictionary merge mode %u for %@. (This is an internal programming error, please report it.)", mergeMode, fileName);
1273 if (folderName !=
nil)
1275 cacheKey = [NSString stringWithFormat:@"%@/%@ merge:%@", folderName, fileName, mergeType];
1279 cacheKey = [NSString stringWithFormat:@"%@ merge:%@", fileName, mergeType];
1282 if (result !=
nil)
return result;
1288 for (enumerator = [
ResourceManager reversePathEnumerator]; (path = [enumerator nextObject]); )
1290 if (folderName !=
nil)
1292 dictPath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
1294 if (dict !=
nil)
break;
1296 dictPath = [path stringByAppendingPathComponent:fileName];
1298 if (dict !=
nil)
break;
1305 results = [NSMutableArray array];
1306 for (enumerator = [
ResourceManager pathEnumerator]; (path = [enumerator nextObject]); )
1312 dictPath = [path stringByAppendingPathComponent:fileName];
1314 if (dict !=
nil) [results addObject:dict];
1315 if (folderName !=
nil)
1317 dictPath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
1319 if (dict !=
nil) [results addObject:dict];
1323 if ([results
count] == 0)
return nil;
1326 result = [NSMutableDictionary dictionary];
1328 for (enumerator = [results objectEnumerator]; (dict = [enumerator nextObject]); )
1330 if (mergeMode ==
MERGE_SMART) [result mergeEntriesFromDictionary:dict];
1331 else [result addEntriesFromDictionary:dict];
1333 result = [[result copy] autorelease];
1342+ (NSArray *) arrayFromFilesNamed:(NSString *)fileName inFolder:(NSString *)folderName andMerge:(BOOL) mergeFiles
1344 return [
self arrayFromFilesNamed:fileName inFolder:folderName andMerge:mergeFiles cache:YES];
1348+ (NSArray *) arrayFromFilesNamed:(NSString *)fileName inFolder:(NSString *)folderName andMerge:(BOOL) mergeFiles cache:(BOOL)useCache
1351 NSMutableArray *results =
nil;
1352 NSString *cacheKey =
nil;
1354 NSEnumerator *enumerator =
nil;
1355 NSString *path =
nil;
1356 NSString *arrayPath =
nil;
1357 NSMutableArray *array =
nil;
1358 NSArray *arrayNonEditable =
nil;
1360 if (fileName ==
nil)
return nil;
1364 cacheKey = [NSString stringWithFormat:@"%@%@ merge:%@", (folderName != nil) ? [folderName stringByAppendingString:@"/"] : (NSString *)@"", fileName, mergeFiles ? @"yes" : @"no"];
1366 if (result !=
nil)
return result;
1372 for (enumerator = [
ResourceManager reversePathEnumerator]; (path = [enumerator nextObject]); )
1374 if (folderName !=
nil)
1376 arrayPath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
1378 if (arrayNonEditable !=
nil)
break;
1380 arrayPath = [path stringByAppendingPathComponent:fileName];
1382 if (arrayNonEditable !=
nil)
break;
1384 result = arrayNonEditable;
1389 results = [NSMutableArray array];
1390 for (enumerator = [
ResourceManager pathEnumerator]; (path = [enumerator nextObject]); )
1397 arrayPath = [path stringByAppendingPathComponent:fileName];
1398 array = [[OOArrayFromFile(arrayPath) mutableCopy] autorelease];
1399 if (array !=
nil) [results addObject:array];
1407 if ([array
count] != 0 && ([[fileName lowercaseString] isEqualToString:
@"nebulatextures.plist"] ||
1408 [[fileName lowercaseString] isEqualToString:
@"startextures.plist"]))
1409 [
self handleStarNebulaListMerging:results];
1411 if ([array
count] != 0 && [[array objectAtIndex:0] isKindOfClass:[NSArray
class]])
1413 if ([[fileName lowercaseString] isEqualToString:
@"equipment.plist"])
1414 [
self handleEquipmentListMerging:results forLookupIndex:3];
1416 if (folderName !=
nil)
1418 arrayPath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
1419 array = [[OOArrayFromFile(arrayPath) mutableCopy] autorelease];
1420 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];
1434 if ([results
count] == 0)
return nil;
1437 result = [NSMutableArray array];
1439 for (enumerator = [results objectEnumerator]; (array = [enumerator nextObject]); )
1441 [result addObjectsFromArray:array];
1444 if ([[fileName lowercaseString] isEqualToString:
@"equipment.plist"])
1446 [
self handleEquipmentOverrides:result];
1448 result = [[result copy] autorelease];
1453 return [NSArray arrayWithArray:result];
1460+ (void) handleEquipmentListMerging: (NSMutableArray *)arrayToProcess forLookupIndex:(
unsigned)lookupIndex
1463 NSMutableArray *refArray = [arrayToProcess objectAtIndex:[arrayToProcess count] - 1];
1467 for (i = 0; i < [refArray count]; i++)
1469 for (j = 0; j < [arrayToProcess count] - 1; j++)
1471 NSUInteger
count = [[arrayToProcess oo_arrayAtIndex:j] count];
1472 if (
count == 0)
continue;
1474 for (k=0; k <
count; k++)
1476 id processValue = [[[arrayToProcess oo_arrayAtIndex:j] oo_arrayAtIndex:k] oo_objectAtIndex:lookupIndex defaultValue:nil];
1477 id refValue = [[refArray oo_arrayAtIndex:i] oo_objectAtIndex:lookupIndex defaultValue:nil];
1479 if ([processValue isEqual:refValue])
1481 [[arrayToProcess objectAtIndex:j] replaceObjectAtIndex:k withObject:[refArray objectAtIndex:i]];
1482 [refArray removeObjectAtIndex:i];
1495+ (void) handleEquipmentOverrides: (NSMutableArray *)arrayToProcess
1497 NSEnumerator *equipKeyEnum =
nil;
1498 NSString *equipKey =
nil;
1499 NSDictionary *overrides =
nil;
1500 NSDictionary *overridesEntry =
nil;
1509 for (equipKeyEnum = [overrides keyEnumerator]; (equipKey = [equipKeyEnum nextObject]); )
1511 overridesEntry = [overrides objectForKey:equipKey];
1513 for (i = 0; i < [arrayToProcess count]; i++)
1515 NSMutableArray *equipArray = [[[arrayToProcess objectAtIndex:i] mutableCopy] autorelease];
1516 id refValue = [equipArray oo_objectAtIndex:EQUIPMENT_KEY_INDEX defaultValue:nil];
1518 if ([equipKey isEqual:refValue])
1520 NSEnumerator *infoKeyEnum =
nil;
1523 for (infoKeyEnum = [overridesEntry keyEnumerator]; (infoKey = [infoKeyEnum nextObject]); )
1526 if ([infoKey isEqualToString:
@"techlevel"])
1527 [equipArray replaceObjectAtIndex:EQUIPMENT_TECH_LEVEL_INDEX withObject:[overridesEntry objectForKey:infoKey]];
1528 else if ([infoKey isEqualToString:
@"price"])
1529 [equipArray replaceObjectAtIndex:EQUIPMENT_PRICE_INDEX withObject:[overridesEntry objectForKey:infoKey]];
1530 else if ([infoKey isEqualToString:
@"short_description"])
1531 [equipArray replaceObjectAtIndex:EQUIPMENT_SHORT_DESC_INDEX withObject:[overridesEntry objectForKey:infoKey]];
1532 else if ([infoKey isEqualToString:
@"name"])
1533 [equipArray replaceObjectAtIndex:EQUIPMENT_SHORT_DESC_INDEX withObject:[overridesEntry objectForKey:infoKey]];
1534 else if ([infoKey isEqualToString:
@"long_description"])
1535 [equipArray replaceObjectAtIndex:EQUIPMENT_LONG_DESC_INDEX withObject:[overridesEntry objectForKey:infoKey]];
1536 else if ([infoKey isEqualToString:
@"description"])
1537 [equipArray replaceObjectAtIndex:EQUIPMENT_LONG_DESC_INDEX withObject:[overridesEntry objectForKey:infoKey]];
1540 NSMutableDictionary *extra =
nil;
1546 extra = [NSMutableDictionary dictionary];
1550 extra = [[equipArray oo_dictionaryAtIndex:EQUIPMENT_EXTRA_INFO_INDEX] mutableCopy];
1553 if ([infoKey isEqualToString:
@"weapon_info"] || [infoKey isEqualToString:
@"script_info"])
1555 NSEnumerator *subEnum =
nil;
1557 NSMutableDictionary *subInfo =
nil;
1558 NSDictionary *subOverrides =
nil;
1560 if (![extra oo_dictionaryForKey:infoKey])
1563 subInfo = [NSMutableDictionary dictionary];
1567 subInfo = [[extra oo_dictionaryForKey:infoKey] mutableCopy];
1569 subOverrides = [overridesEntry oo_dictionaryForKey:infoKey];
1571 for (subEnum = [subOverrides keyEnumerator]; (subKey = [subEnum nextObject]); )
1573 [subInfo setObject:[subOverrides objectForKey:subKey] forKey:subKey];
1575 [extra setObject:[[subInfo copy] autorelease] forKey:infoKey];
1580 [extra setObject:[overridesEntry objectForKey:infoKey] forKey:infoKey];
1582 [equipArray replaceObjectAtIndex:EQUIPMENT_EXTRA_INFO_INDEX withObject:[[extra copy] autorelease]];
1585 [arrayToProcess replaceObjectAtIndex:i withObject:equipArray];
1594+ (void) handleStarNebulaListMerging: (NSMutableArray *)arrayToProcess
1597 NSMutableArray *refArray = [arrayToProcess objectAtIndex:[arrayToProcess count] - 1];
1600 for (i = 0; i < [refArray count]; i++)
1602 for (j = 0; j < [arrayToProcess count] - 1; j++)
1604 NSUInteger
count = [[arrayToProcess oo_arrayAtIndex:j] count];
1605 if (
count == 0)
continue;
1607 for (k = 0; k <
count; k++)
1609 id processValue = [[arrayToProcess oo_arrayAtIndex:j] oo_objectAtIndex:k defaultValue:nil];
1610 id refValue = [refArray oo_objectAtIndex:i defaultValue:nil];
1611 NSString *key1 =
nil;
1612 NSString *key2 =
nil;
1614 if ([processValue isKindOfClass:[NSString
class]])
1616 key1 = processValue;
1618 else if ([processValue isKindOfClass:[NSDictionary
class]])
1620 if (![processValue objectForKey:
@"key"])
1622 key1 = [processValue objectForKey:@"texture"];
1626 key1 = [processValue objectForKey:@"key"];
1629 if (!key1)
continue;
1631 if ([refValue isKindOfClass:[NSString
class]])
1635 else if ([refValue isKindOfClass:[NSDictionary
class]])
1637 if (![refValue objectForKey:
@"key"])
1639 key2 = [refValue objectForKey:@"texture"];
1643 key2 = [refValue objectForKey:@"key"];
1646 if (!key2)
continue;
1648 if ([key1 isEqual:key2])
1650 [[arrayToProcess objectAtIndex:j] replaceObjectAtIndex:k withObject:[refArray objectAtIndex:i]];
1651 [refArray removeObjectAtIndex:i];
1661+ (NSDictionary *) whitelistDictionary
1663 static id whitelistDictionary =
nil;
1665 if (whitelistDictionary ==
nil)
1667 NSString *path = [[[
ResourceManager builtInPath] stringByAppendingPathComponent:@"Config"] stringByAppendingPathComponent:@"whitelist.plist"];
1668 whitelistDictionary = [NSDictionary dictionaryWithContentsOfFile:path];
1669 if (whitelistDictionary ==
nil) whitelistDictionary = [NSNull null];
1671 [whitelistDictionary retain];
1674 if (whitelistDictionary == [NSNull
null])
return nil;
1675 return whitelistDictionary;
1679static NSString *LogClassKeyRoot(NSString *key)
1681 NSRange dot = [key rangeOfString:@"."];
1682 if (dot.location != NSNotFound)
1684 return [key substringToIndex:dot.location];
1693+ (NSDictionary *) logControlDictionary
1697 stringByAppendingPathComponent:@"logcontrol.plist"];
1698 NSMutableDictionary *logControl = [NSMutableDictionary dictionaryWithDictionary:OODictionaryFromFile(path)];
1699 if (logControl ==
nil) logControl = [NSMutableDictionary dictionary];
1702 NSMutableSet *coreRoots = [NSMutableSet set];
1703 NSString *key =
nil;
1706 [coreRoots addObject:LogClassKeyRoot(key)];
1709 NSArray *rootPaths = [
self rootPaths];
1710 NSString *configPath =
nil;
1711 NSDictionary *dict =
nil;
1714 NSEnumerator *pathEnum = [
self pathEnumerator];
1715 while ((path = [pathEnum nextObject]))
1717 if ([rootPaths containsObject:path])
continue;
1719 configPath = [[path stringByAppendingPathComponent:@"Config"]
1720 stringByAppendingPathComponent:@"logcontrol.plist"];
1724 configPath = [path stringByAppendingPathComponent:@"logcontrol.plist"];
1729 if (![coreRoots containsObject:LogClassKeyRoot(key)])
1731 [logControl setObject:[dict objectForKey:key] forKey:key];
1737 pathEnum = [rootPaths objectEnumerator];
1738 while ((path = [pathEnum nextObject]))
1740 configPath = [[path stringByAppendingPathComponent:@"Config"]
1741 stringByAppendingPathComponent:@"logcontrol.plist"];
1745 configPath = [path stringByAppendingPathComponent:@"logcontrol.plist"];
1750 [logControl setObject:[dict objectForKey:key] forKey:key];
1755 dict = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"logging-enable"];
1756 if (dict !=
nil) [logControl addEntriesFromDictionary:dict];
1762+ (NSDictionary *) roleCategoriesDictionary
1764 NSMutableDictionary *roleCategories = [NSMutableDictionary dictionaryWithCapacity:16];
1766 NSString *path =
nil;
1767 NSString *configPath =
nil;
1768 NSDictionary *categories =
nil;
1770 NSEnumerator *pathEnum = [
self pathEnumerator];
1771 while ((path = [pathEnum nextObject]))
1773 if ([
ResourceManager corePlist:
@"role-categories.plist" excludedAt:path])
1778 configPath = [[path stringByAppendingPathComponent:@"Config"]
1779 stringByAppendingPathComponent:@"role-categories.plist"];
1781 if (categories !=
nil)
1795 return [[roleCategories copy] autorelease];
1799+ (void) mergeRoleCategories:(NSDictionary *)catData intoDictionary:(NSMutableDictionary *)categories
1801 NSMutableSet *contents =
nil;
1802 NSArray *catDataEntry =
nil;
1806 contents = [categories objectForKey:key];
1807 if (contents ==
nil)
1809 contents = [NSMutableSet setWithCapacity:16];
1810 [categories setObject:contents forKey:key];
1812 catDataEntry = [catData oo_arrayForKey:key];
1813 OOLog(
@"shipData.load.roleCategories",
@"Adding %ld entries for category %@", (
unsigned long)[catDataEntry
count], key);
1814 [contents addObjectsFromArray:catDataEntry];
1821 OOLog(
@"resourceManager.planetinfo.load",
@"%@",
@"Initialising manager");
1824 NSString *path =
nil;
1825 NSString *configPath =
nil;
1826 NSDictionary *categories =
nil;
1827 NSString *systemKey =
nil;
1829 NSEnumerator *pathEnum = [
self pathEnumerator];
1830 while ((path = [pathEnum nextObject]))
1836 configPath = [[path stringByAppendingPathComponent:@"Config"]
1837 stringByAppendingPathComponent:@"planetinfo.plist"];
1839 if (categories !=
nil)
1843 NSDictionary *values = [categories oo_dictionaryForKey:systemKey defaultValue:nil];
1862 OOLog(
@"resourceManager.planetinfo.load",
@"%@",
@"Caching routes");
1864 OOLog(
@"resourceManager.planetinfo.load",
@"%@",
@"Initialised manager");
1865 return [manager autorelease];
1870+ (NSDictionary *) shaderBindingTypesDictionary
1872 static id shaderBindingTypesDictionary =
nil;
1874 if (shaderBindingTypesDictionary ==
nil)
1876 NSAutoreleasePool *pool = [NSAutoreleasePool new];
1878 NSString *path = [[[
ResourceManager builtInPath] stringByAppendingPathComponent:@"Config"] stringByAppendingPathComponent:@"shader-uniform-bindings.plist"];
1879 NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:path];
1880 NSArray *keys = [dict allKeys];
1883 unsigned changeCount = 0;
1886 NSString *key =
nil;
1889 NSDictionary *value = [dict oo_dictionaryForKey:key];
1890 NSString *inheritKey = [value oo_stringForKey:@"$w299"];
1891 if (inheritKey !=
nil)
1894 NSMutableDictionary *mutableValue = [[value mutableCopy] autorelease];
1895 [mutableValue removeObjectForKey:@"$w300"];
1896 NSDictionary *inherited = [dict oo_dictionaryForKey:inheritKey];
1897 if (inherited !=
nil)
1899 [mutableValue addEntriesFromDictionary:inherited];
1902 [dict setObject:[[mutableValue copy] autorelease] forKey:key];
1905 }
while (changeCount != 0);
1907 shaderBindingTypesDictionary = [dict copy];
1912 return shaderBindingTypesDictionary;
1916+ (NSString *) pathForFileNamed:(NSString *)fileName inFolder:(NSString *)folderName
1918 return [
self pathForFileNamed:fileName inFolder:folderName cache:YES];
1923+ (NSString *) pathForFileNamed:(NSString *)fileName inFolder:(NSString *)folderName cache:(BOOL)useCache
1925 NSString *result =
nil;
1926 NSString *cacheKey =
nil;
1928 NSEnumerator *pathEnum =
nil;
1929 NSString *path =
nil;
1930 NSString *filePath =
nil;
1931 NSFileManager *fmgr =
nil;
1933 if (fileName ==
nil)
return nil;
1937 if (folderName !=
nil) cacheKey = [NSString stringWithFormat:@"%@/%@", folderName, fileName];
1938 else cacheKey = fileName;
1940 if (result !=
nil)
return result;
1944 fmgr = [NSFileManager defaultManager];
1946 for (pathEnum = [[
ResourceManager paths] reverseObjectEnumerator]; (path = [pathEnum nextObject]); )
1948 filePath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
1949 if ([fmgr oo_oxzFileExistsAtPath:filePath])
1955 filePath = [path stringByAppendingPathComponent:fileName];
1956 if ([fmgr oo_oxzFileExistsAtPath:filePath])
1965 OOLog(
@"resourceManager.foundFile",
@"Found %@/%@ at %@", folderName, fileName, filePath);
1977+ (id) retrieveFileNamed:(NSString *)fileName
1978 inFolder:(NSString *)folderName
1979 cache:(NSMutableDictionary **)ioCache
1982 usePathCache:(BOOL)useCache
1985 NSString *path =
nil;
1989 if (key ==
nil) key = [NSString stringWithFormat:@"%@:%@", folderName, fileName];
1990 if (*ioCache !=
nil)
1993 result = [*ioCache objectForKey:key];
1994 if (result)
return result;
1998 path = [
self pathForFileNamed:fileName inFolder:folderName cache:useCache];
1999 if (path !=
nil) result = [[[class alloc] initWithContentsOfFile:path] autorelease];
2001 if (result !=
nil && ioCache != NULL)
2003 if (*ioCache ==
nil) *ioCache = [[NSMutableDictionary alloc] init];
2004 [*ioCache setObject:result forKey:key];
2011+ (
OOMusic *) ooMusicNamed:(NSString *)fileName inFolder:(NSString *)folderName
2013 return [
self retrieveFileNamed:fileName
2016 key:[NSString stringWithFormat:@"OOMusic:%@:%@", folderName, fileName]
2022+ (
OOSound *) ooSoundNamed:(NSString *)fileName inFolder:(NSString *)folderName
2024 return [
self retrieveFileNamed:fileName
2027 key:[NSString stringWithFormat:@"OOSound:%@:%@", folderName, fileName]
2033+ (NSString *) stringFromFilesNamed:(NSString *)fileName inFolder:(NSString *)folderName
2035 return [
self stringFromFilesNamed:fileName inFolder:folderName cache:YES];
2039+ (NSString *) stringFromFilesNamed:(NSString *)fileName inFolder:(NSString *)folderName cache:(BOOL)useCache
2042 NSString *path =
nil;
2043 NSString *key =
nil;
2047 key = [NSString stringWithFormat:@"%@:%@", folderName, fileName];
2051 result = [sStringCache objectForKey:key];
2052 if (result)
return result;
2056 path = [
self pathForFileNamed:fileName inFolder:folderName cache:YES];
2057 if (path !=
nil) result = [NSString stringWithContentsOfUnicodeFile:path];
2059 if (result !=
nil && useCache)
2062 [sStringCache setObject:result forKey:key];
2069+ (NSDictionary *)loadScripts
2071 NSMutableDictionary *loadedScripts =
nil;
2072 NSArray *results =
nil;
2073 NSArray *paths =
nil;
2074 NSEnumerator *pathEnum =
nil;
2075 NSString *path =
nil;
2076 NSEnumerator *scriptEnum =
nil;
2078 NSString *name =
nil;
2079 NSAutoreleasePool *pool =
nil;
2081 OOLog(
@"script.load.world.begin",
@"%@",
@"Loading world scripts...");
2083 loadedScripts = [NSMutableDictionary dictionary];
2085 for (pathEnum = [paths objectEnumerator]; (path = [pathEnum nextObject]); )
2090 if (![
ResourceManager corePlist:
@"world-scripts.plist" excludedAt:path])
2092 pool = [[NSAutoreleasePool alloc] init];
2100 for (scriptEnum = [results objectEnumerator]; (script = [scriptEnum nextObject]); )
2102 name = [script
name];
2103 if (name !=
nil) [loadedScripts setObject:script forKey:name];
2104 else OOLog(
@"script.load.unnamed",
@"Discarding anonymous script %@", script);
2108 @catch (NSException *exception)
2110 OOLog(
@"script.load.exception",
@"***** %s encountered exception %@ (%@) while trying to load script from %@ -- ignoring this location.", __PRETTY_FUNCTION__, [exception name], [exception reason], path);
2120 NSUInteger
count = [loadedScripts count];
2123 NSMutableArray *displayNames =
nil;
2124 NSEnumerator *scriptEnum =
nil;
2126 NSString *displayString =
nil;
2128 displayNames = [NSMutableArray arrayWithCapacity:count];
2130 for (scriptEnum = [loadedScripts objectEnumerator]; (script = [scriptEnum nextObject]); )
2135 displayString = [[displayNames sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] componentsJoinedByString:@"\n "];
2136 OOLog(
@"script.load.world.listAll",
@"Loaded %lu world scripts:\n %@",
count, displayString);
2140 OOLog(
@"script.load.world.listAll",
@"%@",
@"*** No world scripts loaded.");
2144 return loadedScripts;
2148+ (BOOL) writeDiagnosticData:(NSData *)data toFileNamed:(NSString *)name
2150 if (data ==
nil || name ==
nil)
return NO;
2152 NSString *directory = [
self diagnosticFileLocation];
2153 if (directory ==
nil)
return NO;
2155 NSArray *nameComponents = [name componentsSeparatedByString:@"/"];
2156 NSUInteger
count = [nameComponents count];
2159 name = [nameComponents lastObject];
2161 for (NSUInteger i = 0; i <
count - 1; i++)
2163 NSString *component = [nameComponents objectAtIndex:i];
2164 if ([component hasPrefix:
@"."])
2166 component = [@"!" stringByAppendingString:[component substringFromIndex:1]];
2168 directory = [directory stringByAppendingPathComponent:component];
2169 [[NSFileManager defaultManager] oo_createDirectoryAtPath:directory attributes:nil];
2173 return [data writeToFile:[directory stringByAppendingPathComponent:name] atomically:YES];
2177+ (BOOL) writeDiagnosticString:(NSString *)string toFileNamed:(NSString *)name
2179 return [
self writeDiagnosticData:[string dataUsingEncoding:NSUTF8StringEncoding] toFileNamed:name];
2183+ (BOOL) writeDiagnosticPList:(
id)plist toFileNamed:(NSString *)name
2185 NSData *data = [plist oldSchoolPListFormatWithErrorDescription:NULL];
2186 if (data ==
nil) [NSPropertyListSerialization dataFromPropertyList:plist format:NSPropertyListXMLFormat_v1_0 errorDescription:NULL];
2187 if (data ==
nil)
return NO;
2189 return [
self writeDiagnosticData:data toFileNamed:name];
2193+ (NSDictionary *) materialDefaults
2195 return [
self dictionaryFromFilesNamed:@"material-defaults.plist" inFolder:@"Config" andMerge:YES];
2199+ (BOOL)directoryExists:(NSString *)inPath create:(BOOL)inCreate
2201 BOOL exists, directory;
2202 NSFileManager *fmgr = [NSFileManager defaultManager];
2204 exists = [fmgr fileExistsAtPath:inPath isDirectory:&directory];
2206 if (exists && !directory)
2208 OOLog(
@"resourceManager.write.buildPath.failed",
@"Expected %@ to be a folder, but it is a file.", inPath);
2213 if (!inCreate)
return NO;
2214 if (![fmgr oo_createDirectoryAtPath:inPath attributes:
nil])
2216 OOLog(
@"resourceManager.write.buildPath.failed",
@"Could not create folder %@.", inPath);
2225+ (NSString *) diagnosticFileLocation
2233 NSMutableArray *displayPaths =
nil;
2234 NSEnumerator *pathEnum =
nil;
2235 NSString *path =
nil;
2238 displayPaths = [NSMutableArray arrayWithCapacity:[sSearchPaths count]];
2239 for (pathEnum = [
sSearchPaths objectEnumerator]; (path = [pathEnum nextObject]); )
2241 [displayPaths addObject:[[path stringByStandardizingPath] stringByAbbreviatingWithTildeInPath]];
2244 OOLog(
@"searchPaths.dumpAll",
@"Resource paths: %@\n %@",
sUseAddOns, [displayPaths componentsJoinedByString:
@"\n "]);
2251 [sSoundCache release];
2253 [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_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()
OOOXZManager * sharedManager()
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)