422 lines
16 KiB
Objective-C
Executable File
422 lines
16 KiB
Objective-C
Executable File
#import "wagicAppDelegate.h"
|
|
#import "EAGLView.h"
|
|
#import "EAGLViewController.h"
|
|
#import "ASIHTTPRequest.h"
|
|
#import "ZipArchive.h"
|
|
#include "Wagic_Version.h"
|
|
|
|
#include <CommonCrypto/CommonDigest.h>
|
|
|
|
@implementation wagicAppDelegate
|
|
|
|
@synthesize window;
|
|
@synthesize glViewController;
|
|
@synthesize wagicDownloadController;
|
|
@synthesize hostReach, wifiReach, internetReach;
|
|
|
|
- (void) updateComplete: (id) notificationMsg
|
|
{
|
|
NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter];
|
|
|
|
[dnc removeObserver: self name: @"coreComplete" object: nil];
|
|
[dnc removeObserver: self name: @"iosConfigComplete" object: nil];
|
|
[dnc postNotificationName: @"initializeGame" object: self];
|
|
|
|
}
|
|
|
|
- (void) initIosUpdate: (id) notificationMsg
|
|
{
|
|
NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter];
|
|
[dnc addObserver: self selector: @selector(updateComplete:) name: @"iosConfigComplete" object: nil];
|
|
[wagicDownloadController performSelectorInBackground: @selector(startDownload:) withObject:@"iosConfig"];
|
|
}
|
|
|
|
- (void) downloadResources
|
|
{
|
|
NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter];
|
|
|
|
[dnc addObserver:self selector:@selector(initIosUpdate:) name:@"coreComplete" object: nil];
|
|
|
|
wagicDownloadController = [[WagicDownloadProgressViewController alloc] init];
|
|
[wagicDownloadController performSelectorInBackground: @selector(startDownload:) withObject:@"core"];
|
|
|
|
[self.window addSubview: wagicDownloadController.view];
|
|
[self.window makeKeyWindow];
|
|
|
|
}
|
|
|
|
/* unpackage the zip file and delete it afterwards */
|
|
- (void) unpackageResources: (NSString *) folderName pathPrefixName: (NSString *) pathNamePrefix
|
|
{
|
|
NSString *pathPrefix = nil;
|
|
if ( pathNamePrefix == nil ) // default to User
|
|
pathPrefix = @"User";
|
|
else
|
|
pathPrefix = pathNamePrefix;
|
|
|
|
NSError *error = nil;
|
|
|
|
NSFileManager *fm = [NSFileManager defaultManager];
|
|
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES);
|
|
NSString *userDocumentsDirectory = [paths objectAtIndex:0];
|
|
NSString *downloadFilePath = [userDocumentsDirectory stringByAppendingString: [NSString stringWithFormat: @"/%@/%@.zip", pathPrefix, folderName]];
|
|
|
|
ZipArchive *za = [[ZipArchive alloc] init];
|
|
if ([za UnzipOpenFile: downloadFilePath])
|
|
{
|
|
NSString *destinationFilePath = [NSString stringWithFormat: @"%@/%@/",userDocumentsDirectory, pathPrefix];
|
|
NSLog(@"Unzipping %@ to %@", downloadFilePath, destinationFilePath);
|
|
BOOL ret = [za UnzipFileTo: destinationFilePath overWrite: YES];
|
|
if (ret == NO)
|
|
{
|
|
// some error occurred
|
|
NSLog(@"An Error occurred while unpacking zip file.");
|
|
}
|
|
[za UnzipCloseFile];
|
|
|
|
if (ret == YES)
|
|
{
|
|
// delete the archive
|
|
[fm removeItemAtPath: downloadFilePath error: &error];
|
|
if (error != nil)
|
|
{
|
|
NSLog(@"error occurred while trying to delete zip file! %@\n%@", downloadFilePath, [error localizedDescription] );
|
|
}
|
|
}
|
|
}
|
|
[za release], za = nil;
|
|
|
|
}
|
|
|
|
|
|
- (NSString *) getDirContents: (NSString *) path
|
|
{
|
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
NSArray *dirContents = [fileManager contentsOfDirectoryAtPath: path error:nil];
|
|
NSMutableString *data = [[NSMutableString alloc] init ];
|
|
for (NSString *filename in dirContents)
|
|
{
|
|
NSString *pathname = [NSString stringWithFormat: @"%@/%@", path, filename];
|
|
[data appendFormat: @"%@\n", pathname];
|
|
|
|
BOOL isDirectory = [[fileManager attributesOfItemAtPath: pathname error: nil] objectForKey: NSFileType] == NSFileTypeDirectory;
|
|
if (isDirectory)
|
|
[data appendString: [self getDirContents: pathname]];
|
|
}
|
|
|
|
NSString *manifestList = [data stringByAppendingFormat: @"\n"];
|
|
[data release];
|
|
|
|
return manifestList;
|
|
}
|
|
|
|
- (void) createManifest: (NSString *)docsPath
|
|
{
|
|
NSString *manifestFile = [docsPath stringByAppendingPathComponent:@"Manifest"];
|
|
[[self getDirContents: docsPath] writeToFile:manifestFile atomically:YES encoding:NSUTF8StringEncoding error: nil];
|
|
|
|
}
|
|
|
|
/**
|
|
check for any zip files dropped into the documents directory before loading the game.
|
|
If so, move the "core" files into the "Res" directory and move all other zip files into the "User" directory.
|
|
Check for a "core" zip file in the Res directory. If it exists, then return YES. Otherwise, return NO.
|
|
*/
|
|
|
|
- (void) initializeResources
|
|
{
|
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
|
|
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES);
|
|
NSString *docsPath = [paths objectAtIndex: 0];
|
|
NSArray *docsPathContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath: docsPath error:nil];
|
|
NSString *versionPredicate = [NSString stringWithFormat: @"(self BEGINSWITH '%@')", [NSString stringWithCString: WAGIC_CORE_VERSION_STRING encoding:NSUTF8StringEncoding]];
|
|
NSCompoundPredicate *compoundPredicate = [[NSCompoundPredicate alloc] initWithType:NSAndPredicateType subpredicates: [NSArray arrayWithObjects: [NSPredicate predicateWithFormat:@"self ENDSWITH '.zip'"], [NSPredicate predicateWithFormat: [NSString stringWithFormat: @" NOT ( %@ ) ", versionPredicate]], nil]];
|
|
|
|
NSArray *coreFiles = [docsPathContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat: versionPredicate]];
|
|
|
|
NSArray *resourceZipFiles = [docsPathContents filteredArrayUsingPredicate: compoundPredicate];
|
|
NSString *userPath = [NSString stringWithFormat: @"%@/User", docsPath];
|
|
NSString *resPath = [NSString stringWithFormat: @"%@/Res", docsPath];
|
|
NSError *error = nil;
|
|
|
|
[compoundPredicate release], compoundPredicate = nil;
|
|
|
|
if ( ([resourceZipFiles count] > 0 ) && ![fileManager fileExistsAtPath: userPath] )
|
|
[fileManager createDirectoryAtPath: userPath withIntermediateDirectories: YES attributes:nil error:nil ];
|
|
|
|
for (NSString *zipFile in resourceZipFiles)
|
|
{
|
|
NSString *oldPath = [NSString stringWithFormat: @"%@/%@", docsPath, zipFile];
|
|
NSString *newPath = [NSString stringWithFormat: @"%@/%@", userPath, zipFile];
|
|
if ( [fileManager fileExistsAtPath: newPath] )
|
|
{
|
|
NSLog(@"Removing old file at %@", newPath);
|
|
[fileManager removeItemAtPath: newPath error: &error];
|
|
}
|
|
error = nil;
|
|
|
|
[fileManager moveItemAtPath: oldPath toPath:newPath error: &error];
|
|
NSLog(@"Moving %@ to %@", oldPath, newPath);
|
|
if ( error != nil )
|
|
{
|
|
NSLog(@"Error happened while trying to move %@ to %@: \n%@", oldPath, newPath, [error localizedDescription]);
|
|
error = nil;
|
|
}
|
|
}
|
|
|
|
for (NSString *zipFile in coreFiles)
|
|
{
|
|
NSString *oldPath = [NSString stringWithFormat: @"%@/%@", docsPath, zipFile];
|
|
NSString *newPath = [NSString stringWithFormat: @"%@/%@", resPath, zipFile];
|
|
if ( [fileManager fileExistsAtPath: newPath] )
|
|
{
|
|
NSLog(@"Removing old file at %@", newPath);
|
|
[fileManager removeItemAtPath: newPath error: &error];
|
|
}
|
|
error = nil;
|
|
|
|
[fileManager moveItemAtPath: oldPath toPath:newPath error: &error];
|
|
NSLog(@"Moving %@ to %@", oldPath, newPath);
|
|
if ( error != nil )
|
|
{
|
|
NSLog(@"Error happened while trying to move %@ to %@: \n%@", oldPath, newPath, [error localizedDescription]);
|
|
error = nil;
|
|
}
|
|
}
|
|
}
|
|
|
|
- (BOOL) hasResourceFiles
|
|
{
|
|
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES);
|
|
NSString *docsPath = [paths objectAtIndex: 0];
|
|
NSString *resPath = [NSString stringWithFormat: @"%@/Res", docsPath];
|
|
|
|
NSArray *resDirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath: resPath error:nil];
|
|
NSString *versionPredicate = [NSString stringWithFormat: @"(self BEGINSWITH '%@')", [NSString stringWithCString: WAGIC_CORE_VERSION_STRING encoding:NSUTF8StringEncoding]];
|
|
|
|
NSArray *coreFiles = [resDirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat: versionPredicate]];
|
|
|
|
if ([coreFiles count] >= 2)
|
|
{
|
|
return YES;
|
|
}
|
|
|
|
return NO;
|
|
}
|
|
|
|
|
|
- (void)preGameInitialization
|
|
{
|
|
NSString *docsPath = [NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex: 0];
|
|
NSFileManager *fm = [NSFileManager defaultManager];
|
|
NSString *userPath = [docsPath stringByAppendingString: @"/User"];
|
|
|
|
NSArray *userDirectories = [fm contentsOfDirectoryAtPath: userPath error: nil];
|
|
|
|
for (NSString *userFilename in userDirectories)
|
|
{
|
|
NSString *userPathname = [userPath stringByAppendingFormat: @"/%@", userFilename];
|
|
NSString *zipFileName = [userPathname stringByAppendingString: @".zip"];
|
|
|
|
if ([[fm attributesOfItemAtPath: userPathname error: nil] objectForKey: NSFileType] == NSFileTypeDirectory && ([fm fileExistsAtPath:zipFileName]))
|
|
{
|
|
[self unpackageResources: userFilename pathPrefixName: @"User"];
|
|
[fm removeItemAtPath: zipFileName error: nil];
|
|
}
|
|
|
|
else if ( [userFilename hasPrefix: @"ai_decks"] ) // special case to allow manual override of AI decks in User directory
|
|
{
|
|
[self unpackageResources: @"ai_decks" pathPrefixName: @"User/ai/baka"];
|
|
}
|
|
}
|
|
// scan for deck*.txt and collection.dat as well as options.txt in the Documents directory and copy them into the player directory
|
|
NSArray *playerDataFilePredicates = [NSArray arrayWithObjects:
|
|
[NSPredicate predicateWithFormat: @"SELF BEGINSWITH[cd] 'deck' AND SELF ENDSWITH '.txt'"],
|
|
[NSPredicate predicateWithFormat: @"SELF BEGINSWITH[cd] 'options' AND SELF ENDSWITH '.txt'"],
|
|
[NSPredicate predicateWithFormat: @"SELF BEGINSWITH[cd] 'tasks' AND SELF ENDSWITH '.dat'"],
|
|
[NSPredicate predicateWithFormat: @"SELF BEGINSWITH[cd] 'collection' AND SELF ENDSWITH '.dat'"], nil];
|
|
|
|
NSCompoundPredicate *playerDataPredicate = [[NSCompoundPredicate alloc] initWithType:NSOrPredicateType subpredicates: playerDataFilePredicates];
|
|
NSArray *playerDataFiles = [[fm contentsOfDirectoryAtPath: docsPath error: nil] filteredArrayUsingPredicate: playerDataPredicate];
|
|
|
|
for (NSString *file in playerDataFiles)
|
|
{
|
|
NSString *fromPath = [docsPath stringByAppendingFormat: @"/%@", file];
|
|
NSString *toPath = [docsPath stringByAppendingFormat: @"/User/player/%@", [file lowercaseString]];
|
|
[fm moveItemAtPath: fromPath toPath: toPath error: nil];
|
|
}
|
|
|
|
[playerDataPredicate release], playerDataPredicate = nil;
|
|
|
|
[self createManifest: docsPath];
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName: @"readyToStartGame" object: nil];
|
|
}
|
|
|
|
|
|
- (void) startGame
|
|
{
|
|
if (glViewController != nil)
|
|
[glViewController release];
|
|
glViewController = [[EAGLViewController alloc] init];
|
|
|
|
[[[self.window subviews] lastObject] removeFromSuperview];
|
|
[self.window setRootViewController: glViewController];
|
|
|
|
NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter];
|
|
[dnc removeObserver: self name: @"intializeGame" object: nil];
|
|
[dnc removeObserver: self name: @"readyToStartGame" object: nil];
|
|
[dnc addObserver: glViewController selector:@selector(pauseGame) name: UIApplicationWillResignActiveNotification object: nil];
|
|
[dnc addObserver: glViewController selector:@selector(resumeGame) name: UIApplicationDidBecomeActiveNotification object: nil];
|
|
[dnc addObserver: glViewController selector:@selector(resumeGame) name:UIApplicationWillEnterForegroundNotification object: nil];
|
|
[dnc addObserver: glViewController selector:@selector(destroyGame) name:UIApplicationWillTerminateNotification object: nil];
|
|
}
|
|
|
|
|
|
- (void)dealloc
|
|
{
|
|
NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter];
|
|
[dnc removeObserver: glViewController name: UIApplicationDidBecomeActiveNotification object: nil];
|
|
[dnc removeObserver: glViewController name: UIApplicationDidEnterBackgroundNotification object: nil];
|
|
[dnc removeObserver: glViewController name: UIApplicationWillTerminateNotification object: nil];
|
|
[dnc removeObserver: glViewController name: UIApplicationWillResignActiveNotification object: nil];
|
|
[hostReach release];
|
|
[wifiReach release];
|
|
[internetReach release];
|
|
[glViewController release];
|
|
[wagicDownloadController release];
|
|
|
|
[super dealloc];
|
|
}
|
|
|
|
|
|
- (void) setupNetworkListeners
|
|
{
|
|
NSLog(@"App checking network connections");
|
|
|
|
hostReach = [[Reachability reachabilityForGoogleDNS] retain];
|
|
internetReach = [[Reachability reachabilityForInternetConnection] retain];
|
|
wifiReach = [[Reachability reachabilityForLocalWiFi] retain];
|
|
|
|
[hostReach startNotifier];
|
|
[internetReach startNotifier];
|
|
[wifiReach startNotifier];
|
|
}
|
|
|
|
|
|
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
|
{
|
|
self.glViewController = nil;
|
|
|
|
[self setupNetworkListeners];
|
|
|
|
NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter];
|
|
[dnc addObserver:self selector:@selector(preGameInitialization) name:@"initializeGame" object: nil];
|
|
[dnc addObserver:self selector:@selector(startGame) name:@"readyToStartGame" object: nil];
|
|
|
|
[self initializeResources];
|
|
// check to see if the Res folder exists. If it does continue
|
|
// otherwise bring up the download dialog and download the core files
|
|
// once downloaded, extract the files and kick off the game.
|
|
BOOL requiresResourceUpdate = [self hasResourceFiles];
|
|
if (!requiresResourceUpdate)
|
|
{
|
|
[self downloadResources];
|
|
}
|
|
else
|
|
{
|
|
[self preGameInitialization];
|
|
}
|
|
|
|
[self.window setBackgroundColor: [UIColor blackColor]];
|
|
[self.window makeKeyAndVisible];
|
|
|
|
return YES;
|
|
}
|
|
|
|
- (void)applicationWillTerminate:(UIApplication *)application
|
|
{
|
|
[(id)self.glViewController.view destroyGame];
|
|
}
|
|
|
|
- (void)initializeKeyboard: (id) initialState
|
|
{
|
|
[self.glViewController toggleKeyboardWithState: initialState];
|
|
}
|
|
|
|
- (void) handleWEngineCommand:(NSString *) command
|
|
withUIParameters: (CGFloat) x
|
|
yCoordinate: (CGFloat) y
|
|
width: (CGFloat) width
|
|
height: (CGFloat) height
|
|
{
|
|
}
|
|
|
|
- (void)handleWEngineCommand:(NSString *) command withParameter: (NSString *) parameter
|
|
{
|
|
|
|
if ([command isEqualToString: @"displayKeyboard"])
|
|
{
|
|
[self initializeKeyboard: parameter];
|
|
}
|
|
else if ([command isEqualToString: @"combatGuiEndDamage"])
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- (void) rotateBackgroundImage:(UIInterfaceOrientation)fromInterfaceOrientation toInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
|
|
{
|
|
bool isPhone = (UI_USER_INTERFACE_IDIOM()) == UIUserInterfaceIdiomPhone;
|
|
|
|
if (isPhone)
|
|
{
|
|
UIImage *bgImage = [UIImage imageNamed: @"Default-Portrait.png"];
|
|
[[[self.window subviews] objectAtIndex: 0] setBackgroundColor: [UIColor colorWithPatternImage: bgImage]];
|
|
}
|
|
else
|
|
{
|
|
[self.window setBackgroundColor: [UIColor clearColor]];
|
|
if (UIInterfaceOrientationIsLandscape( toInterfaceOrientation)) {
|
|
UIImage *bgImage = [UIImage imageNamed: @"Default-Landscape"];
|
|
[[[self.window subviews] objectAtIndex: 0] setBackgroundColor: [UIColor colorWithPatternImage: bgImage]];
|
|
}
|
|
else {
|
|
UIImage *bgImage = [UIImage imageNamed: @"Default-Portrait.png"];
|
|
[[[self.window subviews] objectAtIndex: 0] setBackgroundColor: [UIColor colorWithPatternImage: bgImage]];
|
|
[self.window setBackgroundColor: [UIColor colorWithPatternImage: bgImage]];
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#pragma mark Application Contents
|
|
|
|
- (BOOL) isNetworkAvailable
|
|
{
|
|
BOOL netAvailable = NO;
|
|
//NSDate *startTime = [[[NSDate alloc ] init] autorelease];
|
|
|
|
hostReach = [[Reachability reachabilityForGoogleDNS] retain];
|
|
|
|
NetworkStatus netStatus = [hostReach currentReachabilityStatus];
|
|
|
|
|
|
if (netStatus == ReachableViaWiFi || netStatus == ReachableViaWWAN) {
|
|
netAvailable = YES;
|
|
}
|
|
|
|
//[[QLog log] logOption: kLogOptionTiming withFormat:@"isNetworkAvailble? %5.2f", [startTime timeIntervalSinceNow]];
|
|
|
|
[hostReach release];
|
|
|
|
return netAvailable;
|
|
}
|
|
|
|
|
|
#pragma mark -
|
|
|
|
@end
|