156 lines
4.4 KiB
Objective-C
156 lines
4.4 KiB
Objective-C
/*
|
|
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
|
* This file is part of OpenRA, which is free software. It is made
|
|
* available to you under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation. For more information,
|
|
* see LICENSE.
|
|
*/
|
|
|
|
#import "GameInstall.h"
|
|
#import "Mod.h"
|
|
|
|
@implementation GameInstall
|
|
|
|
-(id)initWithURL:(NSURL *)url
|
|
{
|
|
self = [super init];
|
|
if (self != nil)
|
|
{
|
|
gameURL = [url retain];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
[gameURL release]; gameURL = nil;
|
|
[super dealloc];
|
|
}
|
|
|
|
- (NSArray *)installedMods
|
|
{
|
|
id raw = [self runUtilityQuery:@"-l"];
|
|
id mods = [raw stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
|
return [mods componentsSeparatedByString:@"\n"];
|
|
}
|
|
|
|
- (NSArray *)infoForMods:(NSArray *)mods
|
|
{
|
|
id query = [NSString stringWithFormat:@"-i=%@",[mods componentsJoinedByString:@","]];
|
|
NSArray *lines = [[self runUtilityQuery:query] componentsSeparatedByString:@"\n"];
|
|
|
|
NSMutableArray *ret = [NSMutableArray array];
|
|
NSMutableDictionary *fields = nil;
|
|
NSString *current = nil;
|
|
for (id l in lines)
|
|
{
|
|
id line = [l stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
|
if (line == nil || [line length] == 0)
|
|
continue;
|
|
|
|
id kv = [line componentsSeparatedByString:@":"];
|
|
if ([kv count] < 2)
|
|
continue;
|
|
|
|
id key = [kv objectAtIndex:0];
|
|
id value = [kv objectAtIndex:1];
|
|
|
|
if ([key isEqualToString:@"Error"])
|
|
{
|
|
NSLog(@"Error: %@",value);
|
|
continue;
|
|
}
|
|
|
|
if ([key isEqualToString:@"Mod"])
|
|
{
|
|
// Commit prev mod
|
|
if (current != nil)
|
|
{
|
|
id url = [gameURL URLByAppendingPathComponent:[NSString stringWithFormat:@"mods/%@",current]];
|
|
[ret addObject:[Mod modWithId:current fields:fields baseURL:url]];
|
|
}
|
|
NSLog(@"Parsing mod %@",value);
|
|
current = value;
|
|
fields = [NSMutableDictionary dictionary];
|
|
}
|
|
|
|
if (fields != nil)
|
|
[fields setObject:[value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]
|
|
forKey:key];
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
-(void)launchGame
|
|
{
|
|
// 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];
|
|
|
|
FSRef appRef;
|
|
CFURLGetFSRef((CFURLRef)[NSURL URLWithString:path], &appRef);
|
|
|
|
// Set the launch parameters
|
|
LSApplicationParameters params;
|
|
params.version = 0;
|
|
params.flags = kLSLaunchDefaults;
|
|
params.application = &appRef;
|
|
params.asyncLaunchRefCon = NULL;
|
|
params.environment = NULL; // CFDictionaryRef of environment variables; could be useful
|
|
params.argv = (CFArrayRef)args;
|
|
params.initialEvent = NULL;
|
|
|
|
ProcessSerialNumber psn;
|
|
OSStatus err = LSOpenApplication(¶ms, &psn);
|
|
|
|
// Bring the game window to the front
|
|
if (err == noErr)
|
|
SetFrontProcess(&psn);
|
|
}
|
|
|
|
- (NSString *)runUtilityQuery:(NSString *)arg
|
|
{
|
|
NSTask *aTask = [[NSTask alloc] init];
|
|
NSPipe *aPipe = [NSPipe pipe];
|
|
NSFileHandle *readHandle = [aPipe fileHandleForReading];
|
|
|
|
NSMutableArray *taskArgs = [NSMutableArray arrayWithObject:@"OpenRA.Utility.exe"];
|
|
[taskArgs addObject:arg];
|
|
|
|
[aTask setCurrentDirectoryPath:[gameURL absoluteString]];
|
|
[aTask setLaunchPath:@"/Library/Frameworks/Mono.framework/Commands/mono"];
|
|
[aTask setArguments:taskArgs];
|
|
[aTask setStandardOutput:aPipe];
|
|
[aTask setStandardError:[aTask standardOutput]];
|
|
[aTask launch];
|
|
NSData *data = [readHandle readDataToEndOfFile];
|
|
[aTask release];
|
|
|
|
return [NSString stringWithUTF8String:[data bytes]];
|
|
}
|
|
|
|
|
|
- (void)runUtilityQuery:(NSString *)arg handleOutput:(id)obj withMethod:(SEL)sel
|
|
{
|
|
NSTask *aTask = [[NSTask alloc] init];
|
|
NSPipe *aPipe = [NSPipe pipe];
|
|
NSFileHandle *readHandle = [aPipe fileHandleForReading];
|
|
|
|
NSMutableArray *taskArgs = [NSMutableArray arrayWithObject:@"OpenRA.Utility.exe"];
|
|
[taskArgs addObject:arg];
|
|
|
|
[aTask setCurrentDirectoryPath:[gameURL absoluteString]];
|
|
[aTask setLaunchPath:@"/Library/Frameworks/Mono.framework/Commands/mono"];
|
|
[aTask setArguments:taskArgs];
|
|
[aTask setStandardOutput:aPipe];
|
|
[aTask launch];
|
|
|
|
NSData *inData = nil;
|
|
while ((inData = [readHandle availableData]) && [inData length])
|
|
[obj performSelector:sel withObject:[NSString stringWithUTF8String:[inData bytes]]];
|
|
[aTask waitUntilExit];
|
|
[aTask release];
|
|
}
|
|
|
|
@end
|