Support launching an arbitrary mod. Hook up package detection for cnc.

This commit is contained in:
Paul Chote
2010-11-17 13:49:30 +13:00
parent f42f39f9c9
commit 3dc16bdbb4
15 changed files with 128 additions and 45 deletions

View File

@@ -16,10 +16,14 @@
{
SidebarEntry *sidebarItems;
GameInstall *game;
NSDictionary *allMods;
IBOutlet NSOutlineView *outlineView;
IBOutlet WebView *webView;
}
- (void)launchGame;
@property(readonly) NSDictionary *allMods;
- (void)launchMod:(NSString *)mod;
- (void)populateModInfo;
- (SidebarEntry *)sidebarModsTree;
- (SidebarEntry *)sidebarOtherTree;

View File

@@ -14,6 +14,7 @@
#import "JSBridge.h"
@implementation Controller
@synthesize allMods;
- (void) awakeFromNib
{
@@ -25,6 +26,7 @@
[col setDataCell:imageAndTextCell];
sidebarItems = [[SidebarEntry headerWithTitle:@""] retain];
[self populateModInfo];
id modsRoot = [self sidebarModsTree];
[sidebarItems addChild:modsRoot];
id otherRoot = [self sidebarOtherTree];
@@ -45,21 +47,25 @@
[outlineView expandItem:otherRoot expandChildren:YES];
}
- (void) dealloc
- (void)dealloc
{
[sidebarItems release]; sidebarItems = nil;
[super dealloc];
}
- (SidebarEntry *)sidebarModsTree
- (void)populateModInfo
{
// Get info for all installed mods
id modnames = [game installedMods];
NSArray *allMods = [game infoForMods:modnames];
[allMods autorelease];
allMods = [[game infoForMods:[game installedMods]] retain];
}
- (SidebarEntry *)sidebarModsTree
{
SidebarEntry *rootItem = [SidebarEntry headerWithTitle:@"MODS"];
for (id aMod in allMods)
for (id key in allMods)
{
id aMod = [allMods objectForKey:key];
if ([aMod standalone])
{
id child = [SidebarEntry entryWithMod:aMod allMods:allMods baseURL:[[game gameURL] URLByAppendingPathComponent:@"mods"]];
@@ -79,9 +85,9 @@
return rootItem;
}
- (void)launchGame
- (void)launchMod:(NSString *)mod
{
[game launchGame];
[game launchMod:mod];
}
#pragma mark Sidebar Datasource and Delegate
@@ -156,4 +162,8 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn
[windowObject setValue:[JSBridge sharedInstance] forKey:@"external"];
}
- (void)webView:(WebView *)webView addMessageToConsole:(NSDictionary *)dictionary
{
NSLog(@"%@",dictionary);
}
@end

View File

@@ -15,9 +15,9 @@
@property(readonly) NSURL *gameURL;
-(id)initWithURL:(NSURL *)path;
-(void)launchGame;
-(void)launchMod:(NSString *)mod;
- (NSString *)runUtilityQuery:(NSString *)arg;
- (void)runUtilityQuery:(NSString *)arg handleOutput:(id)obj withMethod:(SEL)sel;
- (NSArray *)installedMods;
- (NSArray *)infoForMods:(NSArray *)mods;
- (NSDictionary *)infoForMods:(NSArray *)mods;
@end

View File

@@ -35,12 +35,12 @@
return [mods componentsSeparatedByString:@"\n"];
}
- (NSArray *)infoForMods:(NSArray *)mods
- (NSDictionary *)infoForMods:(NSArray *)mods
{
id query = [NSString stringWithFormat:@"-i=%@",[mods componentsJoinedByString:@","]];
NSArray *lines = [[self runUtilityQuery:query] componentsSeparatedByString:@"\n"];
NSMutableArray *ret = [NSMutableArray array];
NSMutableDictionary *ret = [NSMutableDictionary dictionary];
NSMutableDictionary *fields = nil;
NSString *current = nil;
for (id l in lines)
@@ -68,7 +68,7 @@
if (current != nil)
{
id url = [gameURL URLByAppendingPathComponent:[NSString stringWithFormat:@"mods/%@",current]];
[ret addObject:[Mod modWithId:current fields:fields baseURL:url]];
[ret setObject:[Mod modWithId:current fields:fields baseURL:url] forKey:current];
}
NSLog(@"Parsing mod %@",value);
current = value;
@@ -82,17 +82,17 @@
if (current != nil)
{
id url = [gameURL URLByAppendingPathComponent:[NSString stringWithFormat:@"mods/%@",current]];
[ret addObject:[Mod modWithId:current fields:fields baseURL:url]];
[ret setObject:[Mod modWithId:current fields:fields baseURL:url] forKey:current];
}
return ret;
}
-(void)launchGame
-(void)launchMod:(NSString *)mod
{
// Use LaunchServices because neither NSTask or NSWorkspace support Info.plist _and_ arguments pre-10.6
NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"OpenRA.app/Contents/MacOS/OpenRA"];
NSArray *args = [NSArray arrayWithObjects:[gameURL absoluteString], @"mono", @"--debug", @"OpenRA.Game.exe", @"Game.Mods=ra",nil];
NSArray *args = [NSArray arrayWithObjects:[gameURL absoluteString], @"mono", @"--debug", @"OpenRA.Game.exe", [NSString stringWithFormat:@"Game.Mods=%@",mod],nil];
FSRef appRef;
CFURLGetFSRef((CFURLRef)[NSURL URLWithString:path], &appRef);

View File

@@ -38,7 +38,7 @@ static JSBridge *SharedInstance;
if (self != nil)
{
methods = [[NSDictionary dictionaryWithObjectsAndKeys:
@"launchCurrentMod", NSStringFromSelector(@selector(launchCurrentMod)),
@"launchMod", NSStringFromSelector(@selector(launchMod:)),
@"log", NSStringFromSelector(@selector(log:)),
@"fileExistsInMod", NSStringFromSelector(@selector(fileExists:inMod:)),
nil] retain];
@@ -59,10 +59,17 @@ static JSBridge *SharedInstance;
#pragma mark JS methods
- (void)launchCurrentMod
- (BOOL)launchMod:(NSString *)aMod
{
NSLog(@"launchcurrent");
[controller launchGame];
id mod = [[controller allMods] objectForKey:aMod];
if (mod == nil)
{
NSLog(@"Invalid or unknown mod: %@", aMod);
return NO;
}
[controller launchMod:aMod];
return YES;
}
- (void)log:(NSString *)message
@@ -72,8 +79,19 @@ static JSBridge *SharedInstance;
- (BOOL)fileExists:(NSString *)aFile inMod:(NSString *)aMod
{
NSLog(@"File %@ exists in mod %@",aFile, aMod);
return NO;
id mod = [[controller allMods] objectForKey:aMod];
if (mod == nil)
{
NSLog(@"Invalid or unknown mod: %@", aMod);
return NO;
}
// Disallow traversing up the directory tree
id path = [[[mod baseURL] absoluteString]
stringByAppendingPathComponent:[aFile stringByReplacingOccurrencesOfString:@"../"
withString:@""]];
return [[NSFileManager defaultManager] fileExistsAtPath:path];
}
@end

View File

@@ -24,10 +24,9 @@
@property (readonly) NSString *author;
@property (readonly) NSString *description;
@property (readonly) NSString *requires;
@property (readonly) NSURL *baseURL;
@property (readonly) BOOL standalone;
+ (id)modWithId:(NSString *)mid fields:(id)fields baseURL:(NSURL *)url;
- (id)initWithId:(NSString *)anId fields:(NSDictionary *)fields baseURL:(NSURL *)url;
- (NSURL *)pageURL;
@end

View File

@@ -17,6 +17,7 @@
@synthesize description;
@synthesize requires;
@synthesize standalone;
@synthesize baseURL;
+ (id)modWithId:(NSString *)mod fields:(id)fields baseURL:(NSURL *)url
{
@@ -54,9 +55,4 @@
[super dealloc];
}
- (NSURL *)pageURL
{
return [baseURL URLByAppendingPathComponent:@"mod.html"];
}
@end

View File

@@ -25,7 +25,7 @@
+ (id)headerWithTitle:(NSString *)aTitle;
+ (id)entryWithTitle:(NSString *)aTitle url:(NSURL *)aURL icon:(id)anIcon;
+ (id)entryWithMod:(Mod *)baseMod allMods:(NSArray *)allMods baseURL:(NSURL *)aURL;
+ (id)entryWithMod:(Mod *)baseMod allMods:(NSDictionary *)allMods baseURL:(NSURL *)aURL;
- (id)initWithTitle:(NSString *)aTitle url:(NSURL *)aURL icon:(id)anIcon isHeader:(BOOL)aHeader;
- (void)addChild:(id)child;
- (NSURL *)url;

View File

@@ -29,7 +29,7 @@
return newObject;
}
+ (id)entryWithMod:(Mod *)baseMod allMods:(NSArray *)allMods baseURL:(NSURL *)baseURL
+ (id)entryWithMod:(Mod *)baseMod allMods:(NSDictionary *)allMods baseURL:(NSURL *)baseURL
{
// TODO: Get the mod icon from the Mod
// Temporary hack until mods define an icon
@@ -40,8 +40,9 @@
id ret = [SidebarEntry entryWithTitle:[baseMod title] url:url icon:icon];
for (id aMod in allMods)
for (id key in allMods)
{
id aMod = [allMods objectForKey:key];
if (![[aMod requires] isEqualToString:[baseMod mod]])
continue;