22 |
22 |
23 @synthesize systemSettings, gameConfig; |
23 @synthesize systemSettings, gameConfig; |
24 |
24 |
25 -(id) init { |
25 -(id) init { |
26 if (self = [super init]) { |
26 if (self = [super init]) { |
27 srandom(time(NULL)); |
|
28 ipcPort = randomPort(); |
27 ipcPort = randomPort(); |
29 |
28 |
30 NSDictionary *dictSett = [[NSDictionary alloc] initWithContentsOfFile:SETTINGS_FILE()]; //should check it exists |
29 // should check they exist and throw and exection if not |
|
30 NSDictionary *dictSett = [[NSDictionary alloc] initWithContentsOfFile:SETTINGS_FILE()]; |
31 self.systemSettings = dictSett; |
31 self.systemSettings = dictSett; |
32 [dictSett release]; |
32 [dictSett release]; |
33 |
33 |
34 NSDictionary *dictGame = [[NSDictionary alloc] initWithContentsOfFile:GAMECONFIG_FILE()]; |
34 NSDictionary *dictGame = [[NSDictionary alloc] initWithContentsOfFile:GAMECONFIG_FILE()]; |
35 self.gameConfig = dictGame; |
35 self.gameConfig = dictGame; |
48 [super dealloc]; |
48 [super dealloc]; |
49 } |
49 } |
50 |
50 |
51 #pragma mark - |
51 #pragma mark - |
52 #pragma mark Thread/Network relevant code |
52 #pragma mark Thread/Network relevant code |
|
53 // select one of GameSetup method and execute it in a seprate thread |
53 -(void) startThread: (NSString *) selector { |
54 -(void) startThread: (NSString *) selector { |
54 SEL usage = NSSelectorFromString(selector); |
55 SEL usage = NSSelectorFromString(selector); |
55 [NSThread detachNewThreadSelector:usage toTarget:self withObject:nil]; |
56 [NSThread detachNewThreadSelector:usage toTarget:self withObject:nil]; |
56 } |
57 } |
57 |
58 |
|
59 // wrapper that computes the length of the message and then sends the command string |
58 -(int) sendToEngine: (NSString *)string { |
60 -(int) sendToEngine: (NSString *)string { |
59 unsigned char length = [string length]; |
61 unsigned char length = [string length]; |
60 |
62 |
61 SDLNet_TCP_Send(csd, &length , 1); |
63 SDLNet_TCP_Send(csd, &length , 1); |
62 return SDLNet_TCP_Send(csd, [string UTF8String], length); |
64 return SDLNet_TCP_Send(csd, [string UTF8String], length); |
63 } |
65 } |
64 |
66 |
|
67 // unpacks team data from the team.plist to a sequence of commands for engine |
65 -(void) sendTeamData:(NSString *)fileName withPlayingHogs:(NSInteger) playingHogs ofColor:(NSNumber *)color{ |
68 -(void) sendTeamData:(NSString *)fileName withPlayingHogs:(NSInteger) playingHogs ofColor:(NSNumber *)color{ |
66 NSString *teamFile = [[NSString alloc] initWithFormat:@"%@/%@", TEAMS_DIRECTORY(), fileName]; |
69 NSString *teamFile = [[NSString alloc] initWithFormat:@"%@/%@", TEAMS_DIRECTORY(), fileName]; |
67 NSDictionary *teamData = [[NSDictionary alloc] initWithContentsOfFile:teamFile]; |
70 NSDictionary *teamData = [[NSDictionary alloc] initWithContentsOfFile:teamFile]; |
68 [teamFile release]; |
71 [teamFile release]; |
69 |
72 |
141 if (SDLNet_Init() < 0) { |
146 if (SDLNet_Init() < 0) { |
142 NSLog(@"SDLNet_Init: %s", SDLNet_GetError()); |
147 NSLog(@"SDLNet_Init: %s", SDLNet_GetError()); |
143 serverQuit = YES; |
148 serverQuit = YES; |
144 } |
149 } |
145 |
150 |
146 /* Resolving the host using NULL make network interface to listen */ |
151 // Resolving the host using NULL make network interface to listen |
147 if (SDLNet_ResolveHost(&ip, NULL, ipcPort) < 0) { |
152 if (SDLNet_ResolveHost(&ip, NULL, ipcPort) < 0) { |
148 NSLog(@"SDLNet_ResolveHost: %s\n", SDLNet_GetError()); |
153 NSLog(@"SDLNet_ResolveHost: %s\n", SDLNet_GetError()); |
149 serverQuit = YES; |
154 serverQuit = YES; |
150 } |
155 } |
151 |
156 |
152 /* Open a connection with the IP provided (listen on the host's port) */ |
157 // Open a connection with the IP provided (listen on the host's port) |
153 if (!(sd = SDLNet_TCP_Open(&ip))) { |
158 if (!(sd = SDLNet_TCP_Open(&ip))) { |
154 NSLog(@"SDLNet_TCP_Open: %s %\n", SDLNet_GetError(), ipcPort); |
159 NSLog(@"SDLNet_TCP_Open: %s %\n", SDLNet_GetError(), ipcPort); |
155 serverQuit = YES; |
160 serverQuit = YES; |
156 } |
161 } |
157 |
162 |
158 NSLog(@"engineProtocol - Waiting for a client on port %d", ipcPort); |
163 NSLog(@"engineProtocol - Waiting for a client on port %d", ipcPort); |
159 while (!serverQuit) { |
164 while (!serverQuit) { |
160 |
165 |
161 /* This check the sd if there is a pending connection. |
166 // This check the sd if there is a pending connection. |
162 * If there is one, accept that, and open a new socket for communicating */ |
167 // If there is one, accept that, and open a new socket for communicating |
163 csd = SDLNet_TCP_Accept(sd); |
168 csd = SDLNet_TCP_Accept(sd); |
164 if (NULL != csd) { |
169 if (NULL != csd) { |
165 |
170 // Now we can communicate with the client using csd socket |
|
171 // sd will remain opened waiting other connections |
166 NSLog(@"engineProtocol - Client found"); |
172 NSLog(@"engineProtocol - Client found"); |
167 |
173 |
168 //first byte of the command alwayas contain the size of the command |
174 //first byte of the command alwayas contain the size of the command |
169 SDLNet_TCP_Recv(csd, &msgSize, sizeof(Uint8)); |
175 SDLNet_TCP_Recv(csd, &msgSize, sizeof(Uint8)); |
170 |
176 |
171 SDLNet_TCP_Recv(csd, buffer, msgSize); |
177 SDLNet_TCP_Recv(csd, buffer, msgSize); |
172 gameTicks = SDLNet_Read16(&buffer[msgSize - 2]); |
178 gameTicks = SDLNet_Read16 (&buffer[msgSize - 2]); |
173 //NSLog(@"engineProtocol - %d: received [%s]", gameTicks, buffer); |
179 //NSLog(@"engineProtocol - %d: received [%s]", gameTicks, buffer); |
174 |
180 |
175 if ('C' == buffer[0]) { |
181 if ('C' == buffer[0]) { |
176 NSLog(@"engineProtocol - sending game config"); |
182 NSLog(@"engineProtocol - sending game config"); |
177 |
183 |
187 |
193 |
188 // seed info |
194 // seed info |
189 [self sendToEngine:[self.gameConfig objectForKey:@"seed_command"]]; |
195 [self sendToEngine:[self.gameConfig objectForKey:@"seed_command"]]; |
190 |
196 |
191 // various flags |
197 // various flags |
192 [self sendToEngine:@"e$gmflags 256"]; |
198 [self sendToEngine:@"e$gmflags 8448"]; |
193 [self sendToEngine:@"e$damagepct 100"]; |
199 [self sendToEngine:@"e$damagepct 100"]; |
194 [self sendToEngine:@"e$turntime 45000"]; |
200 [self sendToEngine:@"e$turntime 45000"]; |
195 [self sendToEngine:@"e$minestime 3000"]; |
201 [self sendToEngine:@"e$minestime 3000"]; |
196 [self sendToEngine:@"e$landadds 4"]; |
202 [self sendToEngine:@"e$landadds 4"]; |
197 [self sendToEngine:@"e$sd_turns 15"]; |
203 [self sendToEngine:@"e$sd_turns 15"]; |
198 [self sendToEngine:@"e$casefreq 5"]; |
204 [self sendToEngine:@"e$casefreq 5"]; |
|
205 [self sendToEngine:@"e$explosives 2"]; |
|
206 [self sendToEngine:@"e$minedudpct 0"]; |
199 |
207 |
200 // dimension of the map |
208 // dimension of the map |
201 [self sendToEngine:[self.gameConfig objectForKey:@"templatefilter_command"]]; |
209 [self sendToEngine:[self.gameConfig objectForKey:@"templatefilter_command"]]; |
202 [self sendToEngine:[self.gameConfig objectForKey:@"mapgen_command"]]; |
210 [self sendToEngine:[self.gameConfig objectForKey:@"mapgen_command"]]; |
203 [self sendToEngine:[self.gameConfig objectForKey:@"mazesize_command"]]; |
211 [self sendToEngine:[self.gameConfig objectForKey:@"mazesize_command"]]; |
204 |
212 |
205 // theme info |
213 // theme info |
206 [self sendToEngine:@"etheme Compost"]; |
214 [self sendToEngine:[self.gameConfig objectForKey:@"theme_command"]]; |
207 |
215 |
208 NSArray *teamsConfig = [self.gameConfig objectForKey:@"teams_list"]; |
216 NSArray *teamsConfig = [self.gameConfig objectForKey:@"teams_list"]; |
209 for (NSDictionary *teamData in teamsConfig) { |
217 for (NSDictionary *teamData in teamsConfig) { |
210 [self sendTeamData:[teamData objectForKey:@"team"] |
218 [self sendTeamData:[teamData objectForKey:@"team"] |
211 withPlayingHogs:[[teamData objectForKey:@"number"] intValue] |
219 withPlayingHogs:[[teamData objectForKey:@"number"] intValue] |
212 ofColor:[teamData objectForKey:@"color"]]; |
220 ofColor:[teamData objectForKey:@"color"]]; |
213 NSLog(@"teamData sent"); |
|
214 } |
221 } |
215 |
222 |
216 NSDictionary *ammoData = [[NSDictionary alloc] initWithObjectsAndKeys: |
223 NSDictionary *ammoData = [[NSDictionary alloc] initWithObjectsAndKeys: |
217 @"9391929422199121032235111001201000000211190",@"ammostore_initialqt", |
224 @"9391929422199121032235111001201000000211190",@"ammostore_initialqt", |
218 @"0405040541600655546554464776576666666155501",@"ammostore_probability", |
225 @"0405040541600655546554464776576666666155501",@"ammostore_probability", |
226 NSLog(@"engineProtocolThread - wrong message or client closed connection"); |
233 NSLog(@"engineProtocolThread - wrong message or client closed connection"); |
227 clientQuit = YES; |
234 clientQuit = YES; |
228 } |
235 } |
229 |
236 |
230 while (!clientQuit){ |
237 while (!clientQuit){ |
231 /* Now we can communicate with the client using csd socket |
|
232 * sd will remain opened waiting other connections */ |
|
233 msgSize = 0; |
238 msgSize = 0; |
234 memset(buffer, 0, BUFFER_SIZE); |
239 memset(buffer, 0, BUFFER_SIZE); |
235 memset(string, 0, BUFFER_SIZE); |
240 memset(string, 0, BUFFER_SIZE); |
236 if (SDLNet_TCP_Recv(csd, &msgSize, sizeof(Uint8)) <= 0) |
241 if (SDLNet_TCP_Recv(csd, &msgSize, sizeof(Uint8)) <= 0) |
237 clientQuit = YES; |
242 clientQuit = YES; |
298 [NSThread exit]; |
303 [NSThread exit]; |
299 } |
304 } |
300 |
305 |
301 #pragma mark - |
306 #pragma mark - |
302 #pragma mark Setting methods |
307 #pragma mark Setting methods |
|
308 // returns an array of c-strings that are read by engine at startup |
303 -(const char **)getSettings { |
309 -(const char **)getSettings { |
304 NSString *ipcString = [[NSString alloc] initWithFormat:@"%d", ipcPort]; |
310 NSString *ipcString = [[NSString alloc] initWithFormat:@"%d", ipcPort]; |
305 NSString *localeString = [[NSString alloc] initWithFormat:@"%@.txt", [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]]; |
311 NSString *localeString = [[NSString alloc] initWithFormat:@"%@.txt", [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]]; |
306 CGRect screenBounds = [[UIScreen mainScreen] bounds]; |
312 CGRect screenBounds = [[UIScreen mainScreen] bounds]; |
307 NSString *wSize = [[NSString alloc] initWithFormat:@"%d", (int) screenBounds.size.width]; |
313 NSString *wSize = [[NSString alloc] initWithFormat:@"%d", (int) screenBounds.size.width]; |
329 */ |
335 */ |
330 |
336 |
331 // prevents using an empty nickname |
337 // prevents using an empty nickname |
332 NSString *username; |
338 NSString *username; |
333 NSString *originalUsername = [self.systemSettings objectForKey:@"username"]; |
339 NSString *originalUsername = [self.systemSettings objectForKey:@"username"]; |
334 if ([originalUsername length] == 0) { |
340 if ([originalUsername length] == 0) |
335 username = [[NSString alloc] initWithFormat:@"MobileUser-%@",ipcString]; |
341 username = [[NSString alloc] initWithFormat:@"MobileUser-%@",ipcString]; |
336 } else { |
342 else |
337 username = [[NSString alloc] initWithString:originalUsername]; |
343 username = [[NSString alloc] initWithString:originalUsername]; |
338 } |
|
339 |
344 |
340 gameArgs[0] = [username UTF8String]; //UserNick |
345 gameArgs[0] = [username UTF8String]; //UserNick |
341 gameArgs[1] = [ipcString UTF8String]; //ipcPort |
346 gameArgs[1] = [ipcString UTF8String]; //ipcPort |
342 gameArgs[2] = [[[self.systemSettings objectForKey:@"sound"] stringValue] UTF8String]; //isSoundEnabled |
347 gameArgs[2] = [[[self.systemSettings objectForKey:@"sound"] stringValue] UTF8String]; //isSoundEnabled |
343 gameArgs[3] = [[[self.systemSettings objectForKey:@"music"] stringValue] UTF8String]; //isMusicEnabled |
348 gameArgs[3] = [[[self.systemSettings objectForKey:@"music"] stringValue] UTF8String]; //isMusicEnabled |