--- a/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.h Fri Nov 11 01:18:19 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.h Fri Nov 11 01:40:23 2011 +0100
@@ -32,17 +32,21 @@
id<EngineProtocolDelegate> delegate;
NSOutputStream *stream;
- TCPsocket csd; // Client socket descriptor
+ TCPsocket csd;
+ NSInteger enginePort;
}
@property (nonatomic,assign) id<EngineProtocolDelegate> delegate;
@property (nonatomic,retain) NSOutputStream *stream;
@property (assign) TCPsocket csd;
+@property (assign) NSInteger enginePort;
-(id) init;
--(NSInteger) spawnThread:(NSString *)onSaveFile withOptions:(NSDictionary *)dictionary;
++(void) spawnThread:(NSString *)onSaveFile withOptions:(NSDictionary *)dictionary;
++(NSInteger) activeEnginePort;
+
-(void) engineProtocol:(id) object;
-(void) gameHasEndedWithStats:(NSArray *)stats;
--- a/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.m Fri Nov 11 01:18:19 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.m Fri Nov 11 01:40:23 2011 +0100
@@ -25,8 +25,10 @@
#define BUFFER_SIZE 255 // like in original frontend
+static NSInteger activeEnginePort;
+
@implementation EngineProtocolNetwork
-@synthesize delegate, stream, csd;
+@synthesize delegate, stream, csd, enginePort;
-(id) init {
if (self = [super init]) {
@@ -34,7 +36,9 @@
self.csd = NULL;
self.stream = nil;
+ self.enginePort = [HWUtils randomPort];
}
+ activeEnginePort = self.enginePort;
return self;
}
@@ -53,21 +57,20 @@
#pragma mark -
#pragma mark Spawner functions
--(NSInteger) spawnThread:(NSString *)onSaveFile withOptions:(NSDictionary *)dictionary {
- [self retain];
- self.stream = (onSaveFile) ? [[NSOutputStream alloc] initToFileAtPath:onSaveFile append:YES] : nil;
- [self.stream open];
++(void) spawnThread:(NSString *)onSaveFile withOptions:(NSDictionary *)dictionary {
+ EngineProtocolNetwork *proto = [[EngineProtocolNetwork alloc] init];
+ proto.stream = (onSaveFile) ? [[NSOutputStream alloc] initToFileAtPath:onSaveFile append:YES] : nil;
+ [proto.stream open];
- NSInteger ipcPort = [HWUtils randomPort];
- NSDictionary *config = [[NSDictionary alloc] initWithObjectsAndKeys:
- [NSNumber numberWithInt:ipcPort],@"port",
- dictionary,@"config", nil];
+ // +detachNewThreadSelector retain/release self automatically
[NSThread detachNewThreadSelector:@selector(engineProtocol:)
- toTarget:self
- withObject:config];
- [config release];
+ toTarget:proto
+ withObject:dictionary];
+ [proto release];
+}
- return ipcPort;
++(NSInteger) activeEnginePort {
+ return activeEnginePort;
}
#pragma mark -
@@ -228,8 +231,7 @@
// this is launched as thread and handles all IPC with engine
-(void) engineProtocol:(id) object {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSDictionary *gameConfig = [(NSDictionary *)object objectForKey:@"config"];
- NSInteger port = [[(NSDictionary *)object objectForKey:@"port"] intValue];
+ NSDictionary *gameConfig = (NSDictionary *)object;
NSMutableArray *statsArray = nil;
TCPsocket sd;
IPaddress ip;
@@ -247,18 +249,18 @@
}
// Resolving the host using NULL make network interface to listen
- if (SDLNet_ResolveHost(&ip, NULL, port) < 0 && !clientQuit) {
+ if (SDLNet_ResolveHost(&ip, NULL, self.enginePort) < 0 && !clientQuit) {
DLog(@"SDLNet_ResolveHost: %s\n", SDLNet_GetError());
clientQuit = YES;
}
// Open a connection with the IP provided (listen on the host's port)
if (!(sd = SDLNet_TCP_Open(&ip)) && !clientQuit) {
- DLog(@"SDLNet_TCP_Open: %s %\n", SDLNet_GetError(), port);
+ DLog(@"SDLNet_TCP_Open: %s %\n", SDLNet_GetError(), self.enginePort);
clientQuit = YES;
}
- DLog(@"Waiting for a client on port %d", port);
+ DLog(@"Waiting for a client on port %d", self.enginePort);
while (csd == NULL)
csd = SDLNet_TCP_Accept(sd);
SDLNet_TCP_Close(sd);
@@ -413,8 +415,6 @@
SDLNet_Quit();
[pool release];
-
- [self performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:YES];
// Invoking this method should be avoided as it does not give your thread a chance
// to clean up any resources it allocated during its execution.
//[NSThread exit];
--- a/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.h Fri Nov 11 01:18:19 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.h Fri Nov 11 01:40:23 2011 +0100
@@ -23,11 +23,9 @@
@interface GameInterfaceBridge : NSObject {
- NSInteger ipcPort;
UIView *blackView;
}
-@property (assign) NSInteger ipcPort;
@property (nonatomic,retain) UIView *blackView;
+(void) startLocalGame:(NSDictionary *)withOptions;
--- a/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.m Fri Nov 11 01:18:19 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.m Fri Nov 11 01:40:23 2011 +0100
@@ -27,7 +27,7 @@
#import "ObjcExports.h"
@implementation GameInterfaceBridge
-@synthesize ipcPort, blackView;
+@synthesize blackView;
#pragma mark -
#pragma mark Instance methods for engine interaction
@@ -35,10 +35,7 @@
-(void) earlyEngineLaunch:(NSString *)pathOrNil withOptions:(NSDictionary *)optionsOrNil {
[self retain];
[AudioManagerController stopBackgroundMusic];
-
- EngineProtocolNetwork *proto = [[EngineProtocolNetwork alloc] init];
- self.ipcPort = [proto spawnThread:pathOrNil withOptions:optionsOrNil];
- [proto release];
+ [EngineProtocolNetwork spawnThread:pathOrNil withOptions:optionsOrNil];
// add a black view hiding the background
CGRect theFrame = [[UIScreen mainScreen] bounds];
@@ -90,8 +87,9 @@
-(void) engineLaunch:(NSString *)pathOrNil {
const char *gameArgs[11];
CGFloat width, height;
+ NSInteger enginePort = [EngineProtocolNetwork activeEnginePort];
CGFloat screenScale = [[UIScreen mainScreen] safeScale];
- NSString *ipcString = [[NSString alloc] initWithFormat:@"%d",self.ipcPort];
+ NSString *ipcString = [[NSString alloc] initWithFormat:@"%d",enginePort];
NSString *localeString = [[NSString alloc] initWithFormat:@"%@.txt",[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]];
NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
@@ -158,10 +156,14 @@
#pragma mark -
#pragma mark Class methods for setting up the engine from outsite
-// set up variables for a local game
++(void) startGame:(TGameType) type atPath:(NSString *)path withOptions:(NSDictionary *)config {
+ [HWUtils setGameType:type];
+ GameInterfaceBridge *bridge = [[GameInterfaceBridge alloc] init];
+ [bridge earlyEngineLaunch:path withOptions:config];
+ [bridge release];
+}
+
+(void) startLocalGame:(NSDictionary *)withOptions {
- [HWUtils setGameType:gtLocal];
-
NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
[outputFormatter setDateFormat:@"yyyy-MM-dd '@' HH.mm"];
NSString *savePath = [[NSString alloc] initWithFormat:@"%@%@.hws",SAVES_DIRECTORY(),[outputFormatter stringFromDate:[NSDate date]]];
@@ -171,30 +173,20 @@
if ([[NSFileManager defaultManager] fileExistsAtPath:savePath])
[[NSFileManager defaultManager] removeItemAtPath:savePath error:nil];
- GameInterfaceBridge *bridge = [[GameInterfaceBridge alloc] init];
- [bridge earlyEngineLaunch:savePath withOptions:withOptions];
- [bridge release];
+ [self startGame:gtLocal atPath:savePath withOptions:withOptions];
[savePath release];
}
-// set up variables for a save game
+(void) startSaveGame:(NSString *)atPath {
- [HWUtils setGameType:gtSave];
- GameInterfaceBridge *bridge = [[GameInterfaceBridge alloc] init];
- [bridge earlyEngineLaunch:atPath withOptions:nil];
- [bridge release];
+ [self startGame:gtSave atPath:atPath withOptions:nil];
}
+(void) startMissionGame:(NSString *)withScript {
- [HWUtils setGameType:gtMission];
-
NSString *missionPath = [[NSString alloc] initWithFormat:@"escript Missions/Training/%@.lua",withScript];
NSDictionary *missionLine = [[NSDictionary alloc] initWithObjectsAndKeys:missionPath,@"mission_command",nil];
[missionPath release];
- GameInterfaceBridge *bridge = [[GameInterfaceBridge alloc] init];
- [bridge earlyEngineLaunch:nil withOptions:missionLine];
- [bridge release];
+ [self startGame:gtMission atPath:nil withOptions:missionLine];
[missionLine release];
}
--- a/project_files/HedgewarsMobile/Classes/HWUtils.m Fri Nov 11 01:18:19 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/HWUtils.m Fri Nov 11 01:40:23 2011 +0100
@@ -25,6 +25,7 @@
#import <netinet/in.h>
#import <SystemConfiguration/SCNetworkReachability.h>
#import "hwconsts.h"
+#import "EngineProtocolNetwork.h"
static NSString *cachedModel = nil;
static NSArray *cachedColors = nil;
@@ -96,7 +97,11 @@
+(NSInteger) randomPort {
srandom(time(NULL));
NSInteger res = (random() % 64511) + 1024;
- return (res == NETGAME_DEFAULT_PORT) ? [HWUtils randomPort] : res;
+ // recall self until you get a free port
+ if (res == NETGAME_DEFAULT_PORT || res == [EngineProtocolNetwork activeEnginePort])
+ return [self randomPort];
+ else
+ return res;
}
+(BOOL) isNetworkReachable {
--- a/project_files/HedgewarsMobile/Classes/RestoreViewController.m Fri Nov 11 01:18:19 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/RestoreViewController.m Fri Nov 11 01:40:23 2011 +0100
@@ -36,14 +36,13 @@
if (theButton.tag != 0) {
[AudioManagerController playClickSound];
- [self.parentViewController dismissModalViewControllerAnimated:NO];
[[NSNotificationCenter defaultCenter] postNotificationName:@"launchRestoredGame" object:nil];
} else {
[AudioManagerController playBackSound];
[defaults setObject:@"" forKey:@"savedGamePath"];
[defaults synchronize];
- [self.parentViewController dismissModalViewControllerAnimated:YES];
}
+ [self.parentViewController dismissModalViewControllerAnimated:YES];
}
-(void) viewDidLoad {