Line data Source code
1 0 : /* 2 : 3 : OOPListScript.h 4 : 5 : Oolite 6 : Copyright (C) 2004-2013 Giles C Williams and contributors 7 : 8 : This program is free software; you can redistribute it and/or 9 : modify it under the terms of the GNU General Public License 10 : as published by the Free Software Foundation; either version 2 11 : of the License, or (at your option) any later version. 12 : 13 : This program is distributed in the hope that it will be useful, 14 : but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : GNU General Public License for more details. 17 : 18 : You should have received a copy of the GNU General Public License 19 : along with this program; if not, write to the Free Software 20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 21 : MA 02110-1301, USA. 22 : 23 : */ 24 : 25 : #import "OOPListScript.h" 26 : #import "OOPListParsing.h" 27 : #import "PlayerEntityLegacyScriptEngine.h" 28 : #import "OOLegacyScriptWhitelist.h" 29 : #import "OOCacheManager.h" 30 : #import "OOCollectionExtractors.h" 31 : 32 : 33 0 : static NSString * const kMDKeyName = @"name"; 34 0 : static NSString * const kMDKeyDescription = @"description"; 35 0 : static NSString * const kMDKeyVersion = @"version"; 36 0 : static NSString * const kKeyMetadata = @"!metadata!"; 37 0 : static NSString * const kKeyScript = @"script"; 38 : 39 0 : static NSString * const kCacheName = @"sanitized legacy scripts"; 40 : 41 : 42 : @interface OOPListScript (SetUp) 43 : 44 0 : + (NSArray *)scriptsFromDictionaryOfScripts:(NSDictionary *)dictionary filePath:(NSString *)filePath; 45 0 : + (NSArray *) loadCachedScripts:(NSDictionary *)cachedScripts; 46 0 : - (id)initWithName:(NSString *)name scriptArray:(NSArray *)script metadata:(NSDictionary *)metadata; 47 : 48 : @end 49 : 50 : 51 : @implementation OOPListScript 52 : 53 : + (NSArray *)scriptsInPListFile:(NSString *)filePath 54 : { 55 : NSDictionary *cachedScripts = [[OOCacheManager sharedCache] objectForKey:filePath inCache:kCacheName]; 56 : if (cachedScripts != nil) 57 : { 58 : return [self loadCachedScripts:cachedScripts]; 59 : } 60 : else 61 : { 62 : NSDictionary *dict = OODictionaryFromFile(filePath); 63 : if (dict == nil) return nil; 64 : return [self scriptsFromDictionaryOfScripts:dict filePath:filePath]; 65 : } 66 : } 67 : 68 : 69 0 : - (void)dealloc 70 : { 71 : [_script release]; 72 : [_metadata release]; 73 : 74 : [super dealloc]; 75 : } 76 : 77 : 78 0 : - (NSString *)name 79 : { 80 : return [_metadata objectForKey:kMDKeyName]; 81 : } 82 : 83 : 84 0 : - (NSString *)scriptDescription 85 : { 86 : return [_metadata objectForKey:kMDKeyDescription]; 87 : } 88 : 89 : 90 0 : - (NSString *)version 91 : { 92 : return [_metadata objectForKey:kMDKeyVersion]; 93 : } 94 : 95 : 96 0 : - (BOOL) requiresTickle 97 : { 98 : return YES; 99 : } 100 : 101 : 102 0 : - (void)runWithTarget:(Entity *)target 103 : { 104 : if (target != nil && ![target isKindOfClass:[ShipEntity class]]) 105 : { 106 : OOLog(@"script.legacy.run.badTarget", @"Expected ShipEntity or nil for target, got %@.", [target class]); 107 : return; 108 : } 109 : 110 : OOLog(@"script.legacy.run", @"Running script %@", [self displayName]); 111 : OOLogIndentIf(@"script.legacy.run"); 112 : 113 : [PLAYER runScriptActions:_script 114 : withContextName:[self name] 115 : forTarget:(ShipEntity *)target]; 116 : 117 : OOLogOutdentIf(@"script.legacy.run"); 118 : } 119 : 120 : @end 121 : 122 : 123 : @implementation OOPListScript (SetUp) 124 : 125 : + (NSArray *)scriptsFromDictionaryOfScripts:(NSDictionary *)dictionary filePath:(NSString *)filePath 126 : { 127 : NSMutableArray *result = nil; 128 : NSEnumerator *keyEnum = nil; 129 : NSString *key = nil; 130 : NSArray *scriptArray = nil; 131 : NSDictionary *metadata = nil; 132 : NSMutableDictionary *cachedScripts = nil; 133 : OOPListScript *script = nil; 134 : 135 : NSUInteger count = [dictionary count]; 136 : result = [NSMutableArray arrayWithCapacity:count]; 137 : cachedScripts = [NSMutableDictionary dictionaryWithCapacity:count]; 138 : 139 : metadata = [dictionary objectForKey:kKeyMetadata]; 140 : if (![metadata isKindOfClass:[NSDictionary class]]) metadata = nil; 141 : 142 : for (keyEnum = [dictionary keyEnumerator]; (key = [keyEnum nextObject]); ) 143 : { 144 : scriptArray = [dictionary objectForKey:key]; 145 : if ([key isKindOfClass:[NSString class]] && 146 : [scriptArray isKindOfClass:[NSArray class]] && 147 : ![key isEqual:kKeyMetadata]) 148 : { 149 : scriptArray = OOSanitizeLegacyScript(scriptArray, key, NO); 150 : if (scriptArray != nil) 151 : { 152 : script = [[self alloc] initWithName:key scriptArray:scriptArray metadata:metadata]; 153 : if (script != nil) 154 : { 155 : [result addObject:script]; 156 : [cachedScripts setObject:[NSDictionary dictionaryWithObjectsAndKeys:scriptArray, kKeyScript, metadata, kKeyMetadata, nil] forKey:key]; 157 : 158 : [script release]; 159 : } 160 : } 161 : } 162 : } 163 : 164 : [[OOCacheManager sharedCache] setObject:cachedScripts forKey:filePath inCache:kCacheName]; 165 : 166 : return [[result copy] autorelease]; 167 : } 168 : 169 : 170 : + (NSArray *) loadCachedScripts:(NSDictionary *)cachedScripts 171 : { 172 : NSEnumerator *keyEnum = nil; 173 : NSString *key = nil; 174 : 175 : NSMutableArray *result = [NSMutableArray arrayWithCapacity:[cachedScripts count]]; 176 : 177 : for (keyEnum = [cachedScripts keyEnumerator]; (key = [keyEnum nextObject]); ) 178 : { 179 : NSDictionary *cacheValue = [cachedScripts oo_dictionaryForKey:key]; 180 : NSArray *scriptArray = [cacheValue oo_arrayForKey:kKeyScript]; 181 : NSDictionary *metadata = [cacheValue oo_dictionaryForKey:kKeyMetadata]; 182 : OOPListScript *script = [[self alloc] initWithName:key scriptArray:scriptArray metadata:metadata]; 183 : if (script != nil) 184 : { 185 : [result addObject:script]; 186 : [script release]; 187 : } 188 : } 189 : 190 : return [[result copy] autorelease]; 191 : } 192 : 193 : 194 : - (id)initWithName:(NSString *)name scriptArray:(NSArray *)script metadata:(NSDictionary *)metadata 195 : { 196 : self = [super init]; 197 : if (self != nil) 198 : { 199 : _script = [script retain]; 200 : if (name != nil) 201 : { 202 : if (metadata == nil) metadata = [NSDictionary dictionaryWithObject:name forKey:kMDKeyName]; 203 : else 204 : { 205 : NSMutableDictionary *mutableMetadata = [[metadata mutableCopy] autorelease]; 206 : [mutableMetadata setObject:name forKey:kMDKeyName]; 207 : metadata = mutableMetadata; 208 : } 209 : } 210 : _metadata = [metadata copy]; 211 : } 212 : 213 : return self; 214 : } 215 : 216 : @end