]> Dogcows Code - chaz/thecheat/blob - AppController.m
The Cheat 1.1.2
[chaz/thecheat] / AppController.m
1
2 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 // Project: The Cheat
4 //
5 // File: AppController.m
6 // Created: Wed Aug 13 2003
7 //
8 // Copyright: 2003 Chaz McGarvey. All rights reserved.
9 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10
11 #import "AppController.h"
12
13 #include "cheat_shared.h"
14
15 #import "SessionController.h"
16 #import "AboutBoxController.h"
17 #import "PreferenceController.h"
18 #import "NetTrafficController.h"
19
20 #import "CheatListener.h"
21 #import "CheatServer.h"
22
23 #import "ServerHolder.h"
24
25
26 @implementation AppController
27
28
29 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
30 #pragma mark Initialization
31 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
32
33
34 + (void)initialize
35 {
36 NSMutableDictionary *defaults = [NSMutableDictionary dictionary];
37 char temp[104];
38
39 // set up logging
40 //#ifndef TC_SHOW_LOGS
41 CMLogDisable();
42 //#endif
43
44 // change the socket path to reside in the home directory of the current user
45 strncpy( temp, [NSHomeDirectory() lossyCString], 103 );
46 strncat( temp, TCDefaultListenPath, 103 - strlen(TCDefaultListenPath) );
47 strncpy( TCDefaultListenPath, temp, 103 );
48
49 [defaults setObject:[NSNumber numberWithBool:TCGlobalPlaySounds] forKey:TCPlaySoundsPref];
50 [defaults setObject:[NSNumber numberWithBool:TCGlobalWindowsOnTop] forKey:TCWindowsOnTopPref];
51 [defaults setObject:[NSNumber numberWithBool:TCGlobalUpdateCheck] forKey:TCUpdateCheckPref];
52 [defaults setObject:[NSNumber numberWithBool:TCGlobalAllowRemote] forKey:TCAllowRemotePref];
53 [defaults setObject:[NSNumber numberWithInt:TCGlobalListenPort] forKey:TCListenPortPref];
54 [defaults setObject:[NSString stringWithFormat:@"%@'s Computer", NSFullUserName()] forKey:TCBroadcastNamePref];
55 [defaults setObject:[NSNumber numberWithInt:TCGlobalHitsDisplayed] forKey:TCHitsDisplayedPref];
56
57 [[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
58
59 TCGlobalPlaySounds = [[NSUserDefaults standardUserDefaults] boolForKey:TCPlaySoundsPref];
60 TCGlobalWindowsOnTop = [[NSUserDefaults standardUserDefaults] boolForKey:TCWindowsOnTopPref];
61 TCGlobalUpdateCheck = [[NSUserDefaults standardUserDefaults] boolForKey:TCUpdateCheckPref];
62 TCGlobalAllowRemote = [[NSUserDefaults standardUserDefaults] boolForKey:TCAllowRemotePref];
63 TCGlobalListenPort = [[NSUserDefaults standardUserDefaults] integerForKey:TCListenPortPref];
64 TCGlobalHitsDisplayed = [[NSUserDefaults standardUserDefaults] integerForKey:TCHitsDisplayedPref];
65 }
66
67 - (id)init
68 {
69 if ( self = [super init] )
70 {
71 servers = [[NSMutableArray alloc] init];
72
73 // start the server with saved settings
74 [self listenOnPort:TCGlobalListenPort remote:TCGlobalAllowRemote];
75 if ( TCGlobalAllowRemote ) [self broadcastWithName:TCGlobalBroadcastName];
76
77 // set up the network browser
78 browser = [[NSNetServiceBrowser alloc] init];
79 [browser setDelegate:self];
80 [browser searchForServicesOfType:@"_cheat._tcp." inDomain:@"local."];
81
82 serverList = [[NSMutableArray alloc] init];
83
84 [self setDelegate:self];
85 }
86
87 return self;
88 }
89
90
91 - (void)dealloc
92 {
93 [[NSNotificationCenter defaultCenter] removeObserver:self];
94
95 [self stopListener];
96 [self stopBroadcast];
97
98 [servers release];
99
100 [browser release];
101 [serverList release];
102
103 [super dealloc];
104 }
105
106
107 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
108 #pragma mark NSApplication Delegate
109 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
110
111
112 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
113 {
114 if ( TCGlobalUpdateCheck )
115 {
116 [CMUpdateCheck checkWithURL:@"http://www.brokenzipper.com/software.plist" verbose:NO];
117 }
118
119 [self newSessionWindow:self];
120 }
121
122 - (void)applicationDidBecomeActive:(NSNotification *)aNotification
123 {
124 /*if ( TCGlobalSessionCount == 0 )
125 {
126 [self newSessionWindow:self];
127 }*/
128 }
129
130
131 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
132 #pragma mark Server Starting/Stopping
133 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
134
135
136 - (void)listenOnPort:(int)port remote:(BOOL)remote
137 {
138 if ( connection )
139 {
140 [self stopListener];
141
142 waitingToListen = YES;
143 connectionPort = port;
144 connectionRemote = remote;
145 }
146 else
147 {
148 connection = [[CheatListener listenerWithDelegate:self port:port remote:remote] retain];
149 connectionPort = port;
150 connectionRemote = remote;
151 }
152 }
153
154 - (void)stopListener
155 {
156 if ( connection )
157 {
158 close( sockfd );
159 [connection release], connection = nil;
160 }
161 }
162
163
164 - (void)broadcastWithName:(NSString *)name
165 {
166 [self stopBroadcast];
167
168 service = [[NSNetService alloc] initWithDomain:@"local." type:@"_cheat._tcp." name:name port:TCGlobalListenPort];
169 [service setDelegate:self];
170 [service publish];
171 }
172
173 - (void)stopBroadcast
174 {
175 [service stop], service = nil;
176 }
177
178
179 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
180 #pragma mark Interface Activation
181 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
182
183
184 - (IBAction)newSessionWindow:(id)sender
185 {
186 [[[SessionController alloc] init] showWindow:self];
187 }
188
189 - (IBAction)showAboutBoxWindow:(id)sender
190 {
191 if ( !aboutBoxController )
192 {
193 aboutBoxController = [[AboutBoxController alloc] init];
194 }
195
196 [aboutBoxController showWindow:self];
197 }
198
199 - (IBAction)showPreferenceWindow:(id)sender
200 {
201 if ( !preferenceController )
202 {
203 preferenceController = [[PreferenceController alloc] initWithDelegate:self];
204 }
205
206 [preferenceController showWindow:self];
207 }
208
209 - (IBAction)showNetTrafficWindow:(id)sender
210 {
211 if ( !netTrafficController )
212 {
213 netTrafficController = [[NetTrafficController alloc] initWithDelegate:self];
214 }
215
216 [netTrafficController showWindow:self];
217 }
218
219
220 - (IBAction)launchHelpFile:(id)sender
221 {
222 //[[NSWorkspace sharedWorkspace] openFile:[[NSBundle mainBundle] pathForResource:@"Read Me" ofType:@"html"] withApplication:@"Safari"];
223 [[NSWorkspace sharedWorkspace] openURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Read Me" ofType:@"rtf"]]];
224 }
225
226 - (IBAction)launchEmailMenu:(id)sender
227 {
228 LaunchEmail();
229 }
230
231 - (IBAction)launchWebsiteMenu:(id)sender
232 {
233 LaunchWebsite();
234 }
235
236
237 - (IBAction)checkForUpdate:(id)sender
238 {
239 [CMUpdateCheck checkWithURL:@"http://www.brokenzipper.com/software.plist"];
240 }
241
242
243 - (NSArray *)serverList
244 {
245 return serverList;
246 }
247
248
249 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
250 #pragma mark Controlling Preferences
251 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
252
253
254 - (void)preferenceSetWindowsOnTop:(BOOL)windowsOnTop
255 {
256 if ( TCGlobalWindowsOnTop != windowsOnTop )
257 {
258 [[NSNotificationCenter defaultCenter] postNotificationName:@"TCWindowsOnTopChanged" object:[NSNumber numberWithBool:windowsOnTop]];
259 }
260 }
261
262 - (void)preferenceSetAllowRemote:(BOOL)allow listenPort:(int)port broadcastName:(NSString *)name
263 {
264 if ( TCGlobalAllowRemote != allow || TCGlobalListenPort != port )
265 {
266 [self listenOnPort:port remote:allow];
267 }
268 if ( allow )
269 {
270 if ( !TCGlobalAllowRemote || ![TCGlobalBroadcastName isEqualToString:name] )
271 {
272 [self broadcastWithName:name];
273 }
274 }
275 else
276 {
277 [self stopBroadcast];
278 }
279 [netTrafficController serverSetAllowRemote:allow listenPort:port broadcastName:name];
280 //[netTrafficController allowRemoteChanged:allow];
281 //[netTrafficController listenPortChanged:port];
282 //[netTrafficController broadcastNameChanged:name];
283 }
284
285 /*
286 - (void)preferenceAllowRemoteChanged:(BOOL)allow
287 {
288 [self listenOnPort:TCGlobalListenPort remote:allow];
289
290 if ( allow )
291 {
292 [self broadcastWithName:TCGlobalBroadcastName];
293 }
294 else
295 {
296 [self stopBroadcast];
297 }
298
299 [netTrafficController allowRemoteChanged:allow];
300 }
301
302 - (void)preferenceListenPortChanged:(int)port
303 {
304 [self listenOnPort:port remote:TCGlobalAllowRemote];
305 [self broadcastWithName:TCGlobalBroadcastName];
306
307 [netTrafficController listenPortChanged:port];
308 }
309
310 - (void)preferenceBroadcastNameChanged:(NSString *)name
311 {
312 [self broadcastWithName:name];
313
314 [netTrafficController broadcastNameChanged:name];
315 }
316 */
317
318
319 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
320 #pragma mark Controlling NetTraffic
321 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
322
323
324 - (int)netTrafficConnectionCount
325 {
326 return [servers count];
327 }
328
329 - (NSArray *)netTrafficConnectionList
330 {
331 return servers;
332 }
333
334 - (void)netTrafficKillConnection:(int)index
335 {
336 CMLog( @"kill connection" );
337
338 close( [[servers objectAtIndex:index] sockfd] );
339 }
340
341
342 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
343 #pragma mark Controlling Listener
344 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
345
346
347 - (void)listenerListeningWithSocket:(int)sock
348 {
349 sockfd = sock;
350
351 TCGlobalListening = YES;
352 [[NSNotificationCenter defaultCenter] postNotificationName:@"TCListenerStarted" object:nil];
353 }
354
355 - (void)listenerDisconnected
356 {
357 if ( waitingToListen )
358 {
359 waitingToListen = NO;
360 connection = [[CheatListener listenerWithDelegate:self port:connectionPort remote:connectionRemote] retain];
361 }
362 else
363 {
364 [self stopListener];
365 }
366
367 TCGlobalListening = NO;
368 [[NSNotificationCenter defaultCenter] postNotificationName:@"TCListenerStopped" object:nil];
369 }
370
371 - (void)listenerError:(NSString *)error message:(NSString *)message
372 {
373 NSRunCriticalAlertPanel( error, message, @"OK", nil, nil );
374 }
375
376 - (void)listenerReceivedNewConnection:(int)sock
377 {
378 [servers addObject:[ServerHolder holderWithConnection:[CheatServer serverWithDelegate:self socket:sock] socket:sock]];
379 }
380
381
382 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
383 #pragma mark Controlling Server
384 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
385
386
387 - (void)server:(CheatServer *)server connectedWithSocket:(int)sock
388 {
389 int i, top = [servers count];
390
391 for ( i = 0; i < top; i++ )
392 {
393 if ( [(ServerHolder *)[servers objectAtIndex:i] sockfd] == sock )
394 {
395 [(ServerHolder *)[servers objectAtIndex:i] setServer:server];
396 break;
397 }
398 }
399
400 [netTrafficController connectionListChanged];
401 }
402
403 - (void)serverDisconnected:(CheatServer *)server
404 {
405 int i, top = [servers count];
406
407 for ( i = 0; i < top; i++ )
408 {
409 if ( [(ServerHolder *)[servers objectAtIndex:i] server] == server )
410 {
411 [servers removeObjectAtIndex:i];
412 break;
413 }
414 }
415
416 [netTrafficController connectionListChanged];
417 }
418
419 - (void)server:(CheatServer *)server changedAddress:(NSString *)address
420 {
421 int i, top = [servers count];
422
423 for ( i = 0; i < top; i++ )
424 {
425 if ( [(ServerHolder *)[servers objectAtIndex:i] server] == server )
426 {
427 [(ServerHolder *)[servers objectAtIndex:i] setAddress:address];
428 break;
429 }
430 }
431
432 [netTrafficController connectionListChanged];
433 }
434
435 - (void)server:(CheatServer *)server changedAction:(NSString *)action
436 {
437 int i, top = [servers count];
438
439 for ( i = 0; i < top; i++ )
440 {
441 if ( [(ServerHolder *)[servers objectAtIndex:i] server] == server )
442 {
443 [(ServerHolder *)[servers objectAtIndex:i] setAction:action];
444 break;
445 }
446 }
447
448 [netTrafficController connectionListChanged];
449 }
450
451 - (NSArray *)serverProcessList
452 {
453 return [[NSWorkspace sharedWorkspace] launchedApplications];
454 }
455
456 - (pid_t)serverFirstProcess
457 {
458 return (pid_t)[[[[[NSWorkspace sharedWorkspace] launchedApplications] objectAtIndex:0] objectForKey:@"NSApplicationProcessIdentifier"] intValue];
459 }
460
461
462 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
463 #pragma mark NetService Delegate
464 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
465
466
467 - (void)netServiceWillPublish:(NSNetService *)sender
468 {
469 CMLog( @"service will publish" );
470 [sender resolve];
471 }
472
473 - (void)netService:(NSNetService *)sender didNotPublish:(NSDictionary *)errorDict
474 {
475 CMLog( @"service did not publish" );
476
477 if ( [[errorDict objectForKey:@"NSNetServicesErrorCode"] intValue] == NSNetServicesCollisionError )
478 {
479 [self broadcastWithName:[NSString stringWithFormat:@"%@ %i", [sender name], TCGlobalAlternateBroadcastNameCount++]];
480 }
481 else
482 {
483 NSRunCriticalAlertPanel( @"Network Error", @"Server couldn't broadcast. Local can't be cheated by remote computers.", @"OK", nil, nil );
484 }
485 }
486
487 - (void)netServiceDidStop:(NSNetService *)sender
488 {
489 CMLog( @"service stopped" );
490 [sender release];
491 }
492
493
494 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
495 #pragma mark NetServiceBrowser Delegate
496 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
497
498
499 - (void)netServiceBrowser:(NSNetServiceBrowser *)browser didFindService:(NSNetService *)aService moreComing:(BOOL)more
500 {
501 // a server has broadcast; not much use until it's resolved.
502 [aService setDelegate:self];
503 [aService resolve];
504 }
505
506 - (void)netServiceDidResolveAddress:(NSNetService *)aService
507 {
508 int i, top = [serverList count];
509
510 // ignore if this is the local server.
511 if ( TCGlobalAllowRemote && [[aService name] isEqualToString:TCGlobalBroadcastName] )
512 {
513 return;
514 }
515
516 // ignore if the server name is already in the list.
517 for ( i = 0; i < top; i++ )
518 {
519 if ( [[aService name] isEqualToString:[(NSNetService *)[serverList objectAtIndex:i] name]] )
520 {
521 return;
522 }
523 }
524
525 [serverList addObject:aService];
526 CMLog( @"server added: %i", [serverList count] );
527
528 [[NSNotificationCenter defaultCenter] postNotificationName:@"TCServerFound" object:aService];
529 }
530
531 - (void)netServiceBrowser:(NSNetServiceBrowser *)browser didRemoveService:(NSNetService *)aService moreComing:(BOOL)more
532 {
533 int i, top = [serverList count];
534
535 for ( i = 0; i < top; i++ )
536 {
537 if ( [[aService name] isEqualToString:[(NSNetService *)[serverList objectAtIndex:i] name]] )
538 {
539 [serverList removeObjectAtIndex:i];
540 CMLog( @"server deleted: %i", [serverList count] );
541 break;
542 }
543 }
544
545 [[NSNotificationCenter defaultCenter] postNotificationName:@"TCServerLost" object:aService];
546 }
547
548
549 @end
This page took 0.056734 seconds and 5 git commands to generate.