2 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 // File: AppController.m
6 // Created: Wed Aug 13 2003
8 // Copyright: 2003 Chaz McGarvey. All rights reserved.
9 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11 #import "AppController.h"
13 #include "cheat_shared.h"
15 #import "AboutBoxController.h"
16 #import "PreferenceController.h"
17 #import "NetTrafficController.h"
19 #import "CheatListener.h"
20 #import "CheatServer.h"
22 #import "ServerHolder.h"
25 @implementation AppController
29 NSMutableDictionary
*defaults
= [NSMutableDictionary dictionary
];
32 // change the socket path to reside in the home directory of the current user
33 strncpy( temp
, [NSHomeDirectory() lossyCString
], 103 );
34 strncat( temp
, TCDefaultListenPath
, 103 - strlen(TCDefaultListenPath
) );
35 strncpy( TCDefaultListenPath
, temp
, 103 );
37 [defaults setObject
:[NSNumber numberWithBool
:TCGlobalPlaySounds
] forKey
:TCPlaySoundsPref
];
38 [defaults setObject
:[NSNumber numberWithBool
:TCGlobalWindowsOnTop
] forKey
:TCWindowsOnTopPref
];
39 [defaults setObject
:[NSNumber numberWithBool
:TCGlobalAllowRemote
] forKey
:TCAllowRemotePref
];
40 [defaults setObject
:[NSNumber numberWithInt
:TCGlobalListenPort
] forKey
:TCListenPortPref
];
41 [defaults setObject
:[NSString stringWithFormat
:@
"%@'s Computer", NSFullUserName()] forKey
:TCBroadcastNamePref
];
43 [[NSUserDefaults standardUserDefaults
] registerDefaults
:defaults
];
45 TCGlobalPlaySounds
= [[NSUserDefaults standardUserDefaults
] integerForKey
:TCPlaySoundsPref
];
46 TCGlobalWindowsOnTop
= [[NSUserDefaults standardUserDefaults
] integerForKey
:TCWindowsOnTopPref
];
47 TCGlobalListenPort
= [[NSUserDefaults standardUserDefaults
] integerForKey
:TCListenPortPref
];
48 TCGlobalAllowRemote
= [[NSUserDefaults standardUserDefaults
] boolForKey
:TCAllowRemotePref
];
53 if ( self = [super init
] )
55 servers
= [[NSMutableArray alloc
] init
];
57 [[NSNotificationCenter defaultCenter
] addObserver
:self selector
:@selector(willQuit
:) name
:@
"NSApplicationWillTerminateNotification" object
:nil];
59 [self listenOnPort
:TCGlobalListenPort remote
:TCGlobalAllowRemote
];
60 [self broadcastWithName
:TCGlobalBroadcastName
];
67 - (void)listenOnPort
:(int)port remote
:(BOOL)remote
73 waitingToListen
= YES
;
74 connectionPort
= port
;
75 connectionRemote
= remote
;
79 connection
= [[CheatListener listenerWithDelegate
:self port
:port remote
:remote
] retain
];
80 connectionPort
= port
;
81 connectionRemote
= remote
;
90 [connection release
], connection
= nil;
95 - (void)broadcastWithName
:(NSString
*)name
97 if ( TCGlobalAllowRemote
)
101 service
= [[NSNetService alloc
] initWithDomain
:@
"local." type
:@
"_cheat._tcp." name
:name port
:TCGlobalListenPort
];
102 [service setDelegate
:self];
107 - (void)stopBroadcast
109 oldService
= service
;
110 [oldService stop
], service
= nil;
114 - (IBAction
)showAboutBoxWindow
:(id)sender
116 if ( !aboutBoxController
)
118 aboutBoxController
= [[AboutBoxController alloc
] init
];
121 [aboutBoxController showWindow
:self];
124 - (IBAction
)showPreferenceWindow
:(id)sender
126 if ( !preferenceController
)
128 preferenceController
= [[PreferenceController alloc
] initWithDelegate
:self];
131 [preferenceController showWindow
:self];
134 - (IBAction
)showNetTrafficWindow
:(id)sender
136 if ( !netTrafficController
)
138 netTrafficController
= [[NetTrafficController alloc
] initWithDelegate
:self];
141 [netTrafficController showWindow
:self];
145 - (IBAction
)launchHelpFile
:(id)sender
147 //[[NSWorkspace sharedWorkspace] openFile:[[NSBundle mainBundle] pathForResource:@"Read Me" ofType:@"html"] withApplication:@"Safari"];
148 [[NSWorkspace sharedWorkspace
] openURL
:[NSURL fileURLWithPath
:[[NSBundle mainBundle
] pathForResource
:@
"Read Me" ofType
:@
"pdf"]]];
151 - (IBAction
)launchWebsiteMenu
:(id)sender
156 - (IBAction
)launchDebugEmailMenu
:(id)sender
158 [[NSWorkspace sharedWorkspace
] openURL
:[NSURL URLWithString
:@
"mailto:thecheat@brokenzipper.com"]];
164 [[NSNotificationCenter defaultCenter
] removeObserver
:self];
167 [self stopBroadcast
];
175 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
176 %%%%%%%%%%%%%%%%%%%%%% PreferenceControlling
177 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
180 - (void)preferenceAllowRemoteChanged
:(BOOL)allow
182 [self listenOnPort
:TCGlobalListenPort remote
:allow
];
186 [self broadcastWithName
:TCGlobalBroadcastName
];
190 [self stopBroadcast
];
193 [netTrafficController allowRemoteChanged
:allow
];
196 - (void)preferenceListenPortChanged
:(int)port
198 [self listenOnPort
:port remote
:TCGlobalAllowRemote
];
199 [self broadcastWithName
:TCGlobalBroadcastName
];
201 [netTrafficController listenPortChanged
:port
];
204 - (void)preferenceBroadcastNameChanged
:(NSString
*)name
206 [self broadcastWithName
:name
];
208 [netTrafficController broadcastNameChanged
:name
];
212 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
213 %%%%%%%%%%%%%%%%%%%%%% NetTrafficControlling
214 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
217 - (int)netTrafficConnectionCount
219 return [servers count
];
222 - (NSArray
*)netTrafficConnectionList
227 - (void)netTrafficKillConnection
:(int)index
229 NSLog( @
"kill connection" );
231 close( [[servers objectAtIndex
:index
] sockfd
] );
235 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
236 %%%%%%%%%%%%%%%%%%%%%% ListenerDelegate
237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
240 - (void)listenerListeningWithSocket
:(int)sock
244 TCGlobalListening
= YES
;
245 [[NSNotificationCenter defaultCenter
] postNotificationName
:@
"TCListenerStarted" object
:nil];
248 - (void)listenerDisconnected
250 if ( waitingToListen
)
252 waitingToListen
= NO
;
253 connection
= [[CheatListener listenerWithDelegate
:self port
:connectionPort remote
:connectionRemote
] retain
];
260 TCGlobalListening
= NO
;
261 [[NSNotificationCenter defaultCenter
] postNotificationName
:@
"TCListenerStopped" object
:nil];
264 - (void)listenerError
:(NSString
*)error message
:(NSString
*)message
266 NSRunCriticalAlertPanel( error
, message
, @
"OK", nil, nil );
269 - (void)listenerReceivedNewConnection
:(int)sock
271 [servers addObject
:[ServerHolder holderWithConnection
:[CheatServer serverWithDelegate
:self socket
:sock
] socket
:sock
]];
275 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
276 %%%%%%%%%%%%%%%%%%%%%% ServerDelegate
277 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
280 - (void)server
:(CheatServer
*)server connectedWithSocket
:(int)sock
282 int i
, top
= [servers count
];
284 for ( i
= 0; i
< top
; i
++ )
286 if ( [(ServerHolder
*)[servers objectAtIndex
:i
] sockfd
] == sock
)
288 [(ServerHolder
*)[servers objectAtIndex
:i
] setServer
:server
];
293 [netTrafficController connectionListChanged
];
296 - (void)serverDisconnected
:(CheatServer
*)server
298 int i
, top
= [servers count
];
300 for ( i
= 0; i
< top
; i
++ )
302 if ( [(ServerHolder
*)[servers objectAtIndex
:i
] server
] == server
)
304 [servers removeObjectAtIndex
:i
];
309 [netTrafficController connectionListChanged
];
312 - (void)server
:(CheatServer
*)server changedAddress
:(NSString
*)address
314 int i
, top
= [servers count
];
316 for ( i
= 0; i
< top
; i
++ )
318 if ( [(ServerHolder
*)[servers objectAtIndex
:i
] server
] == server
)
320 [(ServerHolder
*)[servers objectAtIndex
:i
] setAddress
:address
];
325 [netTrafficController connectionListChanged
];
328 - (void)server
:(CheatServer
*)server changedAction
:(NSString
*)action
330 int i
, top
= [servers count
];
332 for ( i
= 0; i
< top
; i
++ )
334 if ( [(ServerHolder
*)[servers objectAtIndex
:i
] server
] == server
)
336 [(ServerHolder
*)[servers objectAtIndex
:i
] setAction
:action
];
341 [netTrafficController connectionListChanged
];
344 - (NSArray
*)serverProcessList
346 return [[NSWorkspace sharedWorkspace
] launchedApplications
];
349 - (pid_t
)serverFirstProcess
351 return (pid_t
)[[[[[NSWorkspace sharedWorkspace
] launchedApplications
] objectAtIndex
:0] objectForKey
:@
"NSApplicationProcessIdentifier"] intValue
];
355 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
356 %%%%%%%%%%%%%%%%%%%%%% NetService Delegate
357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
360 - (void)netServiceWillPublish
:(NSNetService
*)sender
362 NSLog( @
"service will publish" );
366 - (void)netService
:(NSNetService
*)sender didNotPublish
:(NSDictionary
*)errorDict
368 NSLog( @
"service did not publish" );
370 if ( [[errorDict objectForKey
:@
"NSNetServicesErrorCode"] intValue
] == NSNetServicesCollisionError
)
372 [self broadcastWithName
:[NSString stringWithFormat
:@
"%@ %i", TCGlobalBroadcastName
, TCGlobalAlternateBroadcastNameCount
++]];
376 NSRunCriticalAlertPanel( @
"Network Error", @
"Server couldn't broadcast. Local can't be cheated by remote computers.", @
"OK", nil, nil );
380 - (void)netServiceDidStop
:(NSNetService
*)sender
382 NSLog( @
"service stopped" );
383 [oldService release
], oldService
= nil;
387 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
388 %%%%%%%%%%%%%%%%%%%%%% NSApplication Notification
389 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
392 - (void)willQuit
:(NSNotification
*)note
394 //[self listenPortTextField:self];
395 //[self broadcastNameTextField:self];