Oolite
Loading...
Searching...
No Matches
ResourceManager Class Reference

#include <ResourceManager.h>

+ Inheritance diagram for ResourceManager:
+ Collaboration diagram for ResourceManager:

Class Methods

(void) + reset
 
(void) + resetManifestKnowledgeForOXZManager
 
(NSArray *) + rootPaths
 
(NSArray *) + userRootPaths
 
(NSString *) + builtInPath
 
(NSArray *) + pathsWithAddOns
 
(NSArray *) + paths
 
(NSArray *) + maskUserNameInPathArray:
 
(NSString *) + maskUserName:inPath:
 
(NSString *) + useAddOns
 
(NSArray *) + OXPsWithMessagesFound
 
(void) + setUseAddOns:
 
(void) + addExternalPath:
 
(NSEnumerator *) + pathEnumerator
 
(NSEnumerator *) + reversePathEnumerator
 
(NSDictionary *) + manifestForIdentifier:
 
(BOOL) + checkVersionCompatibility:forOXP:
 
(BOOL) + manifestHasConflicts:logErrors:
 
(BOOL) + manifestHasMissingDependencies:logErrors:
 
(BOOL) + manifest:HasUnmetDependency:logErrors:
 
(BOOL) + matchVersions:withVersion:
 
(void) + handleEquipmentListMerging:forLookupIndex:
 
(void) + handleEquipmentOverrides:
 
(void) + handleStarNebulaListMerging:
 
(NSString *) + errors
 
(NSString *) + pathForFileNamed:inFolder:
 
(NSString *) + pathForFileNamed:inFolder:cache:
 
(BOOL) + corePlist:excludedAt:
 
(NSDictionary *) + dictionaryFromFilesNamed:inFolder:andMerge:
 
(NSDictionary *) + dictionaryFromFilesNamed:inFolder:mergeMode:cache:
 
(NSArray *) + arrayFromFilesNamed:inFolder:andMerge:
 
(NSArray *) + arrayFromFilesNamed:inFolder:andMerge:cache:
 
(NSDictionary *) + whitelistDictionary
 
(NSDictionary *) + shaderBindingTypesDictionary
 
(NSDictionary *) + logControlDictionary
 
(NSDictionary *) + roleCategoriesDictionary
 
(OOSystemDescriptionManager *) + systemDescriptionManager
 
(OOSound *) + ooSoundNamed:inFolder:
 
(OOMusic *) + ooMusicNamed:inFolder:
 
(NSString *) + stringFromFilesNamed:inFolder:
 
(NSString *) + stringFromFilesNamed:inFolder:cache:
 
(NSDictionary *) + loadScripts
 
(BOOL) + writeDiagnosticData:toFileNamed:
 
(BOOL) + writeDiagnosticString:toFileNamed:
 
(BOOL) + writeDiagnosticPList:toFileNamed:
 
(NSString *) + diagnosticFileLocation
 
(NSDictionary *) + materialDefaults
 
(void) + clearCaches
 
(void) + preloadFileLists [implementation]
 
(void) + preloadFileListFromOXZ:forFolders: [implementation]
 
(void) + preloadFileListFromFolder:forFolders: [implementation]
 
(void) + preloadFilePathFor:inFolder:atPath: [implementation]
 
(void) + checkOXPMessagesInPath: [implementation]
 
(void) + checkPotentialPath:path: [implementation]
 
(BOOL) + validateManifest:forOXP: [implementation]
 
(BOOL) + areRequirementsFulfilled:forOXP:andFile: [implementation]
 
(void) + filterSearchPathsForConflicts: [implementation]
 
(BOOL) + filterSearchPathsForRequirements: [implementation]
 
(void) + filterSearchPathsToExcludeScenarioOnlyPaths: [implementation]
 
(void) + filterSearchPathsByScenario: [implementation]
 
(BOOL) + manifestAllowedByScenario: [implementation]
 
(BOOL) + manifestAllowedByScenario:withIdentifier: [implementation]
 
(BOOL) + manifestAllowedByScenario:withTag: [implementation]
 
(void) + addErrorWithKey:param1:param2: [implementation]
 
(BOOL) + checkCacheUpToDateForPaths: [implementation]
 
(static NSString *) + LogClassKeyRoot [implementation]
 
(void) + mergeRoleCategories:intoDictionary: [implementation]
 
(id) + retrieveFileNamed:inFolder:cache:key:class:usePathCache: [implementation]
 
(BOOL) + directoryExists:create: [implementation]
 
(void) + logPaths [implementation]
 

Detailed Description

Definition at line 55 of file ResourceManager.h.

Method Documentation

◆ addErrorWithKey:param1:param2:

+ (void) addErrorWithKey: (NSString *)  descriptionKey
param1: (id)  param1
param2: (id)  param2 
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 104 of file ResourceManager.m.

1130 :(NSString *)descriptionKey param1:(id)param1 param2:(id)param2
1131{
1132 if (descriptionKey != nil)
1133 {
1134 if (sErrors == nil) sErrors = [[NSMutableArray alloc] init];
1135 [sErrors addObject:[NSArray arrayWithObjects:descriptionKey, param1 ?: (id)@"", param2 ?: (id)@"", nil]];
1136 }
1137}
return nil
static NSMutableArray * sErrors

◆ addExternalPath:

+ (void) addExternalPath: (NSString *)  fileName

Definition at line 104 of file ResourceManager.m.

543 :(NSString *)path
544{
545 if (sSearchPaths == nil) sSearchPaths = [[NSMutableArray alloc] init];
546 if (![sSearchPaths containsObject:path])
547 {
548 [sSearchPaths addObject:path];
549
550 if (sExternalPaths == nil) sExternalPaths = [[NSMutableArray alloc] init];
551 [sExternalPaths addObject:path];
552 }
553}
static NSMutableArray * sSearchPaths
static NSMutableArray * sExternalPaths

◆ areRequirementsFulfilled:forOXP:andFile:

+ (BOOL) areRequirementsFulfilled: (NSDictionary*)  requirements
forOXP: (NSString *)  path
andFile: (NSString *)  file 
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 104 of file ResourceManager.m.

739 :(NSDictionary*)requirements forOXP:(NSString *)path andFile:(NSString *)file
740{
741 BOOL OK = YES;
742 NSString *requiredVersion = nil;
743 NSString *maxVersion = nil;
744 unsigned conditionsHandled = 0;
745 static NSArray *ooVersionComponents = nil;
746 NSArray *oxpVersionComponents = nil;
747
748 if (requirements == nil) return YES;
749
750 if (ooVersionComponents == nil)
751 {
752 ooVersionComponents = ComponentsFromVersionString([[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]);
753 [ooVersionComponents retain];
754 }
755
756 // Check "version" (minimum version)
757 if (OK)
758 {
759 // Not oo_stringForKey:, because we need to be able to complain about non-strings.
760 requiredVersion = [requirements objectForKey:@"version"];
761 if (requiredVersion != nil)
762 {
763 ++conditionsHandled;
764 if ([requiredVersion isKindOfClass:[NSString class]])
765 {
766 oxpVersionComponents = ComponentsFromVersionString(requiredVersion);
767 if (NSOrderedAscending == CompareVersions(ooVersionComponents, oxpVersionComponents)) OK = NO;
768 }
769 else
770 {
771 OOLog(@"requirements.wrongType", @"Expected %@ entry \"%@\" to be string, but got %@ in OXP %@.", file, @"version", [requirements class], [path lastPathComponent]);
772 OK = NO;
773 }
774 }
775 }
776
777 // Check "max_version" (minimum max_version)
778 if (OK)
779 {
780 // Not oo_stringForKey:, because we need to be able to complain about non-strings.
781 maxVersion = [requirements objectForKey:@"max_version"];
782 if (maxVersion != nil)
783 {
784 ++conditionsHandled;
785 if ([maxVersion isKindOfClass:[NSString class]])
786 {
787 oxpVersionComponents = ComponentsFromVersionString(maxVersion);
788 if (NSOrderedDescending == CompareVersions(ooVersionComponents, oxpVersionComponents)) OK = NO;
789 }
790 else
791 {
792 OOLog(@"requirements.wrongType", @"Expected %@ entry \"%@\" to be string, but got %@ in OXP %@.", file, @"max_version", [requirements class], [path lastPathComponent]);
793 OK = NO;
794 }
795 }
796 }
797
798 if (OK && conditionsHandled < [requirements count])
799 {
800 // There are unknown requirement keys - don't support. NOTE: this check was not made pre 1.69!
801 OOLog(@"requirements.unknown", @"requires.plist for OXP %@ contains unknown keys, rejecting.", [path lastPathComponent]);
802 OK = NO;
803 }
804
805 return OK;
806}
#define OOLog(class, format,...)
Definition OOLogging.h:88
unsigned count
NSArray * ComponentsFromVersionString(NSString *string)
NSComparisonResult CompareVersions(NSArray *version1, NSArray *version2)

◆ arrayFromFilesNamed:inFolder:andMerge:

+ (NSArray *) arrayFromFilesNamed: (NSString *)  fileName
inFolder: (NSString *)  folderName
andMerge: (BOOL)  mergeFiles 

Definition at line 104 of file ResourceManager.m.

1357 :(NSString *)fileName inFolder:(NSString *)folderName andMerge:(BOOL) mergeFiles
1358{
1359 return [self arrayFromFilesNamed:fileName inFolder:folderName andMerge:mergeFiles cache:YES];
1360}

◆ arrayFromFilesNamed:inFolder:andMerge:cache:

+ (NSArray *) arrayFromFilesNamed: (NSString *)  fileName
inFolder: (NSString *)  folderName
andMerge: (BOOL)  mergeFiles
cache: (BOOL)  useCache 

Definition at line 104 of file ResourceManager.m.

1363 :(NSString *)fileName inFolder:(NSString *)folderName andMerge:(BOOL) mergeFiles cache:(BOOL)useCache
1364{
1365 id result = nil;
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;
1374
1375 if (fileName == nil) return nil;
1376
1377 if (useCache)
1378 {
1379 cacheKey = [NSString stringWithFormat:@"%@%@ merge:%@", (folderName != nil) ? [folderName stringByAppendingString:@"/"] : (NSString *)@"", fileName, mergeFiles ? @"yes" : @"no"];
1380 result = [cache objectForKey:cacheKey inCache:@"arrays"];
1381 if (result != nil) return result;
1382 }
1383
1384 if (!mergeFiles)
1385 {
1386 // Find "last" matching array
1387 for (enumerator = [ResourceManager reversePathEnumerator]; (path = [enumerator nextObject]); )
1388 {
1389 if (folderName != nil)
1390 {
1391 arrayPath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
1392 arrayNonEditable = OOArrayFromFile(arrayPath);
1393 if (arrayNonEditable != nil) break;
1394 }
1395 arrayPath = [path stringByAppendingPathComponent:fileName];
1396 arrayNonEditable = OOArrayFromFile(arrayPath);
1397 if (arrayNonEditable != nil) break;
1398 }
1399 result = arrayNonEditable;
1400 }
1401 else
1402 {
1403 // Find all matching arrays
1404 results = [NSMutableArray array];
1405 for (enumerator = [ResourceManager pathEnumerator]; (path = [enumerator nextObject]); )
1406 {
1407 if ([ResourceManager corePlist:fileName excludedAt:path])
1408 {
1409 continue;
1410 }
1411
1412 arrayPath = [path stringByAppendingPathComponent:fileName];
1413 array = [[OOArrayFromFile(arrayPath) mutableCopy] autorelease];
1414 if (array != nil) [results addObject:array];
1415
1416 // Special handling for arrays merging. Currently, only equipment.plist, nebulatextures.plist and
1417 // startextures.plist gets their objects merged.
1418 // A lookup index is required. For the equipment.plist items, this is the index corresponding to the
1419 // EQ_* string, which describes the role of an equipment item and is unique.
1420 // For nebula and star textures, this is the texture filename, although it can be overridden with a
1421 // "key" property
1422 if ([array count] != 0 && ([[fileName lowercaseString] isEqualToString:@"nebulatextures.plist"] ||
1423 [[fileName lowercaseString] isEqualToString:@"startextures.plist"]))
1424 [self handleStarNebulaListMerging:results];
1425
1426 if ([array count] != 0 && [[array objectAtIndex:0] isKindOfClass:[NSArray class]])
1427 {
1428 if ([[fileName lowercaseString] isEqualToString:@"equipment.plist"])
1429 [self handleEquipmentListMerging:results forLookupIndex:3]; // Index 3 is the role string (EQ_*).
1430 }
1431 if (folderName != nil)
1432 {
1433 arrayPath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
1434 array = [[OOArrayFromFile(arrayPath) mutableCopy] autorelease];
1435 if (array != nil) [results addObject:array];
1436
1437 if ([array count] != 0 && ([[fileName lowercaseString] isEqualToString:@"nebulatextures.plist"] ||
1438 [[fileName lowercaseString] isEqualToString:@"startextures.plist"]))
1439 [self handleStarNebulaListMerging:results];
1440
1441 if ([array count] != 0 && [[array objectAtIndex:0] isKindOfClass:[NSArray class]])
1442 {
1443 if ([[fileName lowercaseString] isEqualToString:@"equipment.plist"])
1444 [self handleEquipmentListMerging:results forLookupIndex:3]; // Index 3 is the role string (EQ_*).
1445 }
1446 }
1447 }
1448
1449 if ([results count] == 0) return nil;
1450
1451 // Merge result
1452 result = [NSMutableArray array];
1453
1454 for (enumerator = [results objectEnumerator]; (array = [enumerator nextObject]); )
1455 {
1456 [result addObjectsFromArray:array];
1457 }
1458 // if we're doing equipment.plist, do equipment overrides now, while the array is still mutable
1459 if ([[fileName lowercaseString] isEqualToString:@"equipment.plist"])
1460 {
1461 [self handleEquipmentOverrides:result];
1462 }
1463 result = [[result copy] autorelease]; // Make immutable
1464 }
1465
1466 if (useCache && result != nil) [cache setObject:result forKey:cacheKey inCache:@"arrays"];
1467
1468 return [NSArray arrayWithArray:result];
1469}
NSArray * OOArrayFromFile(NSString *path)
return self
void setObject:forKey:inCache:(id inElement,[forKey] NSString *inKey,[inCache] NSString *inCacheKey)
id objectForKey:inCache:(NSString *inKey,[inCache] NSString *inCacheKey)
OOCacheManager * sharedCache()
NSEnumerator * reversePathEnumerator()
NSEnumerator * pathEnumerator()

◆ builtInPath

+ (NSString *) builtInPath

Definition at line 104 of file ResourceManager.m.

204{
205#if OOLITE_WINDOWS
206 /* [[NSBundle mainBundle] resourcePath] causes complaints under Windows,
207 because we don't have a properly-built bundle.
208 */
209 return @"Resources";
210#else
211 return [[NSBundle mainBundle] resourcePath];
212#endif
213}

Referenced by LoadExplicitSettings().

+ Here is the caller graph for this function:

◆ checkCacheUpToDateForPaths:

+ (BOOL) checkCacheUpToDateForPaths: (NSArray *)  searchPaths
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 104 of file ResourceManager.m.

1140 :(NSArray *)searchPaths
1141{
1142 /* Check if caches are up to date.
1143 The strategy is to use a two-entry cache. One entry is an array
1144 containing the search paths, the other an array of modification dates
1145 (in the same order). If either fails to match the correct settings,
1146 we delete both.
1147 */
1149 NSFileManager *fmgr = [NSFileManager defaultManager];
1150 BOOL upToDate = YES;
1151 id oldPaths = nil;
1152 NSMutableArray *modDates = nil;
1153 NSString *path = nil;
1154 id modDate = nil;
1155
1156 if (EXPECT_NOT([[NSUserDefaults standardUserDefaults] boolForKey:@"always-flush-cache"]))
1157 {
1158 OOLog(kOOLogCacheExplicitFlush, @"%@", @"Cache explicitly flushed with always-flush-cache preference. Rebuilding from scratch.");
1159 upToDate = NO;
1160 }
1161 else if ([MyOpenGLView pollShiftKey])
1162 {
1163 OOLog(kOOLogCacheExplicitFlush, @"%@", @"Cache explicitly flushed with shift key. Rebuilding from scratch.");
1164 upToDate = NO;
1165 }
1166
1167 oldPaths = [cacheMgr objectForKey:kOOCacheKeySearchPaths inCache:kOOCacheSearchPathModDates];
1168 if (upToDate && ![oldPaths isEqual:searchPaths])
1169 {
1170 // OXPs added/removed
1171 if (oldPaths != nil) OOLog(kOOLogCacheStalePaths, @"%@", @"Cache is stale (search paths have changed). Rebuilding from scratch.");
1172 upToDate = NO;
1173 }
1174
1175 // Build modification date list. (We need this regardless of whether the search paths matched.)
1176
1177 modDates = [NSMutableArray arrayWithCapacity:[searchPaths count]];
1178 foreach (path, searchPaths)
1179 {
1180 modDate = [[fmgr oo_fileAttributesAtPath:path traverseLink:YES] objectForKey:NSFileModificationDate];
1181 if (modDate != nil)
1182 {
1183 // Converts to double because I'm not sure the cache can deal with dates under GNUstep.
1184 modDate = [NSNumber numberWithDouble:[modDate timeIntervalSince1970]];
1185 [modDates addObject:modDate];
1186 }
1187 }
1188
1189 if (upToDate && ![[cacheMgr objectForKey:kOOCacheKeyModificationDates inCache:kOOCacheSearchPathModDates] isEqual:modDates])
1190 {
1191 OOLog(kOOLogCacheStaleDates, @"%@", @"Cache is stale (modification dates have changed). Rebuilding from scratch.");
1192 upToDate = NO;
1193 }
1194
1195 if (!upToDate)
1196 {
1197 [cacheMgr clearAllCaches];
1198 [cacheMgr setObject:searchPaths forKey:kOOCacheKeySearchPaths inCache:kOOCacheSearchPathModDates];
1199 [cacheMgr setObject:modDates forKey:kOOCacheKeyModificationDates inCache:kOOCacheSearchPathModDates];
1200 }
1201 else OOLog(kOOLogCacheUpToDate, @"%@", @"Data cache is up to date.");
1202
1203 return upToDate;
1204}
#define EXPECT_NOT(x)
static NSString *const kOOLogCacheUpToDate
static NSString *const kOOLogCacheStalePaths
static NSString *const kOOCacheSearchPathModDates
static NSString *const kOOLogCacheStaleDates
static NSString *const kOOLogCacheExplicitFlush
static NSString *const kOOCacheKeyModificationDates

◆ checkOXPMessagesInPath:

+ (void) checkOXPMessagesInPath: (NSString *)  path
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 104 of file ResourceManager.m.

580 :(NSString *)path
581{
582 NSArray *OXPMessageArray = OOArrayFromFile([path stringByAppendingPathComponent:@"OXPMessages.plist"]);
583
584 if ([OXPMessageArray count] > 0)
585 {
586 unsigned i;
587 for (i = 0; i < [OXPMessageArray count]; i++)
588 {
589 NSString *oxpMessage = [OXPMessageArray oo_stringAtIndex:i];
590 if (oxpMessage)
591 {
592 OOLog(@"oxp.message", @"%@: %@", path, oxpMessage);
593 }
594 }
595 if (sOXPsWithMessagesFound == nil) sOXPsWithMessagesFound = [[NSMutableArray alloc] init];
596 [sOXPsWithMessagesFound addObject:[path lastPathComponent]];
597 }
598}
static NSMutableArray * sOXPsWithMessagesFound

◆ checkPotentialPath:path:

+ (void) checkPotentialPath: (NSString *) 
path: (NSMutableArray *)  searchPaths 
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 104 of file ResourceManager.m.

602 :(NSString *)path :(NSMutableArray *)searchPaths
603{
604 NSDictionary *requirements = nil;
605 NSDictionary *manifest = nil;
606 BOOL requirementsMet = YES;
607
608 if (![[[path pathExtension] lowercaseString] isEqualToString:@"oxz"])
609 {
610 // OXZ format ignores requires.plist
611 requirements = OODictionaryFromFile([path stringByAppendingPathComponent:@"requires.plist"]);
612 requirementsMet = [self areRequirementsFulfilled:requirements forOXP:path andFile:@"requires.plist"];
613 }
614 if (!requirementsMet)
615 {
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];
619 return;
620 }
621
622 manifest = OODictionaryFromFile([path stringByAppendingPathComponent:@"manifest.plist"]);
623 if (manifest == nil)
624 {
625 if ([[[path pathExtension] lowercaseString] isEqualToString:@"oxz"])
626 {
627 OOLog(@"oxp.noManifest", @"OXZ %@ has no manifest.plist", path);
628 [self addErrorWithKey:@"oxz-lacks-manifest" param1:[path lastPathComponent] param2:nil];
629 return;
630 }
631 else
632 {
633 if ([[[path pathExtension] lowercaseString] isEqualToString:@"oxp"])
634 {
635 OOStandardsError([NSString stringWithFormat:@"OXP %@ has no manifest.plist", path]);
636 if (OOEnforceStandards())
637 {
638 [self addErrorWithKey:@"oxp-lacks-manifest" param1:[path lastPathComponent] param2:nil];
639 return;
640 }
641 }
642 // make up a basic manifest in relaxed mode or for base folders
643 manifest = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"__oolite.tmp.%@",path],kOOManifestIdentifier,@"1",kOOManifestVersion,@"OXP without manifest",kOOManifestTitle,@"1",kOOManifestRequiredOoliteVersion,nil];
644 }
645 }
646
647 requirementsMet = [self validateManifest:manifest forOXP:path];
648
649
650 if (requirementsMet)
651 {
652 [searchPaths addObject:path];
653 }
654}
BOOL OOEnforceStandards(void)
void OOStandardsError(NSString *message)
NSDictionary * OODictionaryFromFile(NSString *path)

◆ checkVersionCompatibility:forOXP:

+ (BOOL) checkVersionCompatibility: (NSDictionary *)  manifest
forOXP: (NSString *)  title 

Definition at line 104 of file ResourceManager.m.

723 :(NSDictionary *)manifest forOXP:(NSString *)title
724{
725 NSString *required = [manifest oo_stringForKey:kOOManifestRequiredOoliteVersion defaultValue:nil];
726 NSString *maxRequired = [manifest oo_stringForKey:kOOManifestMaximumOoliteVersion defaultValue:nil];
727 // ignore empty max version string rather than treating as "version 0"
728 if (maxRequired == nil || [maxRequired length] == 0)
729 {
730 return [self areRequirementsFulfilled:[NSDictionary dictionaryWithObjectsAndKeys:required, @"version", nil] forOXP:title andFile:@"manifest.plist"];
731 }
732 else
733 {
734 return [self areRequirementsFulfilled:[NSDictionary dictionaryWithObjectsAndKeys:required, @"version", maxRequired, @"max_version", nil] forOXP:title andFile:@"manifest.plist"];
735 }
736}

◆ clearCaches

+ (void) clearCaches

Definition at line 1694 of file ResourceManager.m.

2256{
2257 [sSoundCache release];
2258 sSoundCache = nil;
2259 [sStringCache release];
2260 sStringCache = nil;
2261}
static NSMutableDictionary * sSoundCache
static NSMutableDictionary * sStringCache

◆ corePlist:excludedAt:

+ (BOOL) corePlist: (NSString *)  fileName
excludedAt: (NSString *)  path 

Definition at line 104 of file ResourceManager.m.

1215 :(NSString *)fileName excludedAt:(NSString *)path
1216{
1217 if (![path isEqualToString:[self builtInPath]])
1218 {
1219 // non-core paths always okay
1220 return NO;
1221 }
1222 NSString *uaoBit = nil;
1223 foreach (uaoBit, sUseAddOnsParts)
1224 {
1225 if ([uaoBit hasPrefix:SCENARIO_OXP_DEFINITION_NOPLIST])
1226 {
1227 NSString *plist = [uaoBit substringFromIndex:[SCENARIO_OXP_DEFINITION_NOPLIST length]];
1228 if ([plist isEqualToString:fileName])
1229 {
1230 // this core plist file should not be loaded at all
1231 return YES;
1232 }
1233 }
1234 }
1235 // then not excluded
1236 return NO;
1237}
#define SCENARIO_OXP_DEFINITION_NOPLIST
static NSArray * sUseAddOnsParts
NSString * builtInPath()

◆ diagnosticFileLocation

+ (NSString *) diagnosticFileLocation

Definition at line 1694 of file ResourceManager.m.

2233{
2235}
NSString * OOLogHandlerGetLogBasePath(void)

◆ dictionaryFromFilesNamed:inFolder:andMerge:

+ (NSDictionary *) dictionaryFromFilesNamed: (NSString *)  fileName
inFolder: (NSString *)  folderName
andMerge: (BOOL)  mergeFiles 

Definition at line 104 of file ResourceManager.m.

1240 :(NSString *)fileName
1241 inFolder:(NSString *)folderName
1242 andMerge:(BOOL) mergeFiles
1243{
1244 return [ResourceManager dictionaryFromFilesNamed:fileName inFolder:folderName mergeMode:mergeFiles ? MERGE_BASIC : MERGE_NONE cache:YES];
1245}

Referenced by GuiDisplayGen::addLongText:startingAtRow:align:, CompileSystemDescriptions(), ExportSystemDescriptions(), GlobalAutoAIForRole(), HeadUpDisplay::InitTextEngine(void), and ReportJSError().

+ Here is the caller graph for this function:

◆ dictionaryFromFilesNamed:inFolder:mergeMode:cache:

+ (NSDictionary *) dictionaryFromFilesNamed: (NSString *)  fileName
inFolder: (NSString *)  folderName
mergeMode: (OOResourceMergeMode mergeMode
cache: (BOOL)  useCache 

Definition at line 104 of file ResourceManager.m.

1248 :(NSString *)fileName
1249 inFolder:(NSString *)folderName
1250 mergeMode:(OOResourceMergeMode)mergeMode
1251 cache:(BOOL)cache
1252{
1253 id result = nil;
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;
1262
1263 if (fileName == nil) return nil;
1264
1265 switch (mergeMode)
1266 {
1267 case MERGE_NONE:
1268 mergeType = @"none";
1269 break;
1270
1271 case MERGE_BASIC:
1272 mergeType = @"basic";
1273 break;
1274
1275 case MERGE_SMART:
1276 mergeType = @"smart";
1277 break;
1278 }
1279 if (mergeType == nil)
1280 {
1281 OOLog(kOOLogParameterError, @"Unknown dictionary merge mode %u for %@. (This is an internal programming error, please report it.)", mergeMode, fileName);
1282 return nil;
1283 }
1284
1285 if (cache)
1286 {
1287
1288 if (folderName != nil)
1289 {
1290 cacheKey = [NSString stringWithFormat:@"%@/%@ merge:%@", folderName, fileName, mergeType];
1291 }
1292 else
1293 {
1294 cacheKey = [NSString stringWithFormat:@"%@ merge:%@", fileName, mergeType];
1295 }
1296 result = [cacheMgr objectForKey:cacheKey inCache:@"dictionaries"];
1297 if (result != nil) return result;
1298 }
1299
1300 if (mergeMode == MERGE_NONE)
1301 {
1302 // Find "last" matching dictionary
1303 for (enumerator = [ResourceManager reversePathEnumerator]; (path = [enumerator nextObject]); )
1304 {
1305 if (folderName != nil)
1306 {
1307 dictPath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
1308 dict = OODictionaryFromFile(dictPath);
1309 if (dict != nil) break;
1310 }
1311 dictPath = [path stringByAppendingPathComponent:fileName];
1312 dict = OODictionaryFromFile(dictPath);
1313 if (dict != nil) break;
1314 }
1315 result = dict;
1316 }
1317 else
1318 {
1319 // Find all matching dictionaries
1320 results = [NSMutableArray array];
1321 for (enumerator = [ResourceManager pathEnumerator]; (path = [enumerator nextObject]); )
1322 {
1323 if ([ResourceManager corePlist:fileName excludedAt:path])
1324 {
1325 continue;
1326 }
1327 dictPath = [path stringByAppendingPathComponent:fileName];
1328 dict = OODictionaryFromFile(dictPath);
1329 if (dict != nil) [results addObject:dict];
1330 if (folderName != nil)
1331 {
1332 dictPath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
1333 dict = OODictionaryFromFile(dictPath);
1334 if (dict != nil) [results addObject:dict];
1335 }
1336 }
1337
1338 if ([results count] == 0) return nil;
1339
1340 // Merge result
1341 result = [NSMutableDictionary dictionary];
1342
1343 for (enumerator = [results objectEnumerator]; (dict = [enumerator nextObject]); )
1344 {
1345 if (mergeMode == MERGE_SMART) [result mergeEntriesFromDictionary:dict];
1346 else [result addEntriesFromDictionary:dict];
1347 }
1348 result = [[result copy] autorelease]; // Make immutable
1349 }
1350
1351 if (cache && result != nil) [cacheMgr setObject:result forKey:cacheKey inCache:@"dictionaries"];
1352
1353 return result;
1354}
NSString *const kOOLogParameterError
Definition OOLogging.m:647
OOResourceMergeMode
@ MERGE_SMART
@ MERGE_NONE
@ MERGE_BASIC

Referenced by NSObject(OODebugPlugInController)::setUpDebugger.

+ Here is the caller graph for this function:

◆ directoryExists:create:

+ (BOOL) directoryExists: (NSString *)  inPath
create: (BOOL)  inCreate 
implementation

Definition at line 1694 of file ResourceManager.m.

2206 :(NSString *)inPath create:(BOOL)inCreate
2207{
2208 BOOL exists, directory;
2209 NSFileManager *fmgr = [NSFileManager defaultManager];
2210
2211 exists = [fmgr fileExistsAtPath:inPath isDirectory:&directory];
2212
2213 if (exists && !directory)
2214 {
2215 OOLog(@"resourceManager.write.buildPath.failed", @"Expected %@ to be a folder, but it is a file.", inPath);
2216 return NO;
2217 }
2218 if (!exists)
2219 {
2220 if (!inCreate) return NO;
2221 if (![fmgr oo_createDirectoryAtPath:inPath attributes:nil])
2222 {
2223 OOLog(@"resourceManager.write.buildPath.failed", @"Could not create folder %@.", inPath);
2224 return NO;
2225 }
2226 }
2227
2228 return YES;
2229}

◆ errors

+ (NSString *) errors

Definition at line 104 of file ResourceManager.m.

134{
135 NSArray *error = nil;
136 NSUInteger i, count;
137 NSMutableArray *result = nil;
138 NSString *errStr = nil;
139
140 count = [sErrors count];
141 if (count == 0) return nil;
142
143 // Expand error messages. This is deferred for localizability.
144 result = [NSMutableArray arrayWithCapacity:count];
145 for (i = 0; i != count; ++i)
146 {
147 error = [sErrors objectAtIndex:i];
148 errStr = [UNIVERSE descriptionForKey:[error oo_stringAtIndex:0]];
149 if (errStr != nil)
150 {
151 errStr = [NSString stringWithFormat:errStr, [error objectAtIndex:1], [error objectAtIndex:2]];
152 [result addObject:errStr];
153 }
154 }
155
156 [sErrors release];
157 sErrors = nil;
158
159 return [result componentsJoinedByString:@"\n"];
160}

◆ filterSearchPathsByScenario:

+ (void) filterSearchPathsByScenario: (NSMutableArray *)  searchPaths
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 104 of file ResourceManager.m.

1020 :(NSMutableArray *)searchPaths
1021{
1022 NSDictionary *manifest = nil;
1023 NSString *identifier = nil;
1024 NSArray *identifiers = [sOXPManifests allKeys];
1025
1026 // take a copy because we'll mutate the original
1027 // foreach identified add-on
1028 foreach (identifier, identifiers)
1029 {
1030 manifest = [sOXPManifests objectForKey:identifier];
1031 if (manifest != nil)
1032 {
1033 if (![ResourceManager manifestAllowedByScenario:manifest])
1034 {
1035 // then we don't need this one
1036 [searchPaths removeObject:[manifest oo_stringForKey:kOOManifestFilePath]];
1037 [sOXPManifests removeObjectForKey:identifier];
1038 }
1039 }
1040 }
1041}

◆ filterSearchPathsForConflicts:

+ (void) filterSearchPathsForConflicts: (NSMutableArray *)  searchPaths
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 104 of file ResourceManager.m.

845 :(NSMutableArray *)searchPaths
846{
847 NSDictionary *manifest = nil;
848 NSString *identifier = nil;
849 NSArray *identifiers = [sOXPManifests allKeys];
850
851 // take a copy because we'll mutate the original
852 // foreach identified add-on
853 foreach (identifier, identifiers)
854 {
855 manifest = [sOXPManifests objectForKey:identifier];
856 if (manifest != nil)
857 {
858 if ([self manifestHasConflicts:manifest logErrors:YES])
859 {
860 // then we have a conflict, so remove this path
861 [searchPaths removeObject:[manifest oo_stringForKey:kOOManifestFilePath]];
862 [sOXPManifests removeObjectForKey:identifier];
863 }
864 }
865 }
866}

◆ filterSearchPathsForRequirements:

+ (BOOL) filterSearchPathsForRequirements: (NSMutableArray *)  searchPaths
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 104 of file ResourceManager.m.

938 :(NSMutableArray *)searchPaths
939{
940 NSDictionary *manifest = nil;
941 NSString *identifier = nil;
942 NSArray *identifiers = [sOXPManifests allKeys];
943
944 sAllMet = YES;
945
946 // take a copy because we'll mutate the original
947 // foreach identified add-on
948 foreach (identifier, identifiers)
949 {
950 manifest = [sOXPManifests objectForKey:identifier];
951 if (manifest != nil)
952 {
953 if ([self manifestHasMissingDependencies:manifest logErrors:YES])
954 {
955 // then we have a missing requirement, so remove this path
956 [searchPaths removeObject:[manifest oo_stringForKey:kOOManifestFilePath]];
957 [sOXPManifests removeObjectForKey:identifier];
958 sAllMet = NO;
959 }
960 }
961 }
962
963 return sAllMet;
964}
static BOOL sAllMet

◆ filterSearchPathsToExcludeScenarioOnlyPaths:

+ (void) filterSearchPathsToExcludeScenarioOnlyPaths: (NSMutableArray *)  searchPaths
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 104 of file ResourceManager.m.

996 :(NSMutableArray *)searchPaths
997{
998 NSDictionary *manifest = nil;
999 NSString *identifier = nil;
1000 NSArray *identifiers = [sOXPManifests allKeys];
1001
1002 // take a copy because we'll mutate the original
1003 // foreach identified add-on
1004 foreach (identifier, identifiers)
1005 {
1006 manifest = [sOXPManifests objectForKey:identifier];
1007 if (manifest != nil)
1008 {
1009 if ([[manifest oo_arrayForKey:kOOManifestTags] containsObject:kOOManifestTagScenarioOnly])
1010 {
1011 [searchPaths removeObject:[manifest oo_stringForKey:kOOManifestFilePath]];
1012 [sOXPManifests removeObjectForKey:identifier];
1013 }
1014 }
1015 }
1016}
static NSString *const kOOManifestTags
static NSString *const kOOManifestTagScenarioOnly

◆ handleEquipmentListMerging:forLookupIndex:

+ (void) handleEquipmentListMerging: (NSMutableArray *)  arrayToProcess
forLookupIndex: (unsigned)  lookupIndex 

Definition at line 104 of file ResourceManager.m.

1475 : (NSMutableArray *)arrayToProcess forLookupIndex:(unsigned)lookupIndex
1476{
1477 NSUInteger i,j,k;
1478 NSMutableArray *refArray = [arrayToProcess objectAtIndex:[arrayToProcess count] - 1];
1479
1480 // Any change to refArray will directly modify arrayToProcess.
1481
1482 for (i = 0; i < [refArray count]; i++)
1483 {
1484 for (j = 0; j < [arrayToProcess count] - 1; j++)
1485 {
1486 NSUInteger count = [[arrayToProcess oo_arrayAtIndex:j] count];
1487 if (count == 0) continue;
1488
1489 for (k=0; k < count; k++)
1490 {
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];
1493
1494 if ([processValue isEqual:refValue])
1495 {
1496 [[arrayToProcess objectAtIndex:j] replaceObjectAtIndex:k withObject:[refArray objectAtIndex:i]];
1497 [refArray removeObjectAtIndex:i];
1498 }
1499 }
1500 }
1501 }
1502 // arrayToProcess has been processed at this point. Any necessary merging has been done.
1503}

◆ handleEquipmentOverrides:

+ (void) handleEquipmentOverrides: (NSMutableArray *)  arrayToProcess

Definition at line 104 of file ResourceManager.m.

1510 : (NSMutableArray *)arrayToProcess
1511{
1512 NSEnumerator *equipKeyEnum = nil;
1513 NSString *equipKey = nil;
1514 NSDictionary *overrides = nil;
1515 NSDictionary *overridesEntry = nil;
1516 int i;
1517
1518 overrides = [ResourceManager dictionaryFromFilesNamed:@"equipment-overrides.plist"
1519 inFolder:@"Config"
1520 mergeMode:MERGE_SMART
1521 cache:NO];
1522
1523 // cycle through all the equipment keys found in override files
1524 for (equipKeyEnum = [overrides keyEnumerator]; (equipKey = [equipKeyEnum nextObject]); )
1525 {
1526 overridesEntry = [overrides objectForKey:equipKey];
1527 // loop through our data array to find a match
1528 for (i = 0; i < [arrayToProcess count]; i++)
1529 {
1530 NSMutableArray *equipArray = [[[arrayToProcess objectAtIndex:i] mutableCopy] autorelease];
1531 id refValue = [equipArray oo_objectAtIndex:EQUIPMENT_KEY_INDEX defaultValue:nil];
1532 // does the overridden equipment item exist in the equipment array? if so, get working
1533 if ([equipKey isEqual:refValue])
1534 {
1535 NSEnumerator *infoKeyEnum = nil;
1536 NSString *infoKey;
1537 // cycle through all the properties found for this equipment key in the overrides file
1538 for (infoKeyEnum = [overridesEntry keyEnumerator]; (infoKey = [infoKeyEnum nextObject]); )
1539 {
1540 // special cases for the array items that don't have a direct keyname
1541 if ([infoKey isEqualToString:@"techlevel"])
1542 [equipArray replaceObjectAtIndex:EQUIPMENT_TECH_LEVEL_INDEX withObject:[overridesEntry objectForKey:infoKey]];
1543 else if ([infoKey isEqualToString:@"price"])
1544 [equipArray replaceObjectAtIndex:EQUIPMENT_PRICE_INDEX withObject:[overridesEntry objectForKey:infoKey]];
1545 else if ([infoKey isEqualToString:@"short_description"])
1546 [equipArray replaceObjectAtIndex:EQUIPMENT_SHORT_DESC_INDEX withObject:[overridesEntry objectForKey:infoKey]];
1547 else if ([infoKey isEqualToString:@"name"])
1548 [equipArray replaceObjectAtIndex:EQUIPMENT_SHORT_DESC_INDEX withObject:[overridesEntry objectForKey:infoKey]];
1549 else if ([infoKey isEqualToString:@"long_description"])
1550 [equipArray replaceObjectAtIndex:EQUIPMENT_LONG_DESC_INDEX withObject:[overridesEntry objectForKey:infoKey]];
1551 else if ([infoKey isEqualToString:@"description"])
1552 [equipArray replaceObjectAtIndex:EQUIPMENT_LONG_DESC_INDEX withObject:[overridesEntry objectForKey:infoKey]];
1553 else
1554 {
1555 NSMutableDictionary *extra = nil;
1556 // for everything else
1557 // do we actually have an extras dictionary?
1558 if (![equipArray oo_dictionaryAtIndex:EQUIPMENT_EXTRA_INFO_INDEX])
1559 {
1560 // if not, create a blank one we can add to
1561 extra = [NSMutableDictionary dictionary];
1562 }
1563 else
1564 {
1565 extra = [[equipArray oo_dictionaryAtIndex:EQUIPMENT_EXTRA_INFO_INDEX] mutableCopy];
1566 }
1567 // special case for weapon_info && script_info, which are child dictionaries
1568 if ([infoKey isEqualToString:@"weapon_info"] || [infoKey isEqualToString:@"script_info"])
1569 {
1570 NSEnumerator *subEnum = nil;
1571 NSString *subKey;
1572 NSMutableDictionary *subInfo = nil;
1573 NSDictionary *subOverrides = nil;
1574 // do we actually have a weapon_info/script_info dictionary?
1575 if (![extra oo_dictionaryForKey:infoKey])
1576 {
1577 // if not, create a blank dictionary we can add to
1578 subInfo = [NSMutableDictionary dictionary];
1579 }
1580 else
1581 {
1582 subInfo = [[extra oo_dictionaryForKey:infoKey] mutableCopy];
1583 }
1584 subOverrides = [overridesEntry oo_dictionaryForKey:infoKey];
1585 // cycle through all the sub keys found in the overrides file for this equipment key item
1586 for (subEnum = [subOverrides keyEnumerator]; (subKey = [subEnum nextObject]); )
1587 {
1588 [subInfo setObject:[subOverrides objectForKey:subKey] forKey:subKey];
1589 }
1590 [extra setObject:[[subInfo copy] autorelease] forKey:infoKey];
1591 }
1592 else
1593 {
1594 // for all other keys in the extras dictionary
1595 [extra setObject:[overridesEntry objectForKey:infoKey] forKey:infoKey];
1596 }
1597 [equipArray replaceObjectAtIndex:EQUIPMENT_EXTRA_INFO_INDEX withObject:[[extra copy] autorelease]];
1598 }
1599 }
1600 [arrayToProcess replaceObjectAtIndex:i withObject:equipArray];
1601 }
1602 }
1603 }
1604}
@ EQUIPMENT_SHORT_DESC_INDEX
Definition Universe.h:81
@ EQUIPMENT_LONG_DESC_INDEX
Definition Universe.h:83
@ EQUIPMENT_TECH_LEVEL_INDEX
Definition Universe.h:79
@ EQUIPMENT_PRICE_INDEX
Definition Universe.h:80
@ EQUIPMENT_EXTRA_INFO_INDEX
Definition Universe.h:84
NSDictionary * dictionaryFromFilesNamed:inFolder:mergeMode:cache:(NSString *fileName,[inFolder] NSString *folderName,[mergeMode] OOResourceMergeMode mergeMode,[cache] BOOL useCache)

◆ handleStarNebulaListMerging:

+ (void) handleStarNebulaListMerging: (NSMutableArray *)  arrayToProcess

Definition at line 104 of file ResourceManager.m.

1609 : (NSMutableArray *)arrayToProcess
1610{
1611 NSUInteger i,j,k;
1612 NSMutableArray *refArray = [arrayToProcess objectAtIndex:[arrayToProcess count] - 1];
1613
1614 // Any change to refArray will directly modify arrayToProcess.
1615 for (i = 0; i < [refArray count]; i++)
1616 {
1617 for (j = 0; j < [arrayToProcess count] - 1; j++)
1618 {
1619 NSUInteger count = [[arrayToProcess oo_arrayAtIndex:j] count];
1620 if (count == 0) continue;
1621
1622 for (k = 0; k < count; k++)
1623 {
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;
1628
1629 if ([processValue isKindOfClass:[NSString class]])
1630 {
1631 key1 = processValue;
1632 }
1633 else if ([processValue isKindOfClass:[NSDictionary class]])
1634 {
1635 if (![processValue objectForKey:@"key"])
1636 {
1637 key1 = [processValue objectForKey:@"texture"];
1638 }
1639 else
1640 {
1641 key1 = [processValue objectForKey:@"key"];
1642 }
1643 }
1644 if (!key1) continue;
1645
1646 if ([refValue isKindOfClass:[NSString class]])
1647 {
1648 key2 = refValue;
1649 }
1650 else if ([refValue isKindOfClass:[NSDictionary class]])
1651 {
1652 if (![refValue objectForKey:@"key"])
1653 {
1654 key2 = [refValue objectForKey:@"texture"];
1655 }
1656 else
1657 {
1658 key2 = [refValue objectForKey:@"key"];
1659 }
1660 }
1661 if (!key2) continue;
1662
1663 if ([key1 isEqual:key2])
1664 {
1665 [[arrayToProcess objectAtIndex:j] replaceObjectAtIndex:k withObject:[refArray objectAtIndex:i]];
1666 [refArray removeObjectAtIndex:i];
1667 }
1668
1669 }
1670 }
1671 }
1672 // arrayToProcess has been processed at this point. Any necessary merging has been done.
1673}

◆ loadScripts

+ (NSDictionary *) loadScripts

Definition at line 1694 of file ResourceManager.m.

2080{
2081 NSMutableDictionary *loadedScripts = nil;
2082 NSArray *results = nil;
2083 NSArray *paths = nil;
2084 NSString *path = nil;
2085 OOScript *script = nil;
2086 NSString *name = nil;
2087 NSAutoreleasePool *pool = nil;
2088
2089 OOLog(@"script.load.world.begin", @"%@", @"Loading world scripts...");
2090
2091 loadedScripts = [NSMutableDictionary dictionary];
2093 foreach (path, paths)
2094 {
2095 // excluding world-scripts.plist also excludes script.js / script.plist
2096 // though as those core files don't and won't exist this is not
2097 // a problem.
2098 if (![ResourceManager corePlist:@"world-scripts.plist" excludedAt:path])
2099 {
2100 pool = [[NSAutoreleasePool alloc] init];
2101
2102 @try
2103 {
2104 results = [OOScript worldScriptsAtPath:[path stringByAppendingPathComponent:@"Config"]];
2105 if (results == nil) results = [OOScript worldScriptsAtPath:path];
2106 if (results != nil)
2107 {
2108 foreach (script, results)
2109 {
2110 name = [script name];
2111 if (name != nil) [loadedScripts setObject:script forKey:name];
2112 else OOLog(@"script.load.unnamed", @"Discarding anonymous script %@", script);
2113 }
2114 }
2115 }
2116 @catch (NSException *exception)
2117 {
2118 OOLog(@"script.load.exception", @"***** %s encountered exception %@ (%@) while trying to load script from %@ -- ignoring this location.", __PRETTY_FUNCTION__, [exception name], [exception reason], path);
2119 // Ignore exception and keep loading other scripts.
2120 }
2121
2122 [pool release];
2123 }
2124 }
2125
2126 if (OOLogWillDisplayMessagesInClass(@"script.load.world.listAll"))
2127 {
2128 NSUInteger count = [loadedScripts count];
2129 if (count != 0)
2130 {
2131 NSMutableArray *displayNames = nil;
2132 OOScript *script = nil;
2133 NSString *displayString = nil;
2134
2135 displayNames = [NSMutableArray arrayWithCapacity:count];
2136
2137 foreach (script, [loadedScripts allValues])
2138 {
2139 [displayNames addObject:[script displayName]];
2140 }
2141
2142 displayString = [[displayNames sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] componentsJoinedByString:@"\n "];
2143 OOLog(@"script.load.world.listAll", @"Loaded %llu world scripts:\n %@", count, displayString);
2144 }
2145 else
2146 {
2147 OOLog(@"script.load.world.listAll", @"%@", @"*** No world scripts loaded.");
2148 }
2149 }
2150
2151 return loadedScripts;
2152}
BOOL OOLogWillDisplayMessagesInClass(NSString *inMessageClass)
Definition OOLogging.m:144
NSString * name()
Definition OOScript.m:255
NSArray * worldScriptsAtPath:(NSString *path)
Definition OOScript.m:45
NSString * displayName()
Definition OOScript.m:276

◆ LogClassKeyRoot

+ (static NSString *) LogClassKeyRoot (NSString *)  key
implementation

Definition at line 1694 of file ResourceManager.m.

1695{
1696 NSRange dot = [key rangeOfString:@"."];
1697 if (dot.location != NSNotFound)
1698 {
1699 return [key substringToIndex:dot.location];
1700 }
1701 else
1702 {
1703 return key;
1704 }
1705}

◆ logControlDictionary

+ (NSDictionary *) logControlDictionary

Definition at line 1694 of file ResourceManager.m.

1709{
1710 // Load built-in copy of logcontrol.plist.
1711 NSString *path = [[[ResourceManager builtInPath] stringByAppendingPathComponent:@"Config"]
1712 stringByAppendingPathComponent:@"logcontrol.plist"];
1713 NSMutableDictionary *logControl = [NSMutableDictionary dictionaryWithDictionary:OODictionaryFromFile(path)];
1714 if (logControl == nil) logControl = [NSMutableDictionary dictionary];
1715
1716 // Build list of root log message classes that appear in the built-in list.
1717 NSMutableSet *coreRoots = [NSMutableSet set];
1718 NSString *key = nil;
1719 foreachkey (key, logControl)
1720 {
1721 [coreRoots addObject:LogClassKeyRoot(key)];
1722 }
1723
1724 NSArray *rootPaths = [self rootPaths];
1725 NSString *configPath = nil;
1726 NSDictionary *dict = nil;
1727
1728 // Look for logcontrol.plists inside OXPs (but not in root paths). These are not allowed to define keys in hierarchies used by the build-in one.
1729 foreach (path, [self pathEnumerator])
1730 {
1731 if ([rootPaths containsObject:path]) continue;
1732
1733 configPath = [[path stringByAppendingPathComponent:@"Config"]
1734 stringByAppendingPathComponent:@"logcontrol.plist"];
1735 dict = OODictionaryFromFile(configPath);
1736 if (dict == nil)
1737 {
1738 configPath = [path stringByAppendingPathComponent:@"logcontrol.plist"];
1739 dict = OODictionaryFromFile(configPath);
1740 }
1741 foreachkey (key, dict)
1742 {
1743 if (![coreRoots containsObject:LogClassKeyRoot(key)])
1744 {
1745 [logControl setObject:[dict objectForKey:key] forKey:key];
1746 }
1747 }
1748 }
1749
1750 // Now, look for logcontrol.plists in root paths, i.e. not within OXPs. These are allowed to override the built-in copy.
1751 foreach (path, rootPaths)
1752 {
1753 configPath = [[path stringByAppendingPathComponent:@"Config"]
1754 stringByAppendingPathComponent:@"logcontrol.plist"];
1755 dict = OODictionaryFromFile(configPath);
1756 if (dict == nil)
1757 {
1758 configPath = [path stringByAppendingPathComponent:@"logcontrol.plist"];
1759 dict = OODictionaryFromFile(configPath);
1760 }
1761 foreachkey (key, dict)
1762 {
1763 [logControl setObject:[dict objectForKey:key] forKey:key];
1764 }
1765 }
1766
1767 // Finally, look in preferences, which can override all of the above.
1768 dict = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"logging-enable"];
1769 if (dict != nil) [logControl addEntriesFromDictionary:dict];
1770
1771 return logControl;
1772}
#define foreachkey(VAR, DICT)
Definition OOCocoa.h:353
static NSString * LogClassKeyRoot(NSString *key)

Referenced by LoadExplicitSettings().

+ Here is the caller graph for this function:

◆ logPaths

+ (void) logPaths
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 1694 of file ResourceManager.m.

2239{
2240 NSMutableArray *displayPaths = nil;
2241 NSString *path = nil;
2242
2243 // Prettify paths for logging.
2244 displayPaths = [NSMutableArray arrayWithCapacity:[sSearchPaths count]];
2245 foreach (path, sSearchPaths)
2246 {
2247 [displayPaths addObject:[[path stringByStandardizingPath] stringByAbbreviatingWithTildeInPath]];
2248 }
2249
2250 OOLog(@"searchPaths.dumpAll", @"Resource paths: %@\n %@", sUseAddOns, [displayPaths componentsJoinedByString:@"\n "]);
2251
2252}
static NSString * sUseAddOns

◆ manifest:HasUnmetDependency:logErrors:

+ (BOOL) manifest: (NSDictionary *)  manifest
HasUnmetDependency: (NSDictionary *)  required
logErrors: (BOOL)  logErrors 

Definition at line 104 of file ResourceManager.m.

891 :(NSDictionary *)manifest HasUnmetDependency:(NSDictionary *)required logErrors:(BOOL)logErrors
892{
893 NSString *requiredID = [required oo_stringForKey:kOOManifestRelationIdentifier];
894 NSMutableDictionary *requiredManifest = [sOXPManifests objectForKey:requiredID];
895 // if the other OXP is in the list
896 BOOL requirementsMet = NO;
897 if (requiredManifest != nil)
898 {
899 // then check versions
900 if ([self matchVersions:required withVersion:[requiredManifest oo_stringForKey:kOOManifestVersion]])
901 {
902 requirementsMet = YES;
903 /* Mark the requiredManifest as a dependency of the
904 * requiring manifest */
905 NSSet *reqby = [requiredManifest oo_setForKey:kOOManifestRequiredBy defaultValue:[NSSet set]];
906 NSUInteger reqbycount = [reqby count];
907 /* then add this manifest to its required set. This is
908 * done without checking if it's already there, because
909 * the list of nested requirements may have changed. */
910 reqby = [reqby setByAddingObject:[manifest oo_stringForKey:kOOManifestIdentifier]];
911 // *and* anything that requires this OXP to be installed
912 reqby = [reqby setByAddingObjectsFromSet:[manifest oo_setForKey:kOOManifestRequiredBy]];
913 if (reqbycount < [reqby count])
914 {
915 /* Then the set has increased in size. To handle
916 * potential cases with nested dependencies, need to
917 * re-run the requirement filter until all the sets
918 * stabilise. */
919 sAllMet = NO;
920 }
921 // and push back into the requiring manifest
922 [requiredManifest setObject:reqby forKey:kOOManifestRequiredBy];
923 }
924 }
925 if (!requirementsMet)
926 {
927 if (logErrors)
928 {
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]);
931 }
932 return YES;
933 }
934 return NO;
935}
static NSString *const kOOManifestVersion
static NSString *const kOOManifestFilePath

◆ manifestAllowedByScenario:

+ (BOOL) manifestAllowedByScenario: (NSDictionary *)  manifest
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 104 of file ResourceManager.m.

1044 :(NSDictionary *)manifest
1045{
1046 /* Checks for a couple of "never happens" cases */
1047#ifndef NDEBUG
1048 // test string
1049 if ([sUseAddOns isEqualToString:SCENARIO_OXP_DEFINITION_ALL])
1050 {
1051 OOLog(@"scenario.check", @"%@", @"Checked scenario allowances in all state - this is an internal error; please report this");
1052 return YES;
1053 }
1054 if ([sUseAddOns isEqualToString:SCENARIO_OXP_DEFINITION_NONE])
1055 {
1056 OOLog(@"scenario.check", @"%@", @"Checked scenario allowances in none state - this is an internal error; please report this");
1057 return NO;
1058 }
1059#endif
1060 if ([[manifest oo_stringForKey:kOOManifestIdentifier] isEqualToString:@"org.oolite.oolite"])
1061 {
1062 // the core data is always allowed!
1063 return YES;
1064 }
1065
1066 NSString *uaoBit = nil;
1067 BOOL result = NO;
1068 foreach (uaoBit, sUseAddOnsParts)
1069 {
1070 if ([uaoBit hasPrefix:SCENARIO_OXP_DEFINITION_BYID])
1071 {
1072 result |= [ResourceManager manifestAllowedByScenario:manifest withIdentifier:[uaoBit substringFromIndex:[SCENARIO_OXP_DEFINITION_BYID length]]];
1073 }
1074 else if ([uaoBit hasPrefix:SCENARIO_OXP_DEFINITION_BYTAG])
1075 {
1076 result |= [ResourceManager manifestAllowedByScenario:manifest withTag:[uaoBit substringFromIndex:[SCENARIO_OXP_DEFINITION_BYTAG length]]];
1077 }
1078 }
1079 return result;
1080}
static NSString *const kOOManifestIdentifier
#define SCENARIO_OXP_DEFINITION_BYID
#define SCENARIO_OXP_DEFINITION_NONE
#define SCENARIO_OXP_DEFINITION_ALL
#define SCENARIO_OXP_DEFINITION_BYTAG
BOOL manifestAllowedByScenario:withTag:(NSDictionary *manifest, [withTag] NSString *tag)
BOOL manifestAllowedByScenario:withIdentifier:(NSDictionary *manifest, [withIdentifier] NSString *identifier)

◆ manifestAllowedByScenario:withIdentifier:

+ (BOOL) manifestAllowedByScenario: (NSDictionary *)  manifest
withIdentifier: (NSString *)  identifier 
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 104 of file ResourceManager.m.

1083 :(NSDictionary *)manifest withIdentifier:(NSString *)identifier
1084{
1085 if ([[manifest oo_stringForKey:kOOManifestIdentifier] isEqualToString:identifier])
1086 {
1087 // manifest has the identifier - easy
1088 return YES;
1089 }
1090 // manifest is also allowed if a manifest with that identifier
1091 // requires it to be installed
1092 if ([[manifest oo_setForKey:kOOManifestRequiredBy] containsObject:identifier])
1093 {
1094 return YES;
1095 }
1096 // otherwise, no
1097 return NO;
1098}
static NSString *const kOOManifestRequiredBy

◆ manifestAllowedByScenario:withTag:

+ (BOOL) manifestAllowedByScenario: (NSDictionary *)  manifest
withTag: (NSString *)  tag 
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 104 of file ResourceManager.m.

1101 :(NSDictionary *)manifest withTag:(NSString *)tag
1102{
1103 if ([[manifest oo_arrayForKey:kOOManifestTags] containsObject:tag])
1104 {
1105 // manifest has the tag - easy
1106 return YES;
1107 }
1108 // manifest is also allowed if a manifest with that tag
1109 // requires it to be installed
1110 NSSet *reqby = [manifest oo_setForKey:kOOManifestRequiredBy];
1111 if (reqby != nil)
1112 {
1113 NSString *identifier = nil;
1114 foreach (identifier, reqby)
1115 {
1116 NSDictionary *reqManifest = [sOXPManifests oo_dictionaryForKey:identifier defaultValue:nil];
1117 // need to check for nil as this one may already have been ruled out
1118 if (reqManifest != nil && [[reqManifest oo_arrayForKey:kOOManifestTags] containsObject:tag])
1119 {
1120 return YES;
1121 }
1122 }
1123 }
1124 // otherwise, no
1125 return NO;
1126}

◆ manifestForIdentifier:

+ (NSDictionary *) manifestForIdentifier: (NSString *)  identifier

Definition at line 104 of file ResourceManager.m.

574 :(NSString *)identifier
575{
576 return [sOXPManifests objectForKey:identifier];
577}

◆ manifestHasConflicts:logErrors:

+ (BOOL) manifestHasConflicts: (NSDictionary *)  manifest
logErrors: (BOOL)  logErrors 

Definition at line 104 of file ResourceManager.m.

809 :(NSDictionary *)manifest logErrors:(BOOL)logErrors
810{
811 NSDictionary *conflicting = nil;
812 NSDictionary *conflictManifest = nil;
813 NSString *conflictID = nil;
814 NSArray *conflicts = nil;
815
816 conflicts = [manifest oo_arrayForKey:kOOManifestConflictOXPs defaultValue:nil];
817 // if it has a non-empty conflict_oxps list
818 if (conflicts != nil && [conflicts count] > 0)
819 {
820 // iterate over that list
821 foreach (conflicting, conflicts)
822 {
823 conflictID = [conflicting oo_stringForKey:kOOManifestRelationIdentifier];
824 conflictManifest = [sOXPManifests objectForKey:conflictID];
825 // if the other OXP is in the list
826 if (conflictManifest != nil)
827 {
828 // then check versions
829 if ([self matchVersions:conflicting withVersion:[conflictManifest oo_stringForKey:kOOManifestVersion]])
830 {
831 if (logErrors)
832 {
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]);
835 }
836 return YES;
837 }
838 }
839 }
840 }
841 return NO;
842}

◆ manifestHasMissingDependencies:logErrors:

+ (BOOL) manifestHasMissingDependencies: (NSDictionary *)  manifest
logErrors: (BOOL)  logErrors 

Definition at line 104 of file ResourceManager.m.

869 :(NSDictionary *)manifest logErrors:(BOOL)logErrors
870{
871 NSDictionary *required = nil;
872 NSArray *requireds = nil;
873
874 requireds = [manifest oo_arrayForKey:kOOManifestRequiresOXPs defaultValue:nil];
875 // if it has a non-empty required_oxps list
876 if (requireds != nil && [requireds count] > 0)
877 {
878 // iterate over that list
879 foreach (required, requireds)
880 {
881 if ([ResourceManager manifest:manifest HasUnmetDependency:required logErrors:logErrors])
882 {
883 return YES;
884 }
885 }
886 }
887 return NO;
888}

◆ maskUserName:inPath:

+ (NSString *) maskUserName: (NSString *)  name
inPath: (NSString *)  path 

Definition at line 104 of file ResourceManager.m.

486 :(NSString *)name inPath:(NSString *)path
487{
488 NSMutableString *result = [NSMutableString stringWithString:path];
489 if (result && name) [result replaceOccurrencesOfString:name withString:@"*"
490 options:NSLiteralSearch
491 range:NSMakeRange(0, [result length])
492 ];
493 return [NSString stringWithString:result];
494}

◆ maskUserNameInPathArray:

+ (NSArray *) maskUserNameInPathArray: (NSArray *)  inputPathArray

Definition at line 104 of file ResourceManager.m.

466 :(NSArray *)inputPathArray
467{
468 NSString *path = nil;
469 NSMutableArray *maskedArray = [NSMutableArray arrayWithCapacity:[inputPathArray count]];
470 const char *userNamePathEnvVar =
471#if OOLITE_WINDOWS
472 SDL_getenv("USERPROFILE");
473#else
474 SDL_getenv("HOME");
475#endif
476 NSString *userName = [[NSString stringWithFormat:@"%s", userNamePathEnvVar] lastPathComponent];
477 foreach (path, inputPathArray)
478 {
479 path = [self maskUserName:userName inPath:path];
480 [maskedArray addObject:path];
481 }
482 return maskedArray;
483}

Referenced by OoliteGetProperty().

+ Here is the caller graph for this function:

◆ matchVersions:withVersion:

+ (BOOL) matchVersions: (NSDictionary *)  rangeDict
withVersion: (NSString *)  version 

Definition at line 104 of file ResourceManager.m.

967 :(NSDictionary *)rangeDict withVersion:(NSString *)version
968{
969 NSString *minimum = [rangeDict oo_stringForKey:kOOManifestRelationVersion defaultValue:nil];
970 NSString *maximum = [rangeDict oo_stringForKey:kOOManifestRelationMaxVersion defaultValue:nil];
971 NSArray *isVersionComponents = ComponentsFromVersionString(version);
972 NSArray *reqVersionComponents = nil;
973 if (minimum != nil)
974 {
975 reqVersionComponents = ComponentsFromVersionString(minimum);
976 if (NSOrderedAscending == CompareVersions(isVersionComponents, reqVersionComponents))
977 {
978 // earlier than minimum version
979 return NO;
980 }
981 }
982 if (maximum != nil)
983 {
984 reqVersionComponents = ComponentsFromVersionString(maximum);
985 if (NSOrderedDescending == CompareVersions(isVersionComponents, reqVersionComponents))
986 {
987 // later than maximum version
988 return NO;
989 }
990 }
991 // either version was okay, or no version info so an unconditional match
992 return YES;
993}

◆ materialDefaults

+ (NSDictionary *) materialDefaults

Definition at line 1694 of file ResourceManager.m.

2201{
2202 return [self dictionaryFromFilesNamed:@"material-defaults.plist" inFolder:@"Config" andMerge:YES];
2203}

Referenced by OODefaultShipShaderMacros(), ShipSetMaterialsInternal(), and VisualEffectSetMaterialsInternal().

+ Here is the caller graph for this function:

◆ mergeRoleCategories:intoDictionary:

+ (void) mergeRoleCategories: (NSDictionary *)  catData
intoDictionary: (NSMutableDictionary *)  categories 
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 1694 of file ResourceManager.m.

1811 :(NSDictionary *)catData intoDictionary:(NSMutableDictionary *)categories
1812{
1813 NSMutableSet *contents = nil;
1814 NSArray *catDataEntry = nil;
1815 NSString *key;
1816 foreachkey (key, catData)
1817 {
1818 contents = [categories objectForKey:key];
1819 if (contents == nil)
1820 {
1821 contents = [NSMutableSet setWithCapacity:16];
1822 [categories setObject:contents forKey:key];
1823 }
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];
1827 }
1828}

◆ ooMusicNamed:inFolder:

+ (OOMusic *) ooMusicNamed: (NSString *)  fileName
inFolder: (NSString *)  folderName 

Definition at line 1694 of file ResourceManager.m.

2021 :(NSString *)fileName inFolder:(NSString *)folderName
2022{
2023 return [self retrieveFileNamed:fileName
2024 inFolder:folderName
2025 cache:NULL // Don't cache music objects; minimizing latency isn't really important.
2026 key:[NSString stringWithFormat:@"OOMusic:%@:%@", folderName, fileName]
2027 class:[OOMusic class]
2028 usePathCache:YES];
2029}

◆ ooSoundNamed:inFolder:

+ (OOSound *) ooSoundNamed: (NSString *)  fileName
inFolder: (NSString *)  folderName 

Definition at line 1694 of file ResourceManager.m.

2032 :(NSString *)fileName inFolder:(NSString *)folderName
2033{
2034 return [self retrieveFileNamed:fileName
2035 inFolder:folderName
2036 cache:&sSoundCache
2037 key:[NSString stringWithFormat:@"OOSound:%@:%@", folderName, fileName]
2038 class:[OOSound class]
2039 usePathCache:YES];
2040}

Referenced by Universe::addConditionScripts:, and GetNamedSound().

+ Here is the caller graph for this function:

◆ OXPsWithMessagesFound

+ (NSArray *) OXPsWithMessagesFound

Definition at line 104 of file ResourceManager.m.

569{
570 return [[sOXPsWithMessagesFound copy] autorelease];
571}

◆ pathEnumerator

+ (NSEnumerator *) pathEnumerator

Definition at line 104 of file ResourceManager.m.

557{
558 return [[self paths] objectEnumerator];
559}

◆ pathForFileNamed:inFolder:

+ (NSString *) pathForFileNamed: (NSString *)  fileName
inFolder: (NSString *)  folderName 

Definition at line 1694 of file ResourceManager.m.

1927 :(NSString *)fileName inFolder:(NSString *)folderName
1928{
1929 return [self pathForFileNamed:fileName inFolder:folderName cache:YES];
1930}

Referenced by NSObject(OODebugPlugInController)::setUpDebugger.

+ Here is the caller graph for this function:

◆ pathForFileNamed:inFolder:cache:

+ (NSString *) pathForFileNamed: (NSString *)  fileName
inFolder: (NSString *)  folderName
cache: (BOOL)  useCache 

Definition at line 1694 of file ResourceManager.m.

1934 :(NSString *)fileName inFolder:(NSString *)folderName cache:(BOOL)useCache
1935{
1936 NSString *result = nil;
1937 NSString *cacheKey = nil;
1939 NSString *path = nil;
1940 NSString *filePath = nil;
1941 NSFileManager *fmgr = nil;
1942
1943 if (fileName == nil) return nil;
1944
1945 if (cache)
1946 {
1947 if (folderName != nil) cacheKey = [NSString stringWithFormat:@"%@/%@", folderName, fileName];
1948 else cacheKey = fileName;
1949 result = [cache objectForKey:cacheKey inCache:@"resolved paths"];
1950 if (result != nil) return result;
1951 }
1952
1953 // Search for file
1954 fmgr = [NSFileManager defaultManager];
1955 // reverse object enumerator allows OXPs to override core
1956 foreach (path, [[ResourceManager paths] reverseObjectEnumerator])
1957 {
1958 filePath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
1959 if ([fmgr oo_oxzFileExistsAtPath:filePath])
1960 {
1961 result = filePath;
1962 break;
1963 }
1964
1965 filePath = [path stringByAppendingPathComponent:fileName];
1966 if ([fmgr oo_oxzFileExistsAtPath:filePath])
1967 {
1968 result = filePath;
1969 break;
1970 }
1971 }
1972
1973 if (result != nil)
1974 {
1975 OOLog(@"resourceManager.foundFile", @"Found %@/%@ at %@", folderName, fileName, filePath);
1976 if (useCache)
1977 {
1978 [cache setObject:result forKey:cacheKey inCache:@"resolved paths"];
1979 }
1980 }
1981 return result;
1982}

◆ paths

+ (NSArray *) paths

Definition at line 104 of file ResourceManager.m.

457{
459 {
460 sSearchPaths = [[NSMutableArray alloc] init];
461 }
462 return [self pathsWithAddOns];
463}

Referenced by OoliteGetProperty().

+ Here is the caller graph for this function:

◆ pathsWithAddOns

+ (NSArray *) pathsWithAddOns

Definition at line 104 of file ResourceManager.m.

217{
218 if ([sSearchPaths count] > 0) return sSearchPaths;
219
220 if (sUseAddOns == nil)
221 {
222 sUseAddOns = [[NSString alloc] initWithString:SCENARIO_OXP_DEFINITION_ALL];
223 sUseAddOnsParts = [[sUseAddOns componentsSeparatedByString:@";"] retain];
224 }
225
226 /* Handle special case of 'strict mode' efficiently */
227 // testing actual string
228 if ([sUseAddOns isEqualToString:SCENARIO_OXP_DEFINITION_NONE])
229 {
230 return (NSArray *)[NSArray arrayWithObject:[self builtInPath]];
231 }
232
233 [sErrors release];
234 sErrors = nil;
235
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;
243 BOOL isDirectory;
244
245 // Copy those root paths that actually exist to search paths.
246 rootPaths = [self rootPaths];
247 existingRootPaths = [NSMutableArray arrayWithCapacity:[rootPaths count]];
248 foreach (root, rootPaths)
249 {
250 if ([fmgr fileExistsAtPath:root isDirectory:&isDirectory] && isDirectory)
251 {
252 [existingRootPaths addObject:root];
253 }
254 }
255
256 // validate default search paths
258 sSearchPaths = [NSMutableArray new];
259 foreach (path, existingRootPaths)
260 {
261 [self checkPotentialPath:path :sSearchPaths];
262 }
263
264 // Iterate over root paths.
265 foreach (root, existingRootPaths)
266 {
267 // Iterate over each root path's contents.
268 if ([fmgr fileExistsAtPath:root isDirectory:&isDirectory] && isDirectory)
269 {
270 for (dirEnum = [fmgr enumeratorAtPath:root]; (subPath = [dirEnum nextObject]); )
271 {
272 // Check if it's a directory.
273 path = [root stringByAppendingPathComponent:subPath];
274 if ([fmgr fileExistsAtPath:path isDirectory:&isDirectory])
275 {
276 if (isDirectory)
277 {
278 // If it is, is it an OXP?.
279 if ([[[path pathExtension] lowercaseString] isEqualToString:@"oxp"])
280 {
281 [self checkPotentialPath:path :sSearchPaths];
282 if ([sSearchPaths containsObject:path]) [self checkOXPMessagesInPath:path];
283 }
284 else
285 {
286 // If not, don't search subdirectories.
287 [dirEnum skipDescendents];
288 }
289 }
290 else
291 {
292 // If not a directory, is it an OXZ?
293 if ([[[path pathExtension] lowercaseString] isEqualToString:@"oxz"])
294 {
295 [self checkPotentialPath:path :sSearchPaths];
296 if ([sSearchPaths containsObject:path]) [self checkOXPMessagesInPath:path];
297 }
298 }
299 }
300 }
301 }
302 }
303
304 foreach (path, sExternalPaths)
305 {
306 [self checkPotentialPath:path :sSearchPaths];
307 if ([sSearchPaths containsObject:path]) [self checkOXPMessagesInPath:path];
308 }
309
310 /* If a scenario restriction is *not* in place, remove
311 * scenario-only OXPs. */
312 // test string
313 if ([sUseAddOns isEqualToString:SCENARIO_OXP_DEFINITION_ALL])
314 {
315 [self filterSearchPathsToExcludeScenarioOnlyPaths:sSearchPaths];
316 }
317
318 /* This is a conservative filter. It probably gets rid of more
319 * OXPs than it technically needs to in certain situations with
320 * dependency chains, but really any conflict here needs to be
321 * resolved by the user rather than Oolite. The point is to avoid
322 * loading OXPs which we shouldn't; if doing so takes out other
323 * OXPs which would have been safe, that's not important. */
324 [self filterSearchPathsForConflicts:sSearchPaths];
325
326 /* This one needs to be run repeatedly to be sure. Take the chain
327 * A depends on B depends on C. A and B are installed. A is
328 * checked first, and depends on B, which is thought to be
329 * okay. So A is kept. Then B is checked and removed. A must then
330 * be rechecked. This function therefore is run repeatedly until a
331 * run of it removes no further items.
332 *
333 * There may well be more elegant and efficient ways to do this
334 * but this is already fast enough for most purposes.
335 */
336 while (![self filterSearchPathsForRequirements:sSearchPaths]) {}
337
338 /* If a scenario restriction is in place, restrict OXPs to the
339 * ones valid for the scenario only. */
340 // test string
341 if (![sUseAddOns isEqualToString:SCENARIO_OXP_DEFINITION_ALL])
342 {
343 [self filterSearchPathsByScenario:sSearchPaths];
344 }
345
346 [self checkCacheUpToDateForPaths:sSearchPaths];
347
348 return sSearchPaths;
349}
#define DESTROY(x)
Definition OOCocoa.h:75

◆ preloadFileListFromFolder:forFolders:

+ (void) preloadFileListFromFolder: (NSString *)  path
forFolders: (NSArray *)  folders 
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 104 of file ResourceManager.m.

421 :(NSString *)path forFolders:(NSArray *)folders
422{
423 NSFileManager *fmgr = [NSFileManager defaultManager];
424 NSString *subFolder = nil;
425 NSString *subFolderPath = nil;
426 NSArray *fileList = nil;
427 NSString *fileName = nil;
428
429 // search each subfolder for files
430 foreach (subFolder, folders)
431 {
432 subFolderPath = [path stringByAppendingPathComponent:subFolder];
433 fileList = [fmgr oo_directoryContentsAtPath:subFolderPath];
434 foreach (fileName, fileList)
435 {
436 [self preloadFilePathFor:fileName inFolder:subFolder atPath:[subFolderPath stringByAppendingPathComponent:fileName]];
437 }
438 }
439}

◆ preloadFileListFromOXZ:forFolders:

+ (void) preloadFileListFromOXZ: (NSString *)  path
forFolders: (NSArray *)  folders 
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 104 of file ResourceManager.m.

374 :(NSString *)path forFolders:(NSArray *)folders
375{
376 unzFile uf = NULL;
377 const char* zipname = [path UTF8String];
378 char componentName[512];
379
380 if (zipname != NULL)
381 {
382 uf = unzOpen64(zipname);
383 }
384 if (uf == NULL)
385 {
386 OOLog(@"resourceManager.error",@"Could not open .oxz at %@ as zip file",path);
387 return;
388 }
389 if (unzGoToFirstFile(uf) == UNZ_OK)
390 {
391 do
392 {
394 componentName, 512,
395 NULL, 0,
396 NULL, 0);
397 NSString *zipEntry = [NSString stringWithUTF8String:componentName];
398 NSArray *pathBits = [zipEntry pathComponents];
399 if ([pathBits count] >= 2)
400 {
401 NSString *folder = [pathBits oo_stringAtIndex:0];
402 if ([folders containsObject:folder])
403 {
404 NSRange bitRange;
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];
409
410 [self preloadFilePathFor:file inFolder:folder atPath:fullPath];
411 }
412 }
413
414 }
415 while (unzGoToNextFile(uf) == UNZ_OK);
416 }
417 unzClose(uf);
418}
int ZEXPORT unzGetCurrentFileInfo64(unzFile file, unz_file_info64 *pfile_info, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize)
Definition unzip.c:1130
int ZEXPORT unzGoToFirstFile(unzFile file)
Definition unzip.c:1184
unzFile ZEXPORT unzOpen64(const void *path)
Definition unzip.c:801
int ZEXPORT unzGoToNextFile(unzFile file)
Definition unzip.c:1205
int ZEXPORT unzClose(unzFile file)
Definition unzip.c:811
voidp unzFile
Definition unzip.h:70
#define UNZ_OK
Definition unzip.h:74

◆ preloadFileLists

+ (void) preloadFileLists
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 104 of file ResourceManager.m.

353{
354 NSString *path = nil;
355 NSEnumerator *pathEnum = nil;
356
357 // folders which may contain files to be cached
358 NSArray *folders = [NSArray arrayWithObjects:@"AIs",@"Images",@"Models",@"Music",@"Scenarios",@"Scripts",@"Shaders",@"Sounds",@"Textures",nil];
359
360 for (pathEnum = [[ResourceManager paths] reverseObjectEnumerator]; (path = [pathEnum nextObject]); )
361 {
362 if ([path hasSuffix:@".oxz"])
363 {
364 [self preloadFileListFromOXZ:path forFolders:folders];
365 }
366 else
367 {
368 [self preloadFileListFromFolder:path forFolders:folders];
369 }
370 }
371}

◆ preloadFilePathFor:inFolder:atPath:

+ (void) preloadFilePathFor: (NSString *)  fileName
inFolder: (NSString *)  subFolder
atPath: (NSString *)  path 
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 104 of file ResourceManager.m.

442 :(NSString *)fileName inFolder:(NSString *)subFolder atPath:(NSString *)path
443{
445 NSString *cacheKey = [NSString stringWithFormat:@"%@/%@", subFolder, fileName];
446 NSString *result = [cache objectForKey:cacheKey inCache:@"resolved paths"];
447 // if nil, not found in another OXP already
448 if (result == nil)
449 {
450 OOLog(@"resourceManager.foundFile.preLoad", @"Found %@/%@ at %@", subFolder, fileName, path);
451 [cache setObject:path forKey:cacheKey inCache:@"resolved paths"];
452 }
453}

◆ reset

+ (void) reset

Definition at line 104 of file ResourceManager.m.

111{
112 sFirstRun = YES;
120}
static NSMutableDictionary * sOXPManifests
static BOOL sFirstRun

◆ resetManifestKnowledgeForOXZManager

+ (void) resetManifestKnowledgeForOXZManager

◆ retrieveFileNamed:inFolder:cache:key:class:usePathCache:

+ (id) retrieveFileNamed: (NSString *)  fileName
inFolder: (NSString *)  folderName
cache: (NSMutableDictionary **)  ioCache
key: (NSString *)  key
class: (Class)  class
usePathCache: (BOOL)  useCache 
implementation

Definition at line 1694 of file ResourceManager.m.

1987 :(NSString *)fileName
1988 inFolder:(NSString *)folderName
1989 cache:(NSMutableDictionary **)ioCache
1990 key:(NSString *)key
1991 class:(Class)class
1992 usePathCache:(BOOL)useCache
1993{
1994 id result = nil;
1995 NSString *path = nil;
1996
1997 if (ioCache)
1998 {
1999 if (key == nil) key = [NSString stringWithFormat:@"%@:%@", folderName, fileName];
2000 if (*ioCache != nil)
2001 {
2002 // return the cached object, if any
2003 result = [*ioCache objectForKey:key];
2004 if (result) return result;
2005 }
2006 }
2007
2008 path = [self pathForFileNamed:fileName inFolder:folderName cache:useCache];
2009 if (path != nil) result = [[[class alloc] initWithContentsOfFile:path] autorelease];
2010
2011 if (result != nil && ioCache != NULL)
2012 {
2013 if (*ioCache == nil) *ioCache = [[NSMutableDictionary alloc] init];
2014 [*ioCache setObject:result forKey:key];
2015 }
2016
2017 return result;
2018}

◆ reversePathEnumerator

+ (NSEnumerator *) reversePathEnumerator

Definition at line 104 of file ResourceManager.m.

563{
564 return [[self paths] reverseObjectEnumerator];
565}

◆ roleCategoriesDictionary

+ (NSDictionary *) roleCategoriesDictionary

Definition at line 1694 of file ResourceManager.m.

1776{
1777 NSMutableDictionary *roleCategories = [NSMutableDictionary dictionaryWithCapacity:16];
1778
1779 NSString *path = nil;
1780 NSString *configPath = nil;
1781 NSDictionary *categories = nil;
1782
1783 foreach (path, [self pathEnumerator])
1784 {
1785 if ([ResourceManager corePlist:@"role-categories.plist" excludedAt:path])
1786 {
1787 continue;
1788 }
1789
1790 configPath = [[path stringByAppendingPathComponent:@"Config"]
1791 stringByAppendingPathComponent:@"role-categories.plist"];
1792 categories = OODictionaryFromFile(configPath);
1793 if (categories != nil)
1794 {
1795 [ResourceManager mergeRoleCategories:categories intoDictionary:roleCategories];
1796 }
1797 }
1798
1799 /* If the old pirate-victim-roles files exist, merge them in */
1800 NSArray *pirateVictims = [ResourceManager arrayFromFilesNamed:@"pirate-victim-roles.plist" inFolder:@"Config" andMerge:YES];
1801 if (OOEnforceStandards() && [pirateVictims count] > 0)
1802 {
1803 OOStandardsDeprecated(@"pirate-victim-roles.plist is still being used.");
1804 }
1805 [ResourceManager mergeRoleCategories:[NSDictionary dictionaryWithObject:pirateVictims forKey:@"oolite-pirate-victim"] intoDictionary:roleCategories];
1806
1807 return [[roleCategories copy] autorelease];
1808}
void OOStandardsDeprecated(NSString *message)
NSArray * arrayFromFilesNamed:inFolder:andMerge:(NSString *fileName,[inFolder] NSString *folderName,[andMerge] BOOL mergeFiles)
void mergeRoleCategories:intoDictionary:(NSDictionary *catData, [intoDictionary] NSMutableDictionary *categories)

◆ rootPaths

+ (NSArray *) rootPaths

Definition at line 104 of file ResourceManager.m.

164{
165 static NSArray *sRootPaths = nil;
166 if (sRootPaths == nil) {
167 /* Built-in data, then managed OXZs, then manually installed ones,
168 * which may be useful for debugging/testing purposes. */
169 sRootPaths = [NSArray arrayWithObjects:[self builtInPath], [[OOOXZManager sharedManager] installPath], nil];
170 sRootPaths = [[sRootPaths arrayByAddingObjectsFromArray:[self userRootPaths]] retain];
171 }
172 return sRootPaths;
173}
NSString * installPath()
OOOXZManager * sharedManager()

◆ setUseAddOns:

+ (void) setUseAddOns: (NSString *)  useAddOns

Definition at line 104 of file ResourceManager.m.

503 :(NSString *)useAddOns
504{
505 if (sFirstRun || ![useAddOns isEqualToString:sUseAddOns])
506 {
507 [self reset];
508 sFirstRun = NO;
511 sUseAddOns = [useAddOns retain];
512 sUseAddOnsParts = [[sUseAddOns componentsSeparatedByString:@";"] retain];
513
516
518 /* only allow cache writes for the "all OXPs" default
519 *
520 * cache should be less necessary for restricted sets anyway */
521 // testing the actual string here
522 if ([sUseAddOns isEqualToString:SCENARIO_OXP_DEFINITION_ALL])
523 {
524 [cmgr reloadAllCaches];
525 [cmgr setAllowCacheWrites:YES];
526 }
527 else
528 {
529 [cmgr clearAllCaches];
530 [cmgr setAllowCacheWrites:NO];
531 }
532
533 [self checkCacheUpToDateForPaths:[self paths]];
534 [self logPaths];
535 /* preloading the file lists at this stage helps efficiency a
536 * lot when many OXZs are installed */
537 [self preloadFileLists];
538
539 }
540}
void OOHUDResetTextEngine(void)
void setAllowCacheWrites:(BOOL flag)
NSString * useAddOns()

◆ shaderBindingTypesDictionary

+ (NSDictionary *) shaderBindingTypesDictionary

Definition at line 1694 of file ResourceManager.m.

1882{
1884
1886 {
1887 NSAutoreleasePool *pool = [NSAutoreleasePool new];
1888
1889 NSString *path = [[[ResourceManager builtInPath] stringByAppendingPathComponent:@"Config"] stringByAppendingPathComponent:@"shader-uniform-bindings.plist"];
1890 NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:path];
1891 NSArray *keys = [dict allKeys];
1892
1893 // Resolve all $inherit keys.
1894 unsigned changeCount = 0;
1895 do {
1896 changeCount = 0;
1897 NSString *key = nil;
1898 foreach (key, keys)
1899 {
1900 NSDictionary *value = [dict oo_dictionaryForKey:key];
1901 NSString *inheritKey = [value oo_stringForKey:@"$inherit"];
1902 if (inheritKey != nil)
1903 {
1904 changeCount++;
1905 NSMutableDictionary *mutableValue = [[value mutableCopy] autorelease];
1906 [mutableValue removeObjectForKey:@"$inherit"];
1907 NSDictionary *inherited = [dict oo_dictionaryForKey:inheritKey];
1908 if (inherited != nil)
1909 {
1910 [mutableValue addEntriesFromDictionary:inherited];
1911 }
1912
1913 [dict setObject:[[mutableValue copy] autorelease] forKey:key];
1914 }
1915 }
1916 } while (changeCount != 0);
1917
1918 shaderBindingTypesDictionary = [dict copy];
1919
1920 [pool release];
1921 }
1922
1924}
NSDictionary * shaderBindingTypesDictionary()

◆ stringFromFilesNamed:inFolder:

+ (NSString *) stringFromFilesNamed: (NSString *)  fileName
inFolder: (NSString *)  folderName 

Definition at line 1694 of file ResourceManager.m.

2043 :(NSString *)fileName inFolder:(NSString *)folderName
2044{
2045 return [self stringFromFilesNamed:fileName inFolder:folderName cache:YES];
2046}

Referenced by GetShaderSource().

+ Here is the caller graph for this function:

◆ stringFromFilesNamed:inFolder:cache:

+ (NSString *) stringFromFilesNamed: (NSString *)  fileName
inFolder: (NSString *)  folderName
cache: (BOOL)  useCache 

Definition at line 1694 of file ResourceManager.m.

2049 :(NSString *)fileName inFolder:(NSString *)folderName cache:(BOOL)useCache
2050{
2051 id result = nil;
2052 NSString *path = nil;
2053 NSString *key = nil;
2054
2055 if (useCache)
2056 {
2057 key = [NSString stringWithFormat:@"%@:%@", folderName, fileName];
2058 if (sStringCache != nil)
2059 {
2060 // return the cached object, if any
2061 result = [sStringCache objectForKey:key];
2062 if (result) return result;
2063 }
2064 }
2065
2066 path = [self pathForFileNamed:fileName inFolder:folderName cache:YES];
2067 if (path != nil) result = [NSString stringWithContentsOfUnicodeFile:path];
2068
2069 if (result != nil && useCache)
2070 {
2071 if (sStringCache == nil) sStringCache = [[NSMutableDictionary alloc] init];
2072 [sStringCache setObject:result forKey:key];
2073 }
2074
2075 return result;
2076}

◆ systemDescriptionManager

+ (OOSystemDescriptionManager *) systemDescriptionManager

Definition at line 1694 of file ResourceManager.m.

1832{
1833 OOLog(@"resourceManager.planetinfo.load", @"%@", @"Initialising manager");
1835
1836 NSString *path = nil;
1837 NSString *configPath = nil;
1838 NSDictionary *categories = nil;
1839 NSString *systemKey = nil;
1840
1841 foreach (path, [self pathEnumerator])
1842 {
1843 if ([ResourceManager corePlist:@"planetinfo.plist" excludedAt:path])
1844 {
1845 continue;
1846 }
1847 configPath = [[path stringByAppendingPathComponent:@"Config"]
1848 stringByAppendingPathComponent:@"planetinfo.plist"];
1849 categories = OODictionaryFromFile(configPath);
1850 if (categories != nil)
1851 {
1852 foreachkey (systemKey,categories)
1853 {
1854 NSDictionary *values = [categories oo_dictionaryForKey:systemKey defaultValue:nil];
1855 if (values != nil)
1856 {
1857 if ([systemKey isEqualToString:PLANETINFO_UNIVERSAL_KEY])
1858 {
1859 [manager setUniversalProperties:values];
1860 }
1861 else if ([systemKey isEqualToString:PLANETINFO_INTERSTELLAR_KEY])
1862 {
1863 [manager setInterstellarProperties:values];
1864 }
1865 else
1866 {
1867 [manager setProperties:values forSystemKey:systemKey];
1868 }
1869 }
1870 }
1871 }
1872 }
1873 OOLog(@"resourceManager.planetinfo.load", @"%@", @"Caching routes");
1874 [manager buildRouteCache];
1875 OOLog(@"resourceManager.planetinfo.load", @"%@", @"Initialised manager");
1876 return [manager autorelease];
1877}
#define PLANETINFO_UNIVERSAL_KEY
Definition Universe.h:154
#define PLANETINFO_INTERSTELLAR_KEY
Definition Universe.h:155
void setUniversalProperties:(NSDictionary *properties)
void setProperties:forSystemKey:(NSDictionary *properties,[forSystemKey] NSString *key)
void setInterstellarProperties:(NSDictionary *properties)

◆ useAddOns

+ (NSString *) useAddOns

Definition at line 104 of file ResourceManager.m.

498{
499 return sUseAddOns;
500}

◆ userRootPaths

+ (NSArray *) userRootPaths

Definition at line 104 of file ResourceManager.m.

177{
178 static NSArray *sUserRootPaths = nil;
179
180 if (sUserRootPaths == nil)
181 {
182 // the paths are now in order of preference as per yesterday's talk. -- Kaks 2010-05-05
183 NSArray *defaultAddOnsPaths = [NSArray arrayWithObjects:
184#if OOLITE_MAC_OS_X
185 [[[[NSHomeDirectory() stringByAppendingPathComponent:@"Library"]
186 stringByAppendingPathComponent:@"Application Support"]
187 stringByAppendingPathComponent:@"Oolite"]
188 stringByAppendingPathComponent:@"AddOns"],
189 [[[[NSBundle mainBundle] bundlePath]
190 stringByDeletingLastPathComponent]
191 stringByAppendingPathComponent:@"AddOns"],
192#endif
193 @"AddOns",
195 nil];
196 sUserRootPaths = [[[[OOOXZManager sharedManager] additionalAddOnsPaths] arrayByAddingObjectsFromArray:defaultAddOnsPaths] retain];
197 }
198 OOLog(@"searchPaths.debug",@"%@",sUserRootPaths);
199 return sUserRootPaths;
200}
NSString * extractAddOnsPath()
NSArray * additionalAddOnsPaths()

◆ validateManifest:forOXP:

+ (BOOL) validateManifest: (NSDictionary*)  manifest
forOXP: (NSString *)  path 
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 104 of file ResourceManager.m.

657 :(NSDictionary*)manifest forOXP:(NSString *)path
658{
660 {
661 sOXPManifests = [[NSMutableDictionary alloc] initWithCapacity:32];
662 }
663
664 BOOL OK = YES;
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];
669
670 if (identifier == nil)
671 {
672 OOLog(@"oxp.noManifest", @"OXZ %@ manifest.plist has no '%@' field.", path, kOOManifestIdentifier);
673 [self addErrorWithKey:@"oxp-manifest-incomplete" param1:title param2:kOOManifestIdentifier];
674 OK = NO;
675 }
676 if (version == nil)
677 {
678 OOLog(@"oxp.noManifest", @"OXZ %@ manifest.plist has no '%@' field.", path, kOOManifestVersion);
679 [self addErrorWithKey:@"oxp-manifest-incomplete" param1:title param2:kOOManifestVersion];
680 OK = NO;
681 }
682 if (required == nil)
683 {
684 OOLog(@"oxp.noManifest", @"OXZ %@ manifest.plist has no '%@' field.", path, kOOManifestRequiredOoliteVersion);
685 [self addErrorWithKey:@"oxp-manifest-incomplete" param1:title param2:kOOManifestRequiredOoliteVersion];
686 OK = NO;
687 }
688 if (title == nil)
689 {
690 OOLog(@"oxp.noManifest", @"OXZ %@ manifest.plist has no '%@' field.", path, kOOManifestTitle);
691 [self addErrorWithKey:@"oxp-manifest-incomplete" param1:title param2:kOOManifestTitle];
692 OK = NO;
693 }
694 if (!OK)
695 {
696 return NO;
697 }
698 OK = [self checkVersionCompatibility:manifest forOXP:title];
699
700 if (!OK)
701 {
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];
705 return NO;
706 }
707
708 NSDictionary *duplicate = [sOXPManifests objectForKey:identifier];
709 if (duplicate != nil)
710 {
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]];
713 return NO;
714 }
715 NSMutableDictionary *mData = [NSMutableDictionary dictionaryWithDictionary:manifest];
716 [mData setObject:path forKey:kOOManifestFilePath];
717 // add an extra key
718 [sOXPManifests setObject:mData forKey:identifier];
719 return YES;
720}
static NSString *const kOOManifestRequiredOoliteVersion
static NSString *const kOOManifestTitle

◆ whitelistDictionary

+ (NSDictionary *) whitelistDictionary

Definition at line 104 of file ResourceManager.m.

1677{
1678 static id whitelistDictionary = nil;
1679
1680 if (whitelistDictionary == nil)
1681 {
1682 NSString *path = [[[ResourceManager builtInPath] stringByAppendingPathComponent:@"Config"] stringByAppendingPathComponent:@"whitelist.plist"];
1683 whitelistDictionary = [NSDictionary dictionaryWithContentsOfFile:path];
1684 if (whitelistDictionary == nil) whitelistDictionary = [NSNull null];
1685
1686 [whitelistDictionary retain];
1687 }
1688
1689 if (whitelistDictionary == [NSNull null]) return nil;
1690 return whitelistDictionary;
1691}
NSDictionary * whitelistDictionary()

Referenced by LookUpLegacySelector(), OOUniformBindingPermitted(), SanitizeActionMethod(), and SanitizeQueryMethod().

+ Here is the caller graph for this function:

◆ writeDiagnosticData:toFileNamed:

+ (BOOL) writeDiagnosticData: (NSData *)  data
toFileNamed: (NSString *)  name 

Definition at line 1694 of file ResourceManager.m.

2155 :(NSData *)data toFileNamed:(NSString *)name
2156{
2157 if (data == nil || name == nil) return NO;
2158
2159 NSString *directory = [self diagnosticFileLocation];
2160 if (directory == nil) return NO;
2161
2162 NSArray *nameComponents = [name componentsSeparatedByString:@"/"];
2163 NSUInteger count = [nameComponents count];
2164 if (count > 1)
2165 {
2166 name = [nameComponents lastObject];
2167
2168 for (NSUInteger i = 0; i < count - 1; i++)
2169 {
2170 NSString *component = [nameComponents objectAtIndex:i];
2171 if ([component hasPrefix:@"."])
2172 {
2173 component = [@"!" stringByAppendingString:[component substringFromIndex:1]];
2174 }
2175 directory = [directory stringByAppendingPathComponent:component];
2176 [[NSFileManager defaultManager] oo_createDirectoryAtPath:directory attributes:nil];
2177 }
2178 }
2179
2180 return [data writeToFile:[directory stringByAppendingPathComponent:name] atomically:YES];
2181}

◆ writeDiagnosticPList:toFileNamed:

+ (BOOL) writeDiagnosticPList: (id)  plist
toFileNamed: (NSString *)  name 

Definition at line 1694 of file ResourceManager.m.

2190 :(id)plist toFileNamed:(NSString *)name
2191{
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;
2195
2196 return [self writeDiagnosticData:data toFileNamed:name];
2197}

◆ writeDiagnosticString:toFileNamed:

+ (BOOL) writeDiagnosticString: (NSString *)  string
toFileNamed: (NSString *)  name 

Definition at line 1694 of file ResourceManager.m.

2184 :(NSString *)string toFileNamed:(NSString *)name
2185{
2186 return [self writeDiagnosticData:[string dataUsingEncoding:NSUTF8StringEncoding] toFileNamed:name];
2187}

Referenced by SVGDumpEnd().

+ Here is the caller graph for this function:

The documentation for this class was generated from the following files: