X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=AppController.m;h=303b1eb9d96e9eeb86d36dec0af23639ce1a256c;hb=0a3d732da131b4505c0dbf2330c4667a29ce90e8;hp=aacc0a79d63f0f046753a0019469f0fe49d09624;hpb=5c3719dab502456afddef1ae919e73f06973012f;p=chaz%2Fthecheat diff --git a/AppController.m b/AppController.m index aacc0a7..303b1eb 100644 --- a/AppController.m +++ b/AppController.m @@ -1,509 +1,339 @@ -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Project: The Cheat -// -// File: AppController.m -// Created: Wed Aug 13 2003 -// -// Copyright: 2003 Chaz McGarvey. All rights reserved. -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// ********************************************************************** +// The Cheat - A universal game cheater for Mac OS X +// (C) 2003-2005 Chaz McGarvey (BrokenZipper) +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 1, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// #import "AppController.h" -#include "cheat_shared.h" - +#import "CheatDocument.h" #import "AboutBoxController.h" +#import "HelpController.h" #import "PreferenceController.h" -#import "NetTrafficController.h" -#import "CheatListener.h" -#import "CheatServer.h" +// Privilage elevation libs +#include +#include +#include +#include +#include -#import "ServerHolder.h" +@implementation AppController -#import +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ +#pragma mark Initialization +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -@implementation AppController + (void)initialize { - NSMutableDictionary *defaults = [NSMutableDictionary dictionary]; - char temp[104]; + NSMutableDictionary *defaults = [NSMutableDictionary dictionary]; - // change the socket path to reside in the home directory of the current user - strncpy( temp, [NSHomeDirectory() lossyCString], 103 ); - strncat( temp, TCDefaultListenPath, 103 - strlen(TCDefaultListenPath) ); - strncpy( TCDefaultListenPath, temp, 103 ); - - [defaults setObject:[NSNumber numberWithBool:TCGlobalPlaySounds] forKey:TCPlaySoundsPref]; - [defaults setObject:[NSNumber numberWithBool:TCGlobalWindowsOnTop] forKey:TCWindowsOnTopPref]; - [defaults setObject:[NSNumber numberWithBool:TCGlobalUpdateCheck] forKey:TCUpdateCheckPref]; - [defaults setObject:[NSNumber numberWithBool:TCGlobalAllowRemote] forKey:TCAllowRemotePref]; - [defaults setObject:[NSNumber numberWithInt:TCGlobalListenPort] forKey:TCListenPortPref]; - [defaults setObject:[NSString stringWithFormat:@"%@'s Computer", NSFullUserName()] forKey:TCBroadcastNamePref]; - [defaults setObject:[NSNumber numberWithInt:TCGlobalHitsDisplayed] forKey:TCHitsDisplayedPref]; - + TCFirstLaunchPref = [[NSString stringWithFormat:@"TC%@%@Pref", ChazAppName(), ChazAppVersion()] retain]; + NSString *broadcastName = [NSString stringWithFormat:@"%@'s Computer", NSFullUserName()]; + + // register user defaults + [defaults setObject:[NSNumber numberWithBool:NO] forKey:TCFirstLaunchPref]; + [defaults setObject:[NSNumber numberWithBool:NO] forKey:TCWindowsOnTopPref]; + [defaults setObject:[NSNumber numberWithBool:YES] forKey:TCUpdateCheckPref]; + [defaults setObject:[NSNumber numberWithBool:YES] forKey:TCDisplayValuesPref]; + [defaults setObject:[NSNumber numberWithFloat:1.0] forKey:TCValueUpdatePref]; + [defaults setObject:[NSNumber numberWithInt:1000] forKey:TCHitsDisplayedPref]; + [defaults setObject:[NSNumber numberWithBool:NO] forKey:TCRunServerPref]; + [defaults setObject:broadcastName forKey:TCBroadcastNamePref]; + [defaults setObject:[NSNumber numberWithInt:TCDefaultListenPort] forKey:TCListenPortPref]; + [defaults setObject:[NSNumber numberWithFloat:gFadeAnimationDuration] forKey:TCFadeAnimationPref]; + [defaults setObject:[NSNumber numberWithBool:YES] forKey:TCAskForSavePref]; + [defaults setObject:[NSNumber numberWithBool:YES] forKey:TCSwitchVariablesPref]; + [defaults setObject:[NSNumber numberWithBool:YES] forKey:TCAutoStartEditingVarsPref]; + + // register it [[NSUserDefaults standardUserDefaults] registerDefaults:defaults]; - - TCGlobalPlaySounds = [[NSUserDefaults standardUserDefaults] boolForKey:TCPlaySoundsPref]; - TCGlobalWindowsOnTop = [[NSUserDefaults standardUserDefaults] boolForKey:TCWindowsOnTopPref]; - TCGlobalUpdateCheck = [[NSUserDefaults standardUserDefaults] boolForKey:TCUpdateCheckPref]; - TCGlobalAllowRemote = [[NSUserDefaults standardUserDefaults] boolForKey:TCAllowRemotePref]; - TCGlobalListenPort = [[NSUserDefaults standardUserDefaults] integerForKey:TCListenPortPref]; - TCGlobalHitsDisplayed = [[NSUserDefaults standardUserDefaults] integerForKey:TCHitsDisplayedPref]; + + // set globals + gFadeAnimationDuration = [[NSUserDefaults standardUserDefaults] floatForKey:TCFadeAnimationPref]; } - (id)init { if ( self = [super init] ) { - servers = [[NSMutableArray alloc] init]; - - // start the server with saved settings - [self listenOnPort:TCGlobalListenPort remote:TCGlobalAllowRemote]; - if ( TCGlobalAllowRemote ) [self broadcastWithName:TCGlobalBroadcastName]; - - // set up the network browser - browser = [[NSNetServiceBrowser alloc] init]; - [browser setDelegate:self]; - [browser searchForServicesOfType:@"_cheat._tcp." inDomain:@"local."]; - - serverList = [[NSMutableArray alloc] init]; - - [self setDelegate:self]; - } - - return self; -} - - -- (void)applicationDidFinishLaunching:(NSNotification *)aNotification -{ - if ( TCGlobalUpdateCheck ) - { - [CMUpdateCheck checkWithURL:@"http://www.brokenzipper.com/software.plist" verbose:NO]; - } -} - - -- (void)listenOnPort:(int)port remote:(BOOL)remote -{ - if ( connection ) - { - [self stopListener]; - - waitingToListen = YES; - connectionPort = port; - connectionRemote = remote; - } - else - { - connection = [[CheatListener listenerWithDelegate:self port:port remote:remote] retain]; - connectionPort = port; - connectionRemote = remote; + if( geteuid() != 0 ) + { + [self launchAuthPrgm]; + [self setDelegate:self]; + } } -} -- (void)stopListener -{ - if ( connection ) + if( geteuid() != 0 ) { - close( sockfd ); - [connection release], connection = nil; - } -} - - -- (void)broadcastWithName:(NSString *)name -{ - [self stopBroadcast]; - - service = [[NSNetService alloc] initWithDomain:@"local." type:@"_cheat._tcp." name:name port:TCGlobalListenPort]; - [service setDelegate:self]; - [service publish]; -} - -- (void)stopBroadcast -{ - [service stop], service = nil; -} - - -- (IBAction)showAboutBoxWindow:(id)sender -{ - if ( !aboutBoxController ) - { - aboutBoxController = [[AboutBoxController alloc] init]; + NSRunAlertPanel(@"The Cheat must be run as root,", + @"Due to a limitation of Leopard, the application needs elevated privileges to run.", + @"Exit", nil, nil ); + [self terminate: 0]; } - [aboutBoxController showWindow:self]; + return self; } -- (IBAction)showPreferenceWindow:(id)sender +- (int) preAuthorize { - if ( !preferenceController ) - { - preferenceController = [[PreferenceController alloc] initWithDelegate:self]; - } - - [preferenceController showWindow:self]; + int err; + AuthorizationFlags authFlags; + + + NSLog (@"MyWindowController: preAuthorize"); + + if (_authRef) + return errAuthorizationSuccess; + + NSLog (@"MyWindowController: preAuthorize: ** calling AuthorizationCreate...**\n"); + + authFlags = kAuthorizationFlagDefaults; + err = AuthorizationCreate (NULL, kAuthorizationEmptyEnvironment, authFlags, &_authRef); + if (err != errAuthorizationSuccess) + return err; + + NSLog (@"MyWindowController: preAuthorize: ** calling AuthorizationCopyRights...**\n"); + + _authItem.name = kAuthorizationRightExecute; + _authItem.valueLength = 0; + _authItem.value = NULL; + _authItem.flags = 0; + _authRights.count = 1; + _authRights.items = (AuthorizationItem*) malloc (sizeof (_authItem)); + memcpy (&_authRights.items[0], &_authItem, sizeof (_authItem)); + authFlags = kAuthorizationFlagDefaults + | kAuthorizationFlagExtendRights + | kAuthorizationFlagInteractionAllowed + | kAuthorizationFlagPreAuthorize; + err = AuthorizationCopyRights (_authRef, &_authRights, kAuthorizationEmptyEnvironment, authFlags, NULL); + + return err; } -- (IBAction)showNetTrafficWindow:(id)sender +- (int) launchAuthPrgm { - if ( !netTrafficController ) + AuthorizationFlags authFlags; + int err; + + // path + NSString * path = [[NSBundle mainBundle] executablePath]; + if (![[NSFileManager defaultManager] isExecutableFileAtPath: path]) + return -1; + + // auth + + if (!_authRef) { - netTrafficController = [[NetTrafficController alloc] initWithDelegate:self]; + err = [self preAuthorize]; + if (err != errAuthorizationSuccess) + return err; } - - [netTrafficController showWindow:self]; -} - - -- (IBAction)launchHelpFile:(id)sender -{ - //[[NSWorkspace sharedWorkspace] openFile:[[NSBundle mainBundle] pathForResource:@"Read Me" ofType:@"html"] withApplication:@"Safari"]; - [[NSWorkspace sharedWorkspace] openURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Read Me" ofType:@"rtf"]]]; -} - -- (IBAction)launchEmailMenu:(id)sender -{ - LaunchEmail(); -} - -- (IBAction)launchWebsiteMenu:(id)sender -{ - LaunchWebsite(); -} - - -- (IBAction)checkForUpdate:(id)sender -{ - [CMUpdateCheck checkWithURL:@"http://www.brokenzipper.com/software.plist"]; -} - - -- (NSArray *)serverList -{ - return serverList; + + // launch + + NSLog (@"MyWindowController: launchWithPath: ** calling AuthorizationExecuteWithPrivileges...**\n"); + authFlags = kAuthorizationFlagDefaults; + err = AuthorizationExecuteWithPrivileges (_authRef, [path cString], authFlags, NULL, NULL); + if(err==0) [NSApp terminate:self]; + + return err; } - - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - [self stopListener]; - [self stopBroadcast]; - - [servers release]; - - [browser release]; - [serverList release]; - + ChazLog( @"AppController deallocated!!" ); + [self stopCheatServer]; [super dealloc]; } -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%% PreferenceControlling -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ +#pragma mark NSApplication Delegate +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -- (void)preferenceSetWindowsOnTop:(BOOL)windowsOnTop -{ - if ( TCGlobalWindowsOnTop != windowsOnTop ) - { - [[NSNotificationCenter defaultCenter] postNotificationName:@"TCWindowsOnTopChanged" object:nil]; - } -} -- (void)preferenceSetAllowRemote:(BOOL)allow listenPort:(int)port broadcastName:(NSString *)name +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { - if ( TCGlobalAllowRemote != allow || TCGlobalListenPort != port ) - { - [self listenOnPort:port remote:allow]; + // check if this is the first launch + if ( ![[NSUserDefaults standardUserDefaults] boolForKey:TCFirstLaunchPref] ) { + // FIRST LAUNCH + [self showAboutBoxWindow:self]; + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:TCFirstLaunchPref]; } - if ( allow ) - { - if ( !TCGlobalAllowRemote || ![TCGlobalBroadcastName isEqualToString:name] ) - { - [self broadcastWithName:name]; - } - } - else - { - [self stopBroadcast]; - } - [netTrafficController serverSetAllowRemote:allow listenPort:port broadcastName:name]; - //[netTrafficController allowRemoteChanged:allow]; - //[netTrafficController listenPortChanged:port]; - //[netTrafficController broadcastNameChanged:name]; -} - -/* -- (void)preferenceAllowRemoteChanged:(BOOL)allow -{ - [self listenOnPort:TCGlobalListenPort remote:allow]; - if ( allow ) - { - [self broadcastWithName:TCGlobalBroadcastName]; + // if should check for updates on launch + if ( [[NSUserDefaults standardUserDefaults] boolForKey:TCUpdateCheckPref] ) { + ChazCheckForUpdate( TCUpdateCheckURL, NO ); } - else - { - [self stopBroadcast]; + + // automaticall start the cheat server if the pref is set + if ( [[NSUserDefaults standardUserDefaults] boolForKey:TCRunServerPref] ) { + if ( ![self startCheatServer] ) { + // inform the user that the server won't start + NSRunAlertPanel( @"The Cheat could not start the server.", + @"The cheat server failed to start. Check the server settings and start it manually.", + @"OK", nil, nil ); + // open server prefs + [self showPreferenceWindow:self]; + [_preferenceController chooseServer:self]; + } } - - [netTrafficController allowRemoteChanged:allow]; } -- (void)preferenceListenPortChanged:(int)port -{ - [self listenOnPort:port remote:TCGlobalAllowRemote]; - [self broadcastWithName:TCGlobalBroadcastName]; - - [netTrafficController listenPortChanged:port]; -} - -- (void)preferenceBroadcastNameChanged:(NSString *)name -{ - [self broadcastWithName:name]; - - [netTrafficController broadcastNameChanged:name]; -} -*/ +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ +#pragma mark Interface Actions +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%% NetTrafficControlling -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - -- (int)netTrafficConnectionCount -{ - return [servers count]; -} - -- (NSArray *)netTrafficConnectionList +- (IBAction)newSearchWindow:(id)sender { - return servers; -} - -- (void)netTrafficKillConnection:(int)index -{ - NSLog( @"kill connection" ); - - close( [[servers objectAtIndex:index] sockfd] ); -} - - -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%% ListenerDelegate -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - - -- (void)listenerListeningWithSocket:(int)sock -{ - sockfd = sock; - - TCGlobalListening = YES; - [[NSNotificationCenter defaultCenter] postNotificationName:@"TCListenerStarted" object:nil]; -} - -- (void)listenerDisconnected -{ - if ( waitingToListen ) - { - waitingToListen = NO; - connection = [[CheatListener listenerWithDelegate:self port:connectionPort remote:connectionRemote] retain]; - } - else - { - [self stopListener]; + NSDocumentController *controller = [NSDocumentController sharedDocumentController]; + CheatDocument *doc = [controller makeUntitledDocumentOfType:@"Cheat Document"]; + if ( !doc ) { + ChazLog( @"nil document" ); } - - TCGlobalListening = NO; - [[NSNotificationCenter defaultCenter] postNotificationName:@"TCListenerStopped" object:nil]; -} - -- (void)listenerError:(NSString *)error message:(NSString *)message -{ - NSRunCriticalAlertPanel( error, message, @"OK", nil, nil ); + [doc setMode:TCSearchMode]; + [controller addDocument:doc]; + [doc makeWindowControllers]; + [doc showWindows]; } -- (void)listenerReceivedNewConnection:(int)sock +- (IBAction)newBlankCheatWindow:(id)sender { - [servers addObject:[ServerHolder holderWithConnection:[CheatServer serverWithDelegate:self socket:sock] socket:sock]]; + NSDocumentController *controller = [NSDocumentController sharedDocumentController]; + CheatDocument *doc = [controller makeUntitledDocumentOfType:@"Cheat Document"]; + if ( !doc ) { + ChazLog( @"nil document" ); + } + [doc setMode:TCCheatMode]; + [controller addDocument:doc]; + [doc makeWindowControllers]; + [doc showWindows]; } - -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%% ServerDelegate -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - - -- (void)server:(CheatServer *)server connectedWithSocket:(int)sock +- (IBAction)showAboutBoxWindow:(id)sender { - int i, top = [servers count]; - - for ( i = 0; i < top; i++ ) - { - if ( [(ServerHolder *)[servers objectAtIndex:i] sockfd] == sock ) - { - [(ServerHolder *)[servers objectAtIndex:i] setServer:server]; - break; - } + if ( !_aboutBoxController ) { + _aboutBoxController = [[AboutBoxController alloc] init]; } - - [netTrafficController connectionListChanged]; + [_aboutBoxController showWindow:self]; } -- (void)serverDisconnected:(CheatServer *)server +- (IBAction)showPreferenceWindow:(id)sender { - int i, top = [servers count]; - - for ( i = 0; i < top; i++ ) - { - if ( [(ServerHolder *)[servers objectAtIndex:i] server] == server ) - { - [servers removeObjectAtIndex:i]; - break; - } + if ( !_preferenceController ) { + _preferenceController = [[PreferenceController alloc] init]; } - - [netTrafficController connectionListChanged]; + [_preferenceController showWindow:self]; } -- (void)server:(CheatServer *)server changedAddress:(NSString *)address -{ - int i, top = [servers count]; - for ( i = 0; i < top; i++ ) - { - if ( [(ServerHolder *)[servers objectAtIndex:i] server] == server ) - { - [(ServerHolder *)[servers objectAtIndex:i] setAddress:address]; - break; - } +- (IBAction)launchHelpFile:(id)sender +{ + if ( !_helpController ) { + _helpController = [[HelpController alloc] init]; } - - [netTrafficController connectionListChanged]; + [_helpController showWindow:self]; } -- (void)server:(CheatServer *)server changedAction:(NSString *)action +- (IBAction)launchEmailMenu:(id)sender { - int i, top = [servers count]; - - for ( i = 0; i < top; i++ ) - { - if ( [(ServerHolder *)[servers objectAtIndex:i] server] == server ) - { - [(ServerHolder *)[servers objectAtIndex:i] setAction:action]; - break; - } - } - - [netTrafficController connectionListChanged]; + LaunchEmail(); } -- (NSArray *)serverProcessList +- (IBAction)launchWebsiteMenu:(id)sender { - return [[NSWorkspace sharedWorkspace] launchedApplications]; + LaunchWebsite(); } -- (pid_t)serverFirstProcess + +- (IBAction)checkForUpdate:(id)sender { - return (pid_t)[[[[[NSWorkspace sharedWorkspace] launchedApplications] objectAtIndex:0] objectForKey:@"NSApplicationProcessIdentifier"] intValue]; + ChazCheckForUpdate( TCUpdateCheckURL, YES ); } -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%% NetService Delegate -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ +#pragma mark CheatServer Stuff +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -- (void)netServiceWillPublish:(NSNetService *)sender +- (CheatServer *)cheatServer { - NSLog( @"service will publish" ); - [sender resolve]; + if ( !_server ) { + _server = [[CheatServer alloc] initWithDelegate:self]; + } + return _server; } -- (void)netService:(NSNetService *)sender didNotPublish:(NSDictionary *)errorDict +- (BOOL)startCheatServer { - NSLog( @"service did not publish" ); + ChazLog( @"cheat server starting..." ); - if ( [[errorDict objectForKey:@"NSNetServicesErrorCode"] intValue] == NSNetServicesCollisionError ) - { - [self broadcastWithName:[NSString stringWithFormat:@"%@ %i", [sender name], TCGlobalAlternateBroadcastNameCount++]]; + // start the server with saved settings + int port = [[NSUserDefaults standardUserDefaults] integerForKey:TCListenPortPref]; + NSString *name = [[NSUserDefaults standardUserDefaults] objectForKey:TCBroadcastNamePref]; + if ( [name isEqualToString:@""] ) { + name = nil; } - else - { - NSRunCriticalAlertPanel( @"Network Error", @"Server couldn't broadcast. Local can't be cheated by remote computers.", @"OK", nil, nil ); + + // stop the cheat server if it's running + [self stopCheatServer]; + + // start the server + if ( [[self cheatServer] listenOnPort:port broadcast:name] ) { + [[NSNotificationCenter defaultCenter] postNotificationName:TCServerStartedNote object:[self cheatServer]]; + return YES; } + return NO; } -- (void)netServiceDidStop:(NSNetService *)sender +- (void)stopCheatServer { - NSLog( @"service stopped" ); - [sender release]; + if ( _server ) { + [_server stop]; + [[NSNotificationCenter defaultCenter] postNotificationName:TCServerStoppedNote object:[self cheatServer]]; + } } -/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%% NSNetServiceBrowser Delegate -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ +#pragma mark CheatServerDelegate +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -- (void)netServiceBrowser:(NSNetServiceBrowser *)browser didFindService:(NSNetService *)aService moreComing:(BOOL)more +- (void)serverDisconnectedUnexpectedly:(CheatServer *)theServer { - // a server has broadcast; not much use until it's resolved. - [aService setDelegate:self]; - [aService resolve]; + ChazLog( @"server disconnected unexpectedly." ); + [self stopCheatServer]; } -- (void)netServiceDidResolveAddress:(NSNetService *)aService -{ - int i, top = [serverList count]; - - // ignore if this is the local server. - if ( TCGlobalAllowRemote && [[aService name] isEqualToString:TCGlobalBroadcastName] ) - { - return; - } - - // ignore if the server name is already in the list. - for ( i = 0; i < top; i++ ) - { - if ( [[aService name] isEqualToString:[(NSNetService *)[serverList objectAtIndex:i] name]] ) - { - return; - } - } - - [serverList addObject:aService]; - NSLog( @"server added: %i", [serverList count] ); - - [[NSNotificationCenter defaultCenter] postNotificationName:@"TCServerFound" object:aService]; +- (void)server:(CheatServer *)theServer failedToBroadcastName:(NSString *)theName +{ + NSBeginInformationalAlertSheet( @"The cheat server can not broadcast.", @"OK", nil, nil, [_preferenceController window], nil, NULL, NULL, NULL, + @"The Cheat can't broadcast as \"%@\" because that name is in use by another server. The server will continue running with broadcasting disabled.", theName ); } -- (void)netServiceBrowser:(NSNetServiceBrowser *)browser didRemoveService:(NSNetService *)aService moreComing:(BOOL)more +- (void)serverChildrenChanged:(CheatServer *)theServer { - int i, top = [serverList count]; - - for ( i = 0; i < top; i++ ) - { - if ( [[aService name] isEqualToString:[(NSNetService *)[serverList objectAtIndex:i] name]] ) - { - [serverList removeObjectAtIndex:i]; - NSLog( @"server deleted: %i", [serverList count] ); - break; - } - } - - [[NSNotificationCenter defaultCenter] postNotificationName:@"TCServerLost" object:aService]; + [[NSNotificationCenter defaultCenter] postNotificationName:TCServerConnectionsChangedNote object:theServer]; } -@end \ No newline at end of file +@end