project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.m
changeset 6265 a6944f94c19f
parent 6263 ec41637ceb64
child 6301 1259736c0134
equal deleted inserted replaced
6264:62d59a87daad 6265:a6944f94c19f
    24 
    24 
    25 
    25 
    26 #define BUFFER_SIZE 255     // like in original frontend
    26 #define BUFFER_SIZE 255     // like in original frontend
    27 
    27 
    28 @implementation EngineProtocolNetwork
    28 @implementation EngineProtocolNetwork
    29 @synthesize delegate, stream, ipcPort, csd;
    29 @synthesize delegate, stream, csd;
    30 
    30 
    31 -(id) init {
    31 -(id) init {
    32     if (self = [super init]) {
    32     if (self = [super init]) {
    33         self.delegate = nil;
    33         self.delegate = nil;
    34 
    34 
    35         self.ipcPort = 0;
       
    36         self.csd = NULL;
    35         self.csd = NULL;
    37         self.stream = nil;
    36         self.stream = nil;
    38     }
    37     }
    39     return self;
       
    40 }
       
    41 
       
    42 -(id) initOnPort:(NSInteger) port {
       
    43     if (self = [self init])
       
    44         self.ipcPort = port;
       
    45     return self;
    38     return self;
    46 }
    39 }
    47 
    40 
    48 -(void) gameHasEndedWithStats:(NSArray *)stats {
    41 -(void) gameHasEndedWithStats:(NSArray *)stats {
    49     if (self.delegate != nil && [self.delegate respondsToSelector:@selector(gameHasEndedWithStats:)])
    42     if (self.delegate != nil && [self.delegate respondsToSelector:@selector(gameHasEndedWithStats:)])
    58     [super dealloc];
    51     [super dealloc];
    59 }
    52 }
    60 
    53 
    61 #pragma mark -
    54 #pragma mark -
    62 #pragma mark Spawner functions
    55 #pragma mark Spawner functions
    63 -(void) spawnThread:(NSString *)onSaveFile {
    56 -(NSInteger) spawnThread:(NSString *)onSaveFile withOptions:(NSDictionary *)dictionary {
    64     [self spawnThread:onSaveFile withOptions:nil];
       
    65 }
       
    66 
       
    67 -(void) spawnThread:(NSString *)onSaveFile withOptions:(NSDictionary *)dictionary {
       
    68     self.stream = (onSaveFile) ? [[NSOutputStream alloc] initToFileAtPath:onSaveFile append:YES] : nil;
    57     self.stream = (onSaveFile) ? [[NSOutputStream alloc] initToFileAtPath:onSaveFile append:YES] : nil;
    69     [self.stream open];
    58     [self.stream open];
    70 
    59 
       
    60     NSInteger ipcPort = [HWUtils randomPort];
       
    61     NSDictionary *config = [[NSDictionary alloc] initWithObjectsAndKeys:
       
    62                             [NSNumber numberWithInt:ipcPort],@"port",
       
    63                             dictionary,@"config", nil];
    71     [NSThread detachNewThreadSelector:@selector(engineProtocol:)
    64     [NSThread detachNewThreadSelector:@selector(engineProtocol:)
    72                              toTarget:self
    65                              toTarget:self
    73                            withObject:dictionary];
    66                            withObject:config];
       
    67     [config release];
       
    68 
       
    69     return ipcPort;
    74 }
    70 }
    75 
    71 
    76 #pragma mark -
    72 #pragma mark -
    77 #pragma mark Provider functions
    73 #pragma mark Provider functions
    78 // unpacks team data from the selected team.plist to a sequence of engine commands
    74 // unpacks team data from the selected team.plist to a sequence of engine commands
   229 }
   225 }
   230 
   226 
   231 // this is launched as thread and handles all IPC with engine
   227 // this is launched as thread and handles all IPC with engine
   232 -(void) engineProtocol:(id) object {
   228 -(void) engineProtocol:(id) object {
   233     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   229     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   234     NSDictionary *gameConfig = (NSDictionary *)object;
   230     NSDictionary *gameConfig = [(NSDictionary *)object objectForKey:@"config"];
       
   231     NSInteger port = [[(NSDictionary *)object objectForKey:@"port"] intValue];
   235     NSMutableArray *statsArray = nil;
   232     NSMutableArray *statsArray = nil;
   236     TCPsocket sd;
   233     TCPsocket sd;
   237     IPaddress ip;
   234     IPaddress ip;
   238     int eProto;
   235     int eProto;
   239     BOOL clientQuit;
   236     BOOL clientQuit;
   247         DLog(@"SDLNet_Init: %s", SDLNet_GetError());
   244         DLog(@"SDLNet_Init: %s", SDLNet_GetError());
   248         clientQuit = YES;
   245         clientQuit = YES;
   249     }
   246     }
   250 
   247 
   251     // Resolving the host using NULL make network interface to listen
   248     // Resolving the host using NULL make network interface to listen
   252     if (SDLNet_ResolveHost(&ip, NULL, ipcPort) < 0 && !clientQuit) {
   249     if (SDLNet_ResolveHost(&ip, NULL, port) < 0 && !clientQuit) {
   253         DLog(@"SDLNet_ResolveHost: %s\n", SDLNet_GetError());
   250         DLog(@"SDLNet_ResolveHost: %s\n", SDLNet_GetError());
   254         clientQuit = YES;
   251         clientQuit = YES;
   255     }
   252     }
   256 
   253 
   257     // Open a connection with the IP provided (listen on the host's port)
   254     // Open a connection with the IP provided (listen on the host's port)
   258     if (!(sd = SDLNet_TCP_Open(&ip)) && !clientQuit) {
   255     if (!(sd = SDLNet_TCP_Open(&ip)) && !clientQuit) {
   259         DLog(@"SDLNet_TCP_Open: %s %\n", SDLNet_GetError(), ipcPort);
   256         DLog(@"SDLNet_TCP_Open: %s %\n", SDLNet_GetError(), port);
   260         clientQuit = YES;
   257         clientQuit = YES;
   261     }
   258     }
   262 
   259 
   263     DLog(@"Waiting for a client on port %d", ipcPort);
   260     DLog(@"Waiting for a client on port %d", port);
   264     while (csd == NULL)
   261     while (csd == NULL)
   265         csd = SDLNet_TCP_Accept(sd);
   262         csd = SDLNet_TCP_Accept(sd);
   266     SDLNet_TCP_Close(sd);
   263     SDLNet_TCP_Close(sd);
   267 
   264 
   268     while (!clientQuit) {
   265     while (!clientQuit) {
   392                         break;
   389                         break;
   393                 }
   390                 }
   394                 break;
   391                 break;
   395             case 'q':
   392             case 'q':
   396                 // game ended, can remove the savefile and present the statistics of the match
   393                 // game ended, can remove the savefile and present the statistics of the match
       
   394                 [HWUtils setGameStatus:gsEnded];
   397                 [self gameHasEndedWithStats:statsArray];
   395                 [self gameHasEndedWithStats:statsArray];
   398                 break;
   396                 break;
   399             case 'Q':
   397             case 'Q':
   400                 // game exited but not completed, nothing to do (just don't save the message)
   398                 // game exited but not completed, nothing to do (just don't save the message)
   401                 break;
   399                 break;