-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// 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 <mach/vm_map.h>
-#include <mach/mach_traps.h>
-
-
-// defines
-#define PID_SELECTED [[[processList objectAtIndex:[processPopup indexOfSelectedItem]] objectForKey:@"NSApplicationProcessIdentifier"] intValue]
-#define TYPE_SELECTED [typePopup indexOfSelectedItem]
-#define SIZE_SELECTED [sizePopup indexOfSelectedItem]
+#import "CheatDocument.h"
+#import "AboutBoxController.h"
+#import "HelpController.h"
+#import "PreferenceController.h"
@implementation AppController
-- (id)init
-{
- if ( self = [super init] )
- {
-
- }
-
- return self;
-}
-- (void)awakeFromNib
-{
- NSNotificationCenter *nc = [[NSWorkspace sharedWorkspace] notificationCenter];
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark Initialization
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
- [self rebuildProcessList];
- [self updateProcessPopup];
- [self updateTypePopup];
- [self updateSizePopup];
- [self updateChangeButton];
- [self updateStatusText];
- [nc addObserver:self selector:@selector(processListChanged:) name:@"NSWorkspaceDidLaunchApplicationNotification" object:nil];
- [nc addObserver:self selector:@selector(processListChanged:) name:@"NSWorkspaceDidTerminateApplicationNotification" object:nil];
++ (void)initialize
+{
+ NSMutableDictionary *defaults = [NSMutableDictionary dictionary];
+
+ TCFirstLaunchPref = [[NSString stringWithFormat:@"TC%@%@Pref", ChazAppName(), ChazAppVersion()] retain];
+ NSString *broadcastName = [NSString stringWithFormat:@"%@'s Computer", NSFullUserName()];
- [self reset];
+ // 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];
+
+ // set globals
+ gFadeAnimationDuration = [[NSUserDefaults standardUserDefaults] floatForKey:TCFadeAnimationPref];
}
-
-- (void)reset
+- (id)init
{
- if ( cheating )
- {
- cheating = NO;
-
- [addressList release], addressList = nil;
-
- // update the interface
- [typePopup setEnabled:YES];
- [sizePopup setEnabled:YES];
- [searchTextField setStringValue:@""];
- [changeTextField setStringValue:@""];
- [addressTable reloadData];
+ if ( self = [super init] ) {
+ [self setDelegate:self];
}
+
+ return self;
}
-- (void)firstSearch:(id)nothing
+- (void)dealloc
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- pid_t pid = (pid_t)PID_SELECTED;
- vm_map_t task;
-
- kern_return_t result;
-
- vm_address_t address = 0x0;
- vm_size_t size = 0;
- vm_region_basic_info_data_t info;
- mach_msg_type_number_t infoCnt = 8;
- mach_port_t object_name = 0;
-
- char unsigned *data;
- vm_size_t dataCnt;
-
- char unsigned *string8bit = (char unsigned *)[[searchTextField stringValue] lossyCString];
- long unsigned stringSize = strlen( string8bit );
- char integer8bit = (char)[searchTextField intValue];
- short integer16bit = (short)[searchTextField intValue];
- long integer32bit = (long)[searchTextField intValue];
- long long integer64bit = (long long)[searchTextField intValue];
- float float32bit = (float)[searchTextField floatValue];
- double float64bit = (double)[searchTextField doubleValue];
-
- BOOL done = NO;
-
- if ( (result = task_for_pid( current_task(), pid, &task)) != KERN_SUCCESS )
- {
- NSLog( @"task_for_pid returned error: %i", result );
- return;
- }
-
- addressList = [[NSMutableArray alloc] init];
-
- while ( !done )
- {
- if ( (result = vm_region( task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
- {
- if ( result != KERN_INVALID_ADDRESS )
- {
- NSLog( @"vm_region returned error: %i", result );
- }
-
- done = YES;
- }
-
- //NSLog( @"address: %X, size: %i", address, size );
-
- if ( (info.protection & VM_PROT_READ) && ((info.protection & VM_PROT_WRITE) >> 1) )
- {
- data = (char unsigned *)malloc( size );
- dataCnt = size;
-
- if ( (result = vm_read_overwrite( task, address, size, (vm_address_t)data, &dataCnt )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
- {
- NSLog( @"vm_read_overwrite returned error: %i", result );
- free( data );
- done = YES;
- }
-
- if ( result == KERN_SUCCESS )
- {
- long unsigned i, max = (long unsigned)dataCnt;
-
- //NSLog( @"data: %X, size: %i", (vm_address_t)data, dataCnt );
-
- switch ( TYPE_SELECTED )
- {
- case TYPE_STRING:
- switch ( SIZE_SELECTED )
- {
- case SIZE_8_BIT:
- {
- long unsigned maxString = max - stringSize;
-
- for ( i = 0; i < maxString; i += sizeof(char unsigned) )
- {
- if ( strncmp( string8bit, data+i, stringSize ) == 0 )
- {
- [addressList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
- }
- }
- }
- break;
- }
- break;
-
- case TYPE_INTEGER:
- switch ( SIZE_SELECTED )
- {
- case SIZE_8_BIT:
- {
- for ( i = 0; i < max; i += sizeof(char) )
- {
- if ( integer8bit == *((char *)(data+i)) )
- {
- [addressList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
- }
- }
- }
- break;
-
- case SIZE_16_BIT:
- {
- for ( i = 0; i < max; i += sizeof(short) )
- {
- if ( integer16bit == *((short *)(data+i)) )
- {
- [addressList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
- }
- }
- }
- break;
-
- case SIZE_32_BIT:
- {
- for ( i = 0; i < max; i += sizeof(long) )
- {
- if ( integer32bit == *((long *)(data+i)) )
- {
- [addressList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
- }
- }
- }
- break;
-
- case SIZE_64_BIT:
- {
- for ( i = 0; i < max; i += sizeof(long long) )
- {
- if ( integer64bit == *((long long *)(data+i)) )
- {
- [addressList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
- }
- }
- }
- break;
- }
- break;
-
- case TYPE_FLOAT:
- switch ( SIZE_SELECTED+2 )
- {
- case SIZE_32_BIT:
- {
- for ( i = 0; i < max; i += sizeof(float) )
- {
- if ( float32bit == *((float *)(data+i)) )
- {
- [addressList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
- }
- }
- }
- break;
-
- case SIZE_64_BIT:
- {
- for ( i = 0; i < max; i += sizeof(double) )
- {
- if ( float64bit == *((double *)(data+i)) )
- {
- [addressList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
- }
- }
- }
- break;
- }
- break;
- }
- }
-
- free( data );
- }
-
- address += size;
- }
+ ChazLog( @"AppController deallocated!!" );
+ [self stopCheatServer];
+ [super dealloc];
+}
- searching = NO;
- // update the interface
- [statusBar stopAnimation:self];
- [self updateProcessPopup];
- [self updateSearchButton];
- [self updateTypePopup];
- [self updateSizePopup];
- [self updateChangeButton];
- [self updateStatusText];
- [addressTable reloadData];
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark NSApplication Delegate
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
- [pool release];
-}
-- (void)search:(id)nothing
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ // check if this is the first launch
+ if ( ![[NSUserDefaults standardUserDefaults] boolForKey:TCFirstLaunchPref] ) {
+ // FIRST LAUNCH
+ [self showAboutBoxWindow:self];
+ [[NSUserDefaults standardUserDefaults] setBool:YES forKey:TCFirstLaunchPref];
+ }
- pid_t pid = (pid_t)PID_SELECTED;
- vm_map_t task;
-
- kern_return_t result;
-
- vm_address_t address = 0x0;
- vm_size_t size = 0;
- vm_region_basic_info_data_t info;
- mach_msg_type_number_t infoCnt = 8;
- mach_port_t object_name = 0;
-
- char unsigned *data;
- vm_size_t dataCnt;
-
- char unsigned *string8bit = (char unsigned *)[[searchTextField stringValue] lossyCString];
- long unsigned stringSize = strlen( string8bit );
- char integer8bit = (char)[searchTextField intValue];
- short integer16bit = (short)[searchTextField intValue];
- long integer32bit = (long)[searchTextField intValue];
- long long integer64bit = (long long)[searchTextField intValue];
- float float32bit = (float)[searchTextField floatValue];
- double float64bit = (double)[searchTextField doubleValue];
-
- long unsigned j, max = [addressList count];
-
- NSMutableArray *newList = [[NSMutableArray alloc] init];
-
- if ( (result = task_for_pid( current_task(), pid, &task)) != KERN_SUCCESS )
- {
- NSLog( @"task_for_pid returned error: %i", result );
- return;
+ // if should check for updates on launch
+ if ( [[NSUserDefaults standardUserDefaults] boolForKey:TCUpdateCheckPref] ) {
+ ChazCheckForUpdate( TCUpdateCheckURL, NO );
}
-
- for ( j = 0; j < max; j++ )
- {
- long unsigned item = [[addressList objectAtIndex:j] unsignedLongValue];
-
- address = (vm_address_t)item;
-
- if ( (result = vm_region( task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
- {
- if ( result != KERN_INVALID_ADDRESS )
- {
- NSLog( @"vm_region returned error: %i", result );
- }
-
- break;
- }
-
- //NSLog( @"address: %X, size: %i", address, size );
-
- if ( (info.protection & VM_PROT_READ) && ((info.protection & VM_PROT_WRITE) >> 1) )
- {
- data = (char unsigned *)malloc( size );
- dataCnt = size;
-
- if ( (result = vm_read_overwrite( task, address, size, (vm_address_t)data, &dataCnt )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
- {
- NSLog( @"vm_read_overwrite returned error: %i", result );
- free( data );
- break;
- }
-
- if ( result == KERN_SUCCESS )
- {
- long unsigned i = item - (long unsigned)address;
-
- if ( i < (long unsigned)dataCnt )
- {
- //NSLog( @"data: %X, size: %i", (vm_address_t)data, dataCnt );
-
- switch ( TYPE_SELECTED )
- {
- case TYPE_STRING:
- switch ( SIZE_SELECTED )
- {
- case SIZE_8_BIT:
- {
- if ( strncmp( string8bit, data+i, stringSize ) == 0 )
- {
- [newList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
- }
- }
- break;
- }
- break;
-
- case TYPE_INTEGER:
- switch ( SIZE_SELECTED )
- {
- case SIZE_8_BIT:
- {
- if ( integer8bit == *((char *)(data+i)) )
- {
- [newList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
- }
- }
- break;
-
- case SIZE_16_BIT:
- {
- if ( integer16bit == *((short *)(data+i)) )
- {
- [newList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
- }
- }
- break;
-
- case SIZE_32_BIT:
- {
- if ( integer32bit == *((long *)(data+i)) )
- {
- [newList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
- }
- }
- break;
-
- case SIZE_64_BIT:
- {
- if ( integer64bit == *((long long *)(data+i)) )
- {
- [newList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
- }
- }
- break;
- }
- break;
-
- case TYPE_FLOAT:
- switch ( SIZE_SELECTED+2 )
- {
- case SIZE_32_BIT:
- {
- if ( float32bit == *((float *)(data+i)) )
- {
- [newList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
- }
- }
- break;
-
- case SIZE_64_BIT:
- {
- if ( float64bit == *((double *)(data+i)) )
- {
- [newList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
- }
- }
- break;
- }
- break;
- }
- }
- }
-
- free( data );
+
+ // 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];
}
}
-
- [addressList release];
- addressList = newList;
-
- searching = NO;
-
- // update the interface
- [statusBar stopAnimation:self];
- [self updateProcessPopup];
- [self updateSearchButton];
- [self updateTypePopup];
- [self updateSizePopup];
- [self updateChangeButton];
- [self updateStatusText];
- [addressTable reloadData];
-
- [pool release];
}
-- (void)change
-{
- pid_t pid = (pid_t)PID_SELECTED;
- vm_map_t task;
-
- kern_return_t result;
-
- char unsigned *string8bit = (char unsigned *)[[changeTextField stringValue] lossyCString];
- long unsigned stringSize = strlen( string8bit );
- char integer8bit = (char)[changeTextField intValue];
- short integer16bit = (short)[changeTextField intValue];
- long integer32bit = (long)[changeTextField intValue];
- long long integer64bit = (long long)[changeTextField intValue];
- float float32bit = (float)[changeTextField floatValue];
- double float64bit = (double)[changeTextField doubleValue];
-
- NSEnumerator *enumerator = [addressTable selectedRowEnumerator];
- NSNumber *row;
-
- if ( (result = task_for_pid( current_task(), pid, &task)) != KERN_SUCCESS )
- {
- NSLog( @"task_for_pid returned error: %i", result );
- return;
- }
-
- while ( row = [enumerator nextObject] )
- {
- long unsigned item = [[addressList objectAtIndex:[row intValue]] unsignedLongValue];
-
- //NSLog( @"address: %X", item );
-
- switch ( TYPE_SELECTED )
- {
- case TYPE_STRING:
- switch ( SIZE_SELECTED )
- {
- case SIZE_8_BIT:
- {
- result = vm_write( task, (vm_address_t)item, (vm_offset_t)string8bit, (mach_msg_type_number_t)stringSize );
- }
- break;
- }
- break;
-
- case TYPE_INTEGER:
- switch ( SIZE_SELECTED )
- {
- case SIZE_8_BIT:
- {
- result = vm_write( task, (vm_address_t)item, (vm_offset_t)(&integer8bit), sizeof(char) );
- }
- break;
-
- case SIZE_16_BIT:
- {
- result = vm_write( task, (vm_address_t)item, (vm_offset_t)(&integer16bit), sizeof(short) );
- }
- break;
-
- case SIZE_32_BIT:
- {
- result = vm_write( task, (vm_address_t)item, (vm_offset_t)(&integer32bit), sizeof(long) );
- }
- break;
-
- case SIZE_64_BIT:
- {
- result = vm_write( task, (vm_address_t)item, (vm_offset_t)(&integer64bit), sizeof(long long) );
- }
- break;
- }
- break;
-
- case TYPE_FLOAT:
- switch ( SIZE_SELECTED+2 )
- {
- case SIZE_32_BIT:
- {
- result = vm_write( task, (vm_address_t)item, (vm_offset_t)(&float32bit), sizeof(float) );
- }
- break;
-
- case SIZE_64_BIT:
- {
- result = vm_write( task, (vm_address_t)item, (vm_offset_t)(&float64bit), sizeof(double) );
- }
- break;
- }
- break;
- }
- }
-}
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark Interface Actions
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-- (void)updateProcessPopup
+- (IBAction)newSearchWindow:(id)sender
{
- if ( searching )
- {
- [processPopup setEnabled:NO];
- }
- else
- {
- [processPopup setEnabled:YES];
+ NSDocumentController *controller = [NSDocumentController sharedDocumentController];
+ CheatDocument *doc = [controller makeUntitledDocumentOfType:@"Cheat Document"];
+ if ( !doc ) {
+ ChazLog( @"nil document" );
}
+ [doc setMode:TCSearchMode];
+ [controller addDocument:doc];
+ [doc makeWindowControllers];
+ [doc showWindows];
}
-- (void)updateTypePopup
+- (IBAction)newBlankCheatWindow:(id)sender
{
- if ( cheating || searching )
- {
- [typePopup setEnabled:NO];
- }
- else
- {
- int selected = [typePopup indexOfSelectedItem];
-
- [typePopup setEnabled:YES];
-
- [typePopup removeAllItems];
-
- [typePopup addItemWithTitle:@"String"];
- [typePopup addItemWithTitle:@"Integer"];
- [typePopup addItemWithTitle:@"Float"];
-
- [typePopup selectItemAtIndex:selected];
+ 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];
}
-- (void)updateSizePopup
+- (IBAction)showAboutBoxWindow:(id)sender
{
- if ( cheating || searching )
- {
- [sizePopup setEnabled:NO];
- }
- else
- {
- [sizePopup setEnabled:YES];
-
- [sizePopup removeAllItems];
-
- switch ( TYPE_SELECTED )
- {
- case TYPE_STRING:
- [sizePopup addItemWithTitle:@" 8-bit"];
- break;
-
- case TYPE_INTEGER:
- [sizePopup addItemWithTitle:@" 8-bit"];
- [sizePopup addItemWithTitle:@"16-bit"];
- [sizePopup addItemWithTitle:@"32-bit"];
- [sizePopup addItemWithTitle:@"64-bit"];
- break;
-
- case TYPE_FLOAT:
- [sizePopup addItemWithTitle:@"32-bit"];
- [sizePopup addItemWithTitle:@"64-bit"];
- break;
- }
+ if ( !_aboutBoxController ) {
+ _aboutBoxController = [[AboutBoxController alloc] init];
}
+ [_aboutBoxController showWindow:self];
}
-- (void)updateSearchButton
+- (IBAction)showPreferenceWindow:(id)sender
{
- if ( searching )
- {
- [searchTextField setEnabled:NO];
- [searchButton setEnabled:NO];
- }
- else
- {
- [searchTextField setEnabled:YES];
- [searchButton setEnabled:YES];
+ if ( !_preferenceController ) {
+ _preferenceController = [[PreferenceController alloc] init];
}
+ [_preferenceController showWindow:self];
}
-- (void)updateChangeButton
-{
- if ( [addressTable selectedRow] == -1 || searching )
- {
- [changeTextField setEnabled:NO];
- [changeButton setEnabled:NO];
- }
- else
- {
- [changeTextField setEnabled:YES];
- [changeButton setEnabled:YES];
- }
-}
-- (void)updateStatusText
+- (IBAction)launchHelpFile:(id)sender
{
- if ( searching )
- {
- [statusText setStringValue:@"Searching..."];
- }
- else if ( !cheating )
- {
- [statusText setStringValue:[NSString stringWithFormat:@"PID: %i", PID_SELECTED]];
+ if ( !_helpController ) {
+ _helpController = [[HelpController alloc] init];
}
- else // cheating
- {
- [statusText setStringValue:[NSString stringWithFormat:@"Found: %i", [addressList count]]];
- }
-
- [statusText display];
+ [_helpController showWindow:self];
}
-
-- (void)processListChanged:(NSNotification *)note
+- (IBAction)launchEmailMenu:(id)sender
{
- if ( cheating && [[note name] isEqualToString:@"NSWorkspaceDidTerminateApplicationNotification"] )
- {
- int pid = PID_SELECTED;
- int other = [[[note userInfo] objectForKey:@"NSApplicationProcessIdentifier"] intValue];
-
- // check to make sure the program we were cheating wasn't the one that quit
- if ( pid == other )
- {
- // it was, so let's take care of it
- NSBeginAlertSheet( @"", @"OK", nil, nil, window, nil, nil, nil, 0, @"The application that was being cheated has quit." );
-
- [self reset];
- }
- }
-
- [self rebuildProcessList];
- [self updateProcessPopup];
- [self updateStatusText];
+ LaunchEmail();
}
-
-- (void)rebuildProcessList
+- (IBAction)launchWebsiteMenu:(id)sender
{
- NSString *selected = [[processPopup titleOfSelectedItem] retain];
- int i, max;
-
- [processList release];
- processList = [[[NSWorkspace sharedWorkspace] launchedApplications] retain];
-
- max = [processList count];
-
- [processPopup setImagePosition:NSImageOverlaps];
-
- [processPopup removeAllItems];
-
- for ( i = 0; i < max; i++ )
- {
- NSString *name = [[processList objectAtIndex:i] objectForKey:@"NSApplicationName"];
- NSString *path = [[processList objectAtIndex:i] objectForKey:@"NSApplicationPath"];
-
- NSImage *image = [[NSWorkspace sharedWorkspace] iconForFile:path];
-
- [processPopup addItemWithTitle:name];
-
- [image setScalesWhenResized:YES];
- [image setSize:NSMakeSize( 16.0, 16.0 )];
-
- [[processPopup itemAtIndex:i] setImage:image];
-
- if ( [selected isEqualToString:[processPopup itemTitleAtIndex:i]] )
- {
- [processPopup selectItemAtIndex:i];
- }
- }
-
- [selected release];
+ LaunchWebsite();
}
-- (void)dealloc
+- (IBAction)checkForUpdate:(id)sender
{
- [self reset];
-
- [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
-
- [processList release];
-
- [super dealloc];
+ ChazCheckForUpdate( TCUpdateCheckURL, YES );
}
-- (IBAction)processPopup:(id)sender
-{
- [self reset];
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark CheatServer Stuff
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
- [self updateStatusText];
-}
-
-- (IBAction)typePopup:(id)sender
+- (CheatServer *)cheatServer
{
- [self updateSizePopup];
+ if ( !_server ) {
+ _server = [[CheatServer alloc] initWithDelegate:self];
+ }
+ return _server;
}
-- (IBAction)searchButton:(id)sender
+- (BOOL)startCheatServer
{
- if ( [[searchTextField stringValue] isEqualToString:@""] )
- {
- NSBeep();
- return;
- }
-
- searching = YES;
-
- // update the interface
- [statusBar startAnimation:self];
- [self updateProcessPopup];
- [self updateSearchButton];
- [self updateTypePopup];
- [self updateSizePopup];
- [self updateChangeButton];
- [self updateStatusText];
-
- if ( !cheating )
- {
- cheating = YES;
-
- [NSThread detachNewThreadSelector:@selector(firstSearch:) toTarget:self withObject:nil];
+ ChazLog( @"cheat server starting..." );
+
+ // start the server with saved settings
+ int port = [[NSUserDefaults standardUserDefaults] integerForKey:TCListenPortPref];
+ NSString *name = [[NSUserDefaults standardUserDefaults] objectForKey:TCBroadcastNamePref];
+ if ( [name isEqualToString:@""] ) {
+ name = nil;
}
- else
- {
- [NSThread detachNewThreadSelector:@selector(search:) toTarget:self withObject: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;
}
-/*
- {
- pid_t pid = (pid_t)PID_SELECTED;
- vm_map_t task;
-
- kern_return_t result;
- //int waitStatus;
-
- addressList = [[NSMutableArray alloc] init];
-
- result = task_for_pid( current_task(), pid, &task );
-
- if ( result == KERN_SUCCESS )
- NSLog( @"KERN_SUCCESS" );
- else if ( result == KERN_INVALID_ADDRESS )
- NSLog( @"KERN_INVALID_ADDRESS" );
- else if ( result == KERN_INVALID_ARGUMENT )
- NSLog( @"KERN_INVALID_ARGUMENT" );
- else if ( result == KERN_PROTECTION_FAILURE )
- NSLog( @"KERN_PROTECTION_FAILURE" );
- else if ( result == KERN_NO_SPACE )
- NSLog( @"KERN_NO_SPACE" );
-
- if ( ptrace( PT_ATTACH, pid, 0, 0 ) != -1 )
- {
- if ( waitpid( pid, &waitStatus, WUNTRACED ) == pid )
- {
- if ( WIFSTOPPED(waitStatus) )
- {
- NSLog( @"process stopped" );
- }
- else
- {
- NSLog( @"process didn't stop" );
- }
-
- {
- vm_address_t address = 0x1b000;
- vm_size_t size = 0;
- vm_region_basic_info_data_t info;
- mach_msg_type_number_t infoCnt = 8;
- mach_port_t object_name = 0;
-
- BOOL canRead, canWrite, canExecute;
-
- char unsigned *data;
- vm_size_t dataCnt;
-
- NSLog( @"pid: %i, task: %i", pid, task );
-
- result = vm_region( task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name );
-
- NSLog( @"info count: %i", (int)infoCnt );
-
- if ( result == KERN_SUCCESS )
- NSLog( @"KERN_SUCCESS" );
- else if ( result == KERN_INVALID_ADDRESS )
- NSLog( @"KERN_INVALID_ADDRESS" );
- else if ( result == KERN_INVALID_ARGUMENT )
- NSLog( @"KERN_INVALID_ARGUMENT" );
- else if ( result == KERN_PROTECTION_FAILURE )
- NSLog( @"KERN_PROTECTION_FAILURE" );
- else if ( result == KERN_NO_SPACE )
- NSLog( @"KERN_NO_SPACE" );
-
- NSLog( @"address: %X, size: %i", address, size );
-
- canRead = info.protection & VM_PROT_READ;
- canWrite = (info.protection & VM_PROT_WRITE) >> 1;
- canExecute = (info.protection & VM_PROT_EXECUTE) >> 2;
-
- if ( canRead )
- NSLog( @"can read" );
- if ( canWrite )
- NSLog( @"can write" );
- if ( canExecute )
- NSLog( @"can execute" );
-
- data = (char unsigned *)malloc( size );
- dataCnt = size;
-
- result = vm_read_overwrite( task, address, size, (vm_address_t)data, &dataCnt );
-
- if ( result == KERN_SUCCESS )
- NSLog( @"KERN_SUCCESS" );
- else if ( result == KERN_INVALID_ADDRESS )
- NSLog( @"KERN_INVALID_ADDRESS" );
- else if ( result == KERN_INVALID_ARGUMENT )
- NSLog( @"KERN_INVALID_ARGUMENT" );
- else if ( result == KERN_PROTECTION_FAILURE )
- NSLog( @"KERN_PROTECTION_FAILURE" );
- else if ( result == KERN_NO_SPACE )
- NSLog( @"KERN_NO_SPACE" );
-
- NSLog( @"data: %X, size: %i", (vm_address_t)data, dataCnt );
-
- free( data );
- }
- }
- else
- {
- NSLog( @"waitpid() failed" );
- }
-
- ptrace( PT_DETACH, pid, 0, 0 );
- }
- else
- {
- NSLog( @"ptrace() failed" );
- }
- }*/
+ return NO;
}
-- (IBAction)changeButton:(id)sender
+- (void)stopCheatServer
{
- [self change];
+ if ( _server ) {
+ [_server stop];
+ [[NSNotificationCenter defaultCenter] postNotificationName:TCServerStoppedNote object:[self cheatServer]];
+ }
}
-- (int)numberOfRowsInTableView:(NSTableView *)table
-{
- if ( cheating && !searching )
- return [addressList count];
-
- return 0;
-}
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark CheatServerDelegate
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-- (id)tableView:(NSTableView *)table objectValueForTableColumn:(NSTableColumn *)column row:(int)row
+- (void)serverDisconnectedUnexpectedly:(CheatServer *)theServer
{
- return [NSString stringWithFormat:@"%X", [[addressList objectAtIndex:row] unsignedLongValue]];
+ ChazLog( @"server disconnected unexpectedly." );
+ [self stopCheatServer];
}
-- (void)tableView:(NSTableView *) setObjectValue:(id)object forTableColumn:(NSTableColumn *)column row:(int)row
+- (void)server:(CheatServer *)theServer failedToBroadcastName:(NSString *)theName
{
- return;
+ 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)tableViewSelectionDidChange:(NSNotification *)note
+- (void)serverChildrenChanged:(CheatServer *)theServer
{
- [self updateChangeButton];
+ [[NSNotificationCenter defaultCenter] postNotificationName:TCServerConnectionsChangedNote object:theServer];
}
-@end
\ No newline at end of file
+@end