project_files/HedgewarsMobile/Classes/GameSetup.m
changeset 3902 3aac7ca07b0e
parent 3898 0a9c3735a713
child 3904 22e4d74240e5
equal deleted inserted replaced
3900:5fe24180fc72 3902:3aac7ca07b0e
    24 #import "SDL_net.h"
    24 #import "SDL_net.h"
    25 #import "PascalImports.h"
    25 #import "PascalImports.h"
    26 #import "CommodityFunctions.h"
    26 #import "CommodityFunctions.h"
    27 #import "NSStringExtra.h"
    27 #import "NSStringExtra.h"
    28 
    28 
    29 #define BUFFER_SIZE 64
    29 #define BUFFER_SIZE 255     // like in original frontend
    30 
    30 
    31 @implementation GameSetup
    31 @implementation GameSetup
    32 @synthesize systemSettings, gameConfig, savePath;
    32 @synthesize systemSettings, gameConfig, savePath;
    33 
    33 
    34 -(id) initWithDictionary:(NSDictionary *)gameDictionary {
    34 -(id) initWithDictionary:(NSDictionary *)gameDictionary {
   253 // wrapper that computes the length of the message and then sends the command string, saving the command on a file
   253 // wrapper that computes the length of the message and then sends the command string, saving the command on a file
   254 -(int) sendToEngine: (NSString *)string {
   254 -(int) sendToEngine: (NSString *)string {
   255     uint8_t length = [string length];
   255     uint8_t length = [string length];
   256 
   256 
   257     [[NSString stringWithFormat:@"%c%@",length,string] appendToFile:savePath];
   257     [[NSString stringWithFormat:@"%c%@",length,string] appendToFile:savePath];
   258     SDLNet_TCP_Send(csd, &length , 1);
   258     SDLNet_TCP_Send(csd, &length, 1);
   259     return SDLNet_TCP_Send(csd, [string UTF8String], length);
   259     return SDLNet_TCP_Send(csd, [string UTF8String], length);
   260 }
   260 }
   261 
   261 
   262 // wrapper that computes the length of the message and then sends the command string, skipping file writing
   262 // wrapper that computes the length of the message and then sends the command string, skipping file writing
   263 -(int) sendToEngineNoSave: (NSString *)string {
   263 -(int) sendToEngineNoSave: (NSString *)string {
   264     uint8_t length = [string length];
   264     uint8_t length = [string length];
   265 
   265 
   266     SDLNet_TCP_Send(csd, &length , 1);
   266     SDLNet_TCP_Send(csd, &length, 1);
   267     return SDLNet_TCP_Send(csd, [string UTF8String], length);
   267     return SDLNet_TCP_Send(csd, [string UTF8String], length);
   268 }
   268 }
   269 
   269 
   270 // method that handles net setup with engine and keeps connection alive
   270 // method that handles net setup with engine and keeps connection alive
   271 -(void) engineProtocol {
   271 -(void) engineProtocol {
   272     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   272     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   273     TCPsocket sd;
   273     TCPsocket sd;
   274     IPaddress ip;
   274     IPaddress ip;
   275     int eProto;
   275     int eProto;
   276     BOOL clientQuit;
   276     BOOL clientQuit;
   277     char buffer[BUFFER_SIZE];
   277     uint8_t buffer[BUFFER_SIZE];
   278     uint8_t msgSize;
   278     uint8_t msgSize;
   279     uint16_t gameTicks;
       
   280 
   279 
   281     clientQuit = NO;
   280     clientQuit = NO;
   282     csd = NULL;
   281     csd = NULL;
   283 
   282 
   284     if (SDLNet_Init() < 0) {
   283     if (SDLNet_Init() < 0) {
   302     while (csd == NULL)
   301     while (csd == NULL)
   303         csd = SDLNet_TCP_Accept(sd);
   302         csd = SDLNet_TCP_Accept(sd);
   304     SDLNet_TCP_Close(sd);
   303     SDLNet_TCP_Close(sd);
   305 
   304 
   306     while (!clientQuit) {
   305     while (!clientQuit) {
       
   306         NSString *msgToSave = nil;
       
   307         NSOutputStream *os = nil;
   307         msgSize = 0;
   308         msgSize = 0;
   308         memset(buffer, 0, BUFFER_SIZE);
   309         memset(buffer, '\0', BUFFER_SIZE);
   309         if (SDLNet_TCP_Recv(csd, &msgSize, sizeof(uint8_t)) <= 0)
   310         if (SDLNet_TCP_Recv(csd, &msgSize, sizeof(uint8_t)) <= 0)
   310             clientQuit = YES;
   311             break;
   311         if (SDLNet_TCP_Recv(csd, buffer, msgSize) <=0)
   312         if (SDLNet_TCP_Recv(csd, buffer, msgSize) <=0)
   312             clientQuit = YES;
   313             break;
   313 
   314 
   314         switch (buffer[0]) {
   315         switch (buffer[0]) {
   315             case 'C':
   316             case 'C':
   316                 DLog(@"sending game config...\n%@",self.gameConfig);
   317                 DLog(@"sending game config...\n%@",self.gameConfig);
   317 
   318 
   358             case 'E':
   359             case 'E':
   359                 DLog(@"ERROR - last console line: [%s]", &buffer[1]);
   360                 DLog(@"ERROR - last console line: [%s]", &buffer[1]);
   360                 clientQuit = YES;
   361                 clientQuit = YES;
   361                 break;
   362                 break;
   362             case 'e':
   363             case 'e':
   363                 buffer[msgSize] = '\0';
   364                 msgToSave = [NSString stringWithFormat:@"%c%s",msgSize,buffer];                
   364                 [[NSString stringWithUTF8String:buffer] appendToFile:savePath];
   365                 [msgToSave appendToFile:self.savePath];
   365                 sscanf(buffer, "%*s %d", &eProto);
   366                 
       
   367                 sscanf((char *)buffer, "%*s %d", &eProto);
   366                 short int netProto = 0;
   368                 short int netProto = 0;
   367                 char *versionStr;
   369                 char *versionStr;
   368 
   370 
   369                 HW_versionInfo(&netProto, &versionStr);
   371                 HW_versionInfo(&netProto, &versionStr);
   370                 if (netProto == eProto) {
   372                 if (netProto == eProto) {
   376 
   378 
   377                 break;
   379                 break;
   378             case 'i':
   380             case 'i':
   379                 switch (buffer[1]) {
   381                 switch (buffer[1]) {
   380                     case 'r':
   382                     case 'r':
   381                         NSLog(@"Winning team: %s", &buffer[2]);
   383                         DLog(@"Winning team: %s", &buffer[2]);
   382                         break;
   384                         break;
   383                     case 'k':
   385                     case 'k':
   384                         NSLog(@"Best Hedgehog: %s", &buffer[2]);
   386                         DLog(@"Best Hedgehog: %s", &buffer[2]);
       
   387                         break;
       
   388                     default:
       
   389                         // TODO: losta stats stuff
   385                         break;
   390                         break;
   386                 }
   391                 }
   387                 break;
   392                 break;
       
   393             case 'q':
       
   394                 // game ended, can remove the savefile
       
   395                 [[NSFileManager defaultManager] removeItemAtPath:self.savePath error:nil];
       
   396                 break;
   388             default:
   397             default:
   389                 // empty packet or just statistics -- in either cases gameTicks is sent
   398                 // is it performant to reopen the stream every time? 
   390                 gameTicks = SDLNet_Read16 (&buffer[msgSize - 2]);
   399                 os = [[NSOutputStream alloc] initToFileAtPath:self.savePath append:YES];
   391                 DLog(@"engineProtocol - %d: received [%s]", gameTicks, buffer);
   400                 [os open];
   392                 buffer[msgSize] = '\0';
   401                 [os write:&msgSize maxLength:1];
   393                 [[NSString stringWithUTF8String:buffer] appendToFile:savePath];
   402                 [os write:buffer maxLength:msgSize];
       
   403                 [os close];
       
   404                 [os release];
   394                 break;
   405                 break;
   395         }
   406         }
   396     }
   407     }
   397     DLog(@"Engine exited, closing server");
   408     DLog(@"Engine exited, closing server");
   398     // wait a little to let the client close cleanly
   409     // wait a little to let the client close cleanly