// // Network.m // Pong // // Created by Jeena on 27.02.11. // Copyright 2011 __MyCompanyName__. All rights reserved. // #import "GGSNetwork.h" @implementation GGSNetwork #define GGS_HOST @"localhost" #define GGS_PORT 9000 #define NO_TIMEOUT -1 #define HEADER_DELIMITER [@"\n\n" dataUsingEncoding:NSUTF8StringEncoding] #define CONNECT_HEAD 8 #define CONNECT_BODY 9 #define HELLO_HEAD 10 #define HELLO_BODY 11 #define DEFINE_HEAD 12 #define DEFINE_BODY 13 #define COMMAND_HEAD 14 #define COMMAND_BODY 15 @synthesize asyncSocket, delegate, gameToken, currentHeaders; - (id)initWithDelegate:(id)_delegate { if (self = [super init]) { delegate = _delegate; asyncSocket = [[AsyncSocket alloc] initWithDelegate:self]; [asyncSocket connectToHost:GGS_HOST onPort:GGS_PORT error:nil]; [asyncSocket readDataToData:HEADER_DELIMITER withTimeout:NO_TIMEOUT tag:CONNECT_HEAD]; } return self; } - (NSData *)makeMessageWithCommand:(NSString *)command andArgs:(NSString *)args { return [[NSString stringWithFormat:@"Token: %@\nServer-Command: %@\nContent-Length: %i\n\n%@", self.gameToken, command, [args length], args] dataUsingEncoding:NSUTF8StringEncoding]; } - (void)define:(NSString *)sourceCode { [asyncSocket writeData:[self makeMessageWithCommand:@"define" andArgs:sourceCode] withTimeout:NO_TIMEOUT tag:DEFINE_HEAD]; [asyncSocket readDataToData:HEADER_DELIMITER withTimeout:NO_TIMEOUT tag:DEFINE_BODY]; } - (void)sendCommand:(NSString *)command withArgs:(NSString *)args { [asyncSocket writeData:[self makeMessageWithCommand:command andArgs:args] withTimeout:NO_TIMEOUT tag:COMMAND_HEAD]; [asyncSocket readDataToData:HEADER_DELIMITER withTimeout:NO_TIMEOUT tag:COMMAND_BODY]; } - (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port { } - (void)onSocket:(AsyncSocket *)sender didReadData:(NSData *)data withTag:(long)tag { if (tag == CONNECT_HEAD) { [self parseHeader:data]; if ([self.currentHeaders objectForKey:@"Size"] != nil) { [asyncSocket readDataToLength:[[self.currentHeaders objectForKey:@"Size"] intValue] withTimeout:NO_TIMEOUT tag:CONNECT_BODY]; } } else if (tag == CONNECT_BODY) { NSString *response = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; self.gameToken = response; [response release]; [delegate GGSNetwork:self ready:YES]; } else if (tag == DEFINE_HEAD) { [self.delegate GGSNetwork:self defined:YES]; } else if (tag == DEFINE_BODY) { // nothing to do } else if (tag == COMMAND_HEAD) { [self parseHeader:data]; if ([self.currentHeaders objectForKey:@"Size"] != nil) { [asyncSocket readDataToLength:[[self.currentHeaders objectForKey:@"Size"] intValue] withTimeout:NO_TIMEOUT tag:COMMAND_BODY]; } } else if (tag == COMMAND_BODY) { NSString *response = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; if ([self.currentHeaders objectForKey:@"Client-Command"] != nil) { [delegate GGSNetwork:self receivedCommand:[self.currentHeaders objectForKey:@"Client-Command"] withArgs:response]; [asyncSocket readDataToData:HEADER_DELIMITER withTimeout:NO_TIMEOUT tag:COMMAND_BODY]; } [response release]; } } - (void)parseHeader:(NSData *)headerData { NSString *headerString = [[NSString alloc] initWithData:headerData encoding:NSUTF8StringEncoding]; NSArray *headers = [headerString componentsSeparatedByString:@"\n"]; NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:[headers count]]; for (NSInteger i=0; i<[headers count]; i++) { NSString *header = [headers objectAtIndex:i]; if ([header rangeOfString:@"Client-Command: "].location == 0) { [dict setValue:[header substringFromIndex:16] forKey:@"Client-Command"]; } else if ([header rangeOfString:@"Size: "].location == 0) { [dict setValue:[header substringFromIndex:6] forKey:@"Size"]; } } self.currentHeaders = dict; [headerString release]; [dict release]; } - (void)dealloc { [asyncSocket release]; [gameToken release]; [currentHeaders release]; [super dealloc]; } @end