]> Dogcows Code - chaz/thecheat/commitdiff
The Cheat 1.2 v1.2
authorCharles McGarvey <chazmcgarvey@brokenzipper.com>
Tue, 22 Feb 2005 19:00:00 +0000 (12:00 -0700)
committerCharles McGarvey <chazmcgarvey@brokenzipper.com>
Tue, 22 Feb 2005 19:00:00 +0000 (12:00 -0700)
Bug Fixes:
- Double variables now work.
- 64-bit variables now work.
- Program list problems fixed.
New Features:
- Unknown-value searching.
- Search operator support.
- Variable values are now displayed.
- Automatic value-updating.
- Variable addresses can be edited.
- Memory can be dumped to a file.
- Signed/unsigned integers.
- Can change the window title.
- Cheats can now be saved to file.
Other Changes:
- Improved interface.
- Cheat server can run without broadcasting.
- Pausing is now more stable.
- Comprehensive help system included.
- Search speed improved for narrowing down results.
- More reliable update checker.
- Much better Rendezvous support.
- New icon.

183 files changed:
AboutBoxController.h
AboutBoxController.m
AppController.h
AppController.m
BetterTableView.h [new file with mode: 0644]
BetterTableView.m [new file with mode: 0644]
ChazLog.h [new file with mode: 0644]
ChazLog.m [new file with mode: 0644]
ChazUpdate.h [new file with mode: 0644]
ChazUpdate.m [new file with mode: 0644]
CheatClient.h [deleted file]
CheatClient.m [deleted file]
CheatData.h [new file with mode: 0644]
CheatData.m [new file with mode: 0644]
CheatDocument.h [new file with mode: 0644]
CheatDocument.m [new file with mode: 0644]
CheatListener.h [deleted file]
CheatListener.m [deleted file]
CheatServer.h
CheatServer.m
CheatURLCommand.h [new file with mode: 0644]
CheatURLCommand.m [new file with mode: 0644]
CheatURLHandler.scriptSuite [new file with mode: 0644]
CheatURLHandler.scriptTerminology [new file with mode: 0644]
Cheater.h [new file with mode: 0644]
Cheater.m [new file with mode: 0644]
CheaterTypes.h [new file with mode: 0644]
CheaterTypes.m [new file with mode: 0644]
ClientDelegate.h [deleted file]
Conversions.h [new file with mode: 0644]
Conversions.m [new file with mode: 0644]
DocCheaterDelegate.m [new file with mode: 0644]
DocInterfaceActions.m [new file with mode: 0644]
DumpContext.h [new file with mode: 0644]
DumpContext.m [new file with mode: 0644]
English.lproj/AboutBox.nib/classes.nib
English.lproj/AboutBox.nib/info.nib
English.lproj/AboutBox.nib/keyedobjects.nib
English.lproj/AboutBox.nib/objects.nib [deleted file]
English.lproj/AboutBox~.nib/classes.nib
English.lproj/AboutBox~.nib/info.nib
English.lproj/AboutBox~.nib/keyedobjects.nib
English.lproj/AboutBox~.nib/objects.nib [deleted file]
English.lproj/CheatDocument.nib/classes.nib [new file with mode: 0644]
English.lproj/CheatDocument.nib/disc_session.tiff [new file with mode: 0644]
English.lproj/CheatDocument.nib/info.nib [new file with mode: 0644]
English.lproj/CheatDocument.nib/keyedobjects.nib [new file with mode: 0644]
English.lproj/CheatDocument~.nib/classes.nib [new file with mode: 0644]
English.lproj/CheatDocument~.nib/disc_session.tiff [new file with mode: 0644]
English.lproj/CheatDocument~.nib/info.nib [new file with mode: 0644]
English.lproj/CheatDocument~.nib/keyedobjects.nib [new file with mode: 0644]
English.lproj/Help.nib/classes.nib [new file with mode: 0644]
English.lproj/Help.nib/info.nib [moved from English.lproj/Record.nib/info.nib with 73% similarity]
English.lproj/Help.nib/keyedobjects.nib [new file with mode: 0644]
English.lproj/Help~.nib/classes.nib [new file with mode: 0644]
English.lproj/Help~.nib/info.nib [moved from English.lproj/NetTraffic.nib/info.nib with 58% similarity]
English.lproj/Help~.nib/keyedobjects.nib [new file with mode: 0644]
English.lproj/InfoPlist.strings
English.lproj/MainMenu.nib/classes.nib
English.lproj/MainMenu.nib/info.nib
English.lproj/MainMenu.nib/keyedobjects.nib
English.lproj/MainMenu.nib/objects.nib [deleted file]
English.lproj/MainMenu~.nib/classes.nib
English.lproj/MainMenu~.nib/info.nib
English.lproj/MainMenu~.nib/keyedobjects.nib
English.lproj/MainMenu~.nib/objects.nib [deleted file]
English.lproj/MyDocument~.nib/classes.nib [deleted file]
English.lproj/MyDocument~.nib/info.nib [deleted file]
English.lproj/MyDocument~.nib/keyedobjects.nib [deleted file]
English.lproj/MyDocument~.nib/objects.nib [deleted file]
English.lproj/NetTraffic.nib/classes.nib [deleted file]
English.lproj/NetTraffic.nib/keyedobjects.nib [deleted file]
English.lproj/NetTraffic.nib/objects.nib [deleted file]
English.lproj/NetTraffic~.nib/classes.nib [deleted file]
English.lproj/NetTraffic~.nib/info.nib [deleted file]
English.lproj/NetTraffic~.nib/keyedobjects.nib [deleted file]
English.lproj/NetTraffic~.nib/objects.nib [deleted file]
English.lproj/Preferences.nib/classes.nib
English.lproj/Preferences.nib/info.nib
English.lproj/Preferences.nib/keyedobjects.nib
English.lproj/Preferences.nib/objects.nib [deleted file]
English.lproj/Preferences~.nib/classes.nib
English.lproj/Preferences~.nib/info.nib
English.lproj/Preferences~.nib/keyedobjects.nib
English.lproj/Preferences~.nib/objects.nib [deleted file]
English.lproj/Record.nib/classes.nib [deleted file]
English.lproj/Record.nib/keyedobjects.nib [deleted file]
English.lproj/Record~.nib/classes.nib
English.lproj/Record~.nib/info.nib
English.lproj/Record~.nib/keyedobjects.nib
English.lproj/Session.nib/classes.nib [deleted file]
English.lproj/Session.nib/info.nib [deleted file]
English.lproj/Session.nib/keyedobjects.nib [deleted file]
English.lproj/Session.nib/objects.nib [deleted file]
English.lproj/Session~.nib/classes.nib
English.lproj/Session~.nib/info.nib
English.lproj/Session~.nib/keyedobjects.nib
English.lproj/Session~.nib/objects.nib
English.lproj/locversion.plist [new file with mode: 0644]
FadeView.h [new file with mode: 0644]
FadeView.m [new file with mode: 0644]
General.png [new file with mode: 0644]
GeneralPrefs.h [new file with mode: 0644]
GeneralPrefs.m [new file with mode: 0644]
Help.html [new file with mode: 0644]
HelpController.h [new file with mode: 0644]
HelpController.m [new file with mode: 0644]
Info.plist [moved from Info-The_Cheat.plist with 70% similarity]
LICENSE [new file with mode: 0644]
ListenerDelegate.h [deleted file]
LocalCheater.h [new file with mode: 0644]
LocalCheater.m [new file with mode: 0644]
Lock.tif [new file with mode: 0644]
MenuExtras.h
MenuExtras.m
MySocket.h [new file with mode: 0644]
MySocket.m [new file with mode: 0644]
NOTICE [new file with mode: 0644]
NetTrafficController.h [deleted file]
NetTrafficController.m [deleted file]
NetTrafficControlling.h [deleted file]
PreferenceController.h
PreferenceController.m
PreferenceControlling.h [deleted file]
Process.h [new file with mode: 0644]
Process.m [new file with mode: 0644]
Read Me.rtf [deleted file]
RemoteCheater.h [new file with mode: 0644]
RemoteCheater.m [new file with mode: 0644]
SearchContext.h [new file with mode: 0644]
SearchContext.m [new file with mode: 0644]
SearchData.h [new file with mode: 0644]
SearchData.m [new file with mode: 0644]
SearchResults.h [deleted file]
SearchResults.m [deleted file]
Searching.h [new file with mode: 0644]
Searching.m [new file with mode: 0644]
Server.png [new file with mode: 0644]
ServerChild.h [new file with mode: 0644]
ServerChild.m [new file with mode: 0644]
ServerDelegate.h [deleted file]
ServerDelegate.m [deleted file]
ServerHolder.h [deleted file]
ServerHolder.m [deleted file]
ServerPrefs.h [new file with mode: 0644]
ServerPrefs.m [new file with mode: 0644]
SessionController.h [deleted file]
SessionController.m [deleted file]
StatusTextField.h [new file with mode: 0644]
StatusTextField.m [new file with mode: 0644]
The Cheat.pbproj/chaz.pbxuser [deleted file]
The Cheat.pbproj/project.pbxproj [deleted file]
The Cheat.xcode/chaz.mode1 [new file with mode: 0644]
The Cheat.xcode/chaz.pbxuser [new file with mode: 0644]
The Cheat.xcode/project.pbxproj [new file with mode: 0644]
The_Cheat_Prefix.pch
ThreadedTask.h [new file with mode: 0644]
ThreadedTask.m [new file with mode: 0644]
TrackerScroller.h [new file with mode: 0644]
TrackerScroller.m [new file with mode: 0644]
Update.png [new file with mode: 0644]
UpdatePrefs.h [new file with mode: 0644]
UpdatePrefs.m [new file with mode: 0644]
VMRegion.h [new file with mode: 0644]
VMRegion.m [new file with mode: 0644]
Variable.h [new file with mode: 0644]
Variable.m [new file with mode: 0644]
VariableTable.h [new file with mode: 0644]
VariableTable.m [new file with mode: 0644]
cheat_global.h [new file with mode: 0644]
cheat_global.m [new file with mode: 0644]
cheat_globals.h [deleted file]
cheat_globals.m [deleted file]
cheat_net.h [deleted file]
cheat_net.m [deleted file]
cheat_shared.h [deleted file]
cheat_shared.m [deleted file]
cheat_types.h [deleted file]
disc_session.tif [new file with mode: 0644]
icon.icns
icondoc.icns
main.m
version.plist [new file with mode: 0644]

index d932f5992734e437300435c4a8eed8649628654f..b030bfeb86b478b4cc120a38520df60529e77871 100644 (file)
@@ -1,24 +1,40 @@
 
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      AboutBoxController.h
-// Created:   Mon Nov 24 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 <Cocoa/Cocoa.h>
-#import <Chaz/Chaz.h>
+#import "ChazLog.h"
+
+#import "ChazUpdate.h"
+
+#include "cheat_global.h"
 
 
 @interface AboutBoxController : NSWindowController
 {
-       IBOutlet NSWindow               *aboutWindow;
-       IBOutlet NSTextField    *nameVersionText;
+       IBOutlet NSTextField *ibNameVersionText;
+       IBOutlet NSButton *ibWebsiteButton;
+       IBOutlet NSButton *ibEmailButton;
+       IBOutlet NSTextField *ibDateText;
 }
 
-- (IBAction)launchWebsiteButton:(id)sender;
-- (IBAction)launchEmailButton:(id)sender;
+- (IBAction)ibWebsiteButton:(id)sender;
+- (IBAction)ibEmailButton:(id)sender;
 
 @end
index 6211a41862446460dca7566b3f8e791e8633b5f1..7e1b5fd1a8c3684554cbca3be4ab12be7a8f0bc8 100644 (file)
@@ -1,17 +1,25 @@
 
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      AboutBoxController.m
-// Created:   Mon Nov 24 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 "AboutBoxController.h"
 
-#include "cheat_shared.h"
-
 
 @implementation AboutBoxController
 
 
 - (void)windowDidLoad
 {
-       [nameVersionText setStringValue:[NSString stringWithFormat:@"%@ %@", [CMUpdateCheck appName], [CMUpdateCheck appVersion]]];
-       [aboutWindow center];
+       NSDictionary *attributes;
+       NSAttributedString *string;
+       
+       // set the version string
+       [ibNameVersionText setStringValue:[NSString stringWithFormat:@"Version %@", ChazAppVersion()]];
+       // set the built string
+       [ibDateText setStringValue:[NSString stringWithFormat:@"Built %@", [ChazAppBuildDate() description]]];
+       
+       // set the attributes for the website and email links
+       attributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSColor blueColor], NSForegroundColorAttributeName,
+               [NSNumber numberWithBool:YES], NSUnderlineStyleAttributeName,
+               [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]], NSFontAttributeName, nil];
+       
+       string = [[NSAttributedString alloc] initWithString:[ibWebsiteButton title] attributes:attributes];
+       [ibWebsiteButton setAttributedTitle:string];
+       [string release];
+       string = [[NSAttributedString alloc] initWithString:[ibEmailButton title] attributes:attributes];
+       [ibEmailButton setAttributedTitle:string];
+       [string release];
+       
+       attributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSColor redColor], NSForegroundColorAttributeName,
+               [NSNumber numberWithBool:YES], NSUnderlineStyleAttributeName,
+               [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]], NSFontAttributeName, nil];
+       
+       string = [[NSAttributedString alloc] initWithString:[ibWebsiteButton title] attributes:attributes];
+       [ibWebsiteButton setAttributedAlternateTitle:string];
+       [string release];
+       string = [[NSAttributedString alloc] initWithString:[ibEmailButton title] attributes:attributes];
+       [ibEmailButton setAttributedAlternateTitle:string];
+       [string release];
+       
+       [[self window] center];
 }
 
-- (IBAction)launchWebsiteButton:(id)sender
+
+- (IBAction)ibWebsiteButton:(id)sender
 {
        LaunchWebsite();
 }
 
-- (IBAction)launchEmailButton:(id)sender
+- (IBAction)ibEmailButton:(id)sender
 {
        LaunchEmail();
 }
index af9c6549edbd4a0b03bdfdb72b4a91bb9f8ae919..e4a9765ba55ce03fd93d164da1b691f73614dc25 100644 (file)
@@ -1,60 +1,52 @@
 
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      AppController.h
-// 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 <Cocoa/Cocoa.h>
-#import <Chaz/Chaz.h>
+#import "ChazLog.h"
+#include "cheat_global.h"
 
-#import "PreferenceControlling.h"
-#import "NetTrafficControlling.h"
-#import "ListenerDelegate.h"
-#import "ServerDelegate.h"
+#import "ChazUpdate.h"
 
-#include "cheat_globals.h"
+#import "CheatServer.h"
 
 
 @class AboutBoxController;
+@class HelpController;
 @class PreferenceController;
-@class NetTrafficController;
 
 
-@interface AppController : NSApplication < PreferenceControlling, NetTrafficControlling, ListenerDelegate, ServerDelegate >
+@interface AppController : NSApplication
 {
-       BOOL                                    waitingToListen;
-       NSConnection                    *connection;
-       int                                             connectionPort;
-       BOOL                                    connectionRemote;
-       int                                             sockfd;
-       NSNetService                    *service;
-
-       NSMutableArray                  *servers;
-
-       AboutBoxController              *aboutBoxController;
-       PreferenceController    *preferenceController;
-       NetTrafficController    *netTrafficController;
-       
-       // global network browser
-       NSNetServiceBrowser             *browser;
-       NSMutableArray                  *serverList;
-}
-
-- (void)listenOnPort:(int)port remote:(BOOL)remote;
-- (void)stopListener;
+       CheatServer *_server;
 
-- (void)broadcastWithName:(NSString *)name;
-- (void)stopBroadcast;
+       AboutBoxController *_aboutBoxController;
+       HelpController *_helpController;
+       PreferenceController *_preferenceController;
+}
 
-- (IBAction)newSessionWindow:(id)sender;
+// Interface Actions
+- (IBAction)newSearchWindow:(id)sender;
+- (IBAction)newBlankCheatWindow:(id)sender;
 
 - (IBAction)showAboutBoxWindow:(id)sender;
 - (IBAction)showPreferenceWindow:(id)sender;
-- (IBAction)showNetTrafficWindow:(id)sender;
 
 - (IBAction)launchHelpFile:(id)sender;
 - (IBAction)launchEmailMenu:(id)sender;
 
 - (IBAction)checkForUpdate:(id)sender;
 
-- (NSArray *)serverList;
+// Server Stuff
+- (CheatServer *)cheatServer;
+- (BOOL)startCheatServer;
+- (void)stopCheatServer;
+
+@end
+
 
-@end
\ No newline at end of file
index af247bdccd4e257aca362285d578090ccbfd3957..ebae2deae04d2c320139de396c52f10ecd114fc7 100644 (file)
@@ -1,26 +1,29 @@
 
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// 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 "SessionController.h"
+#import "CheatDocument.h"
 #import "AboutBoxController.h"
+#import "HelpController.h"
 #import "PreferenceController.h"
-#import "NetTrafficController.h"
-
-#import "CheatListener.h"
-#import "CheatServer.h"
-
-#import "ServerHolder.h"
 
 
 @implementation AppController
 
 + (void)initialize
 {
-       NSMutableDictionary             *defaults = [NSMutableDictionary dictionary];
-       char                                    temp[104];
+       NSMutableDictionary *defaults = [NSMutableDictionary dictionary];
        
-       // set up logging
-//#ifndef TC_SHOW_LOGS
-       CMLogDisable();
-//#endif
+       TCFirstLaunchPref = [[NSString stringWithFormat:@"TC%@%@Pref", ChazAppName(), ChazAppVersion()] retain];
+       NSString *broadcastName = [NSString stringWithFormat:@"%@'s Computer", NSFullUserName()];
        
-       // 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];
-
+       // 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];
-               
+       if ( self = [super init] ) {
                [self setDelegate:self];
        }
 
 
 - (void)dealloc
 {
-       [[NSNotificationCenter defaultCenter] removeObserver:self];
-       
-       [self stopListener];
-       [self stopBroadcast];
-       
-       [servers release];
-       
-       [browser release];
-       [serverList release];
-       
+       ChazLog( @"AppController deallocated!!" );
+       [self stopCheatServer];
        [super dealloc];
 }
 
 
 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
 {
-       if ( TCGlobalUpdateCheck )
-       {
-               [CMUpdateCheck checkWithURL:@"http://www.brokenzipper.com/software.plist" verbose:NO];
+       // check if this is the first launch
+       if ( ![[NSUserDefaults standardUserDefaults] boolForKey:TCFirstLaunchPref] ) {
+               // FIRST LAUNCH
+               [self showAboutBoxWindow:self];
+               [[NSUserDefaults standardUserDefaults] setBool:YES forKey:TCFirstLaunchPref];
        }
        
-       [self newSessionWindow:self];
-}
-
-- (void)applicationDidBecomeActive:(NSNotification *)aNotification
-{
-       /*if ( TCGlobalSessionCount == 0 )
-       {
-               [self newSessionWindow:self];
-       }*/
+       // if should check for updates on launch
+       if ( [[NSUserDefaults standardUserDefaults] boolForKey:TCUpdateCheckPref] ) {
+               ChazCheckForUpdate( TCUpdateCheckURL, NO );
+       }
+       
+       // 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];
+               }
+       }
 }
 
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#pragma mark Server Starting/Stopping
+#pragma mark Interface Actions
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 
-- (void)listenOnPort:(int)port remote:(BOOL)remote
+- (IBAction)newSearchWindow:(id)sender
 {
-       if ( connection )
-       {
-               [self stopListener];
-
-               waitingToListen = YES;
-               connectionPort = port;
-               connectionRemote = remote;
-       }
-       else
-       {
-               connection = [[CheatListener listenerWithDelegate:self port:port remote:remote] retain];
-               connectionPort = port;
-               connectionRemote = remote;
+       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)stopListener
+- (IBAction)newBlankCheatWindow:(id)sender
 {
-       if ( connection )
-       {
-               close( sockfd );
-               [connection release], connection = nil;
+       NSDocumentController    *controller = [NSDocumentController sharedDocumentController];
+       CheatDocument                   *doc = [controller makeUntitledDocumentOfType:@"Cheat Document"];
+       if ( !doc ) {
+               ChazLog( @"nil document" );
        }
-}
-
-
-- (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;
-}
-
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#pragma mark Interface Activation
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-- (IBAction)newSessionWindow:(id)sender
-{
-       [[[SessionController alloc] init] showWindow:self];
+       [doc setMode:TCCheatMode];
+       [controller addDocument:doc];
+       [doc makeWindowControllers];
+       [doc showWindows];
 }
 
 - (IBAction)showAboutBoxWindow:(id)sender
 {
-       if ( !aboutBoxController )
-       {
-               aboutBoxController = [[AboutBoxController alloc] init];
+       if ( !_aboutBoxController ) {
+               _aboutBoxController = [[AboutBoxController alloc] init];
        }
-       
-       [aboutBoxController showWindow:self];
+       [_aboutBoxController showWindow:self];
 }
 
 - (IBAction)showPreferenceWindow:(id)sender
 {
-       if ( !preferenceController )
-       {
-               preferenceController = [[PreferenceController alloc] initWithDelegate:self];
-       }
-
-       [preferenceController showWindow:self];
-}
-
-- (IBAction)showNetTrafficWindow:(id)sender
-{
-       if ( !netTrafficController )
-       {
-               netTrafficController = [[NetTrafficController alloc] initWithDelegate:self];
+       if ( !_preferenceController ) {
+               _preferenceController = [[PreferenceController alloc] init];
        }
-
-       [netTrafficController showWindow:self];
+       [_preferenceController 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"]]];
+       if ( !_helpController ) {
+               _helpController = [[HelpController alloc] init];
+       }
+       [_helpController showWindow:self];
 }
 
 - (IBAction)launchEmailMenu:(id)sender
 
 - (IBAction)checkForUpdate:(id)sender
 {
-       [CMUpdateCheck checkWithURL:@"http://www.brokenzipper.com/software.plist"];
-}
-
-
-- (NSArray *)serverList
-{
-       return serverList;
+       ChazCheckForUpdate( TCUpdateCheckURL, YES );
 }
 
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#pragma mark Controlling Preferences
+#pragma mark CheatServer Stuff
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-
-- (void)preferenceSetWindowsOnTop:(BOOL)windowsOnTop
-{
-       if ( TCGlobalWindowsOnTop != windowsOnTop )
-       {
-               [[NSNotificationCenter defaultCenter] postNotificationName:@"TCWindowsOnTopChanged" object:[NSNumber numberWithBool:windowsOnTop]];
-       }
-}
-
-- (void)preferenceSetAllowRemote:(BOOL)allow listenPort:(int)port broadcastName:(NSString *)name
+- (CheatServer *)cheatServer
 {
-       if ( TCGlobalAllowRemote != allow || TCGlobalListenPort != port )
-       {
-               [self listenOnPort:port remote:allow];
-       }
-       if ( allow )
-       {
-               if ( !TCGlobalAllowRemote || ![TCGlobalBroadcastName isEqualToString:name] )
-               {
-                       [self broadcastWithName:name];
-               }
+       if ( !_server ) {
+               _server = [[CheatServer alloc] initWithDelegate:self];
        }
-       else
-       {
-               [self stopBroadcast];
-       }
-       [netTrafficController serverSetAllowRemote:allow listenPort:port broadcastName:name];
-       //[netTrafficController allowRemoteChanged:allow];
-       //[netTrafficController listenPortChanged:port];
-       //[netTrafficController broadcastNameChanged:name];
+       return _server;
 }
 
-/*
-- (void)preferenceAllowRemoteChanged:(BOOL)allow
+- (BOOL)startCheatServer
 {
-       [self listenOnPort:TCGlobalListenPort remote:allow];
+       ChazLog( @"cheat server starting..." );
        
-       if ( allow )
-       {
-               [self broadcastWithName:TCGlobalBroadcastName];
-       }
-       else
-       {
-               [self stopBroadcast];
-       }
-
-       [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 Controlling NetTraffic
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-- (int)netTrafficConnectionCount
-{
-       return [servers count];
-}
-
-- (NSArray *)netTrafficConnectionList
-{
-       return servers;
-}
-
-- (void)netTrafficKillConnection:(int)index
-{
-       CMLog( @"kill connection" );
-
-       close( [[servers objectAtIndex:index] sockfd] );
-}
-
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#pragma mark Controlling Listener
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-- (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];
-       }
-
-       TCGlobalListening = NO;
-       [[NSNotificationCenter defaultCenter] postNotificationName:@"TCListenerStopped" object:nil];
-}
-
-- (void)listenerError:(NSString *)error message:(NSString *)message
-{
-       NSRunCriticalAlertPanel( error, message, @"OK", nil, nil );
-}
-
-- (void)listenerReceivedNewConnection:(int)sock
-{
-       [servers addObject:[ServerHolder holderWithConnection:[CheatServer serverWithDelegate:self socket:sock] socket:sock]];
-}
-
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#pragma mark Controlling Server
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-- (void)server:(CheatServer *)server connectedWithSocket:(int)sock
-{
-       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;
-               }
+       // start the server with saved settings
+       int port = [[NSUserDefaults standardUserDefaults] integerForKey:TCListenPortPref];
+       NSString *name = [[NSUserDefaults standardUserDefaults] objectForKey:TCBroadcastNamePref];
+       if ( [name isEqualToString:@""] ) {
+               name = nil;
        }
-
-       [netTrafficController connectionListChanged];
-}
-
-- (void)serverDisconnected:(CheatServer *)server
-{
-       int                             i, top = [servers count];
-
-       for ( i = 0; i < top; i++ )
-       {
-               if ( [(ServerHolder *)[servers objectAtIndex:i] server] == server )
-               {
-                       [servers removeObjectAtIndex:i];
-                       break;
-               }
-       }
-
-       [netTrafficController connectionListChanged];
-}
-
-- (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;
-               }
+       
+       // 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;
        }
-
-       [netTrafficController connectionListChanged];
+       return NO;
 }
 
-- (void)server:(CheatServer *)server changedAction:(NSString *)action
+- (void)stopCheatServer
 {
-       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;
-               }
+       if ( _server ) {
+               [_server stop];
+               [[NSNotificationCenter defaultCenter] postNotificationName:TCServerStoppedNote object:[self cheatServer]];
        }
-
-       [netTrafficController connectionListChanged];
-}
-
-- (NSArray *)serverProcessList
-{
-       return [[NSWorkspace sharedWorkspace] launchedApplications];
-}
-
-- (pid_t)serverFirstProcess
-{
-       return (pid_t)[[[[[NSWorkspace sharedWorkspace] launchedApplications] objectAtIndex:0] objectForKey:@"NSApplicationProcessIdentifier"] intValue];
 }
 
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#pragma mark NetService Delegate
+#pragma mark CheatServerDelegate
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-
-- (void)netServiceWillPublish:(NSNetService *)sender
-{
-       CMLog( @"service will publish" );
-       [sender resolve];
-}
-
-- (void)netService:(NSNetService *)sender didNotPublish:(NSDictionary *)errorDict
-{
-       CMLog( @"service did not publish" );
-       
-       if ( [[errorDict objectForKey:@"NSNetServicesErrorCode"] intValue] == NSNetServicesCollisionError )
-       {
-               [self broadcastWithName:[NSString stringWithFormat:@"%@ %i", [sender name], TCGlobalAlternateBroadcastNameCount++]];
-       }
-       else
-       {
-               NSRunCriticalAlertPanel( @"Network Error", @"Server couldn't broadcast.  Local can't be cheated by remote computers.", @"OK", nil, nil );
-       }
-}
-
-- (void)netServiceDidStop:(NSNetService *)sender
+- (void)serverDisconnectedUnexpectedly:(CheatServer *)theServer
 {
-       CMLog( @"service stopped" );
-       [sender release];
+       ChazLog( @"server disconnected unexpectedly." );
+       [self stopCheatServer];
 }
 
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#pragma mark NetServiceBrowser Delegate
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-- (void)netServiceBrowser:(NSNetServiceBrowser *)browser didFindService:(NSNetService *)aService moreComing:(BOOL)more
+- (void)server:(CheatServer *)theServer failedToBroadcastName:(NSString *)theName
 {
-       // a server has broadcast; not much use until it's resolved.
-       [aService setDelegate:self];
-       [aService resolve];
-}
-
-- (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];
-       CMLog( @"server added: %i", [serverList count] );
-       
-       [[NSNotificationCenter defaultCenter] postNotificationName:@"TCServerFound" object:aService];
+       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];
-                       CMLog( @"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
diff --git a/BetterTableView.h b/BetterTableView.h
new file mode 100644 (file)
index 0000000..fc3d417
--- /dev/null
@@ -0,0 +1,56 @@
+
+// **********************************************************************
+// 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 <Cocoa/Cocoa.h>
+
+
+@interface BetterTableView : NSTableView
+{
+       BOOL _canDelete; // YES if deleting is enabled
+       BOOL _canCopyPaste;
+}
+
+// override super
+- (void)keyDown:(NSEvent *)theEvent;
+
+// new stuff
+- (BOOL)canDelete;
+- (void)setCanDelete:(BOOL)flag;
+
+- (BOOL)canCopyPaste;
+- (void)setCanCopyPaste:(BOOL)flag;
+
+// array of NSNumbers with the rows which are selected
+- (NSArray *)selectedRows;
+
+@end
+
+@interface NSObject(BetterTableViewDelegate)
+
+- (NSString *)tableViewPasteboardType:(NSTableView *)tableView;
+- (NSData *)tableView:(NSTableView *)tableView copyRows:(NSArray *)rows;
+- (void)tableView:(NSTableView *)tableView pasteRowsWithData:(NSData *)rowData;
+
+- (void)tableView:(NSTableView *)tableView deleteRows:(NSArray *)rows;
+
+- (BOOL)tableViewDidReceiveEnterKey:(NSTableView *)tableView;
+- (BOOL)tableViewDidReceiveSpaceKey:(NSTableView *)tableView;
+
+@end
diff --git a/BetterTableView.m b/BetterTableView.m
new file mode 100644 (file)
index 0000000..9384f40
--- /dev/null
@@ -0,0 +1,247 @@
+
+// **********************************************************************
+// 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 "BetterTableView.h"
+
+
+@interface BetterTableView ( PrivateAPI )
+
+- (NSString *)_copyString;
+
+- (IBAction)copy:(id)sender;
+- (IBAction)paste:(id)sender;
+- (IBAction)cut:(id)sender;
+- (IBAction)delete:(id)sender;
+
+@end
+
+
+@implementation BetterTableView
+
+
+- (id)init
+{
+       if ( self = [super init] ) {
+               _canCopyPaste = YES;
+               _canDelete = YES;
+       }
+       return self;
+}
+
+- (id)initWithCoder:(NSCoder *)coder
+{
+       if ( self = [super initWithCoder:coder] ) {
+               _canCopyPaste = YES;
+               _canDelete = YES;
+       }
+       return self;
+}
+
+
+- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
+{
+       SEL selector = [menuItem action];
+       
+       if ( selector == @selector(selectAll:) ) {
+               return YES;
+       }
+       // support copy/paste
+       if ( _canCopyPaste ) {
+               if ( selector == @selector(paste:) ) {
+                       id delegate = [self delegate];
+                       NSPasteboard *pb = [NSPasteboard generalPasteboard];
+                       NSString *type = nil;
+                       // allow the delegate specify the type of data
+                       if ( [delegate respondsToSelector:@selector(tableViewPasteboardType:)] ) {
+                               type = [delegate tableViewPasteboardType:self];
+                       }
+                       if ( type && [pb availableTypeFromArray:[NSArray arrayWithObject:type]] ) {
+                               return YES;
+                       }
+               }
+               if ( [self selectedRow] != -1 ) {
+                       if ( selector == @selector(copy:) ) {
+                               return YES;
+                       }
+                       else if ( selector == @selector(cut:) || selector == @selector(delete:) ) {
+                               return _canDelete;
+                       }
+               }
+       }
+       return NO;
+}
+
+- (IBAction)copy:(id)sender
+{
+       if ( _canCopyPaste && [self selectedRow] != -1 ) {
+               id delegate = [self delegate];
+               NSPasteboard *pb = [NSPasteboard generalPasteboard];
+               NSString *type = nil;
+               // allow the delegate specify the type of data
+               if ( [delegate respondsToSelector:@selector(tableViewPasteboardType:)] ) {
+                       type = [delegate tableViewPasteboardType:self];
+               }
+               if ( type ) {
+                       [pb declareTypes:[NSArray arrayWithObjects:NSStringPboardType, type, nil] owner:self];
+                       // allow the delegate to copy data
+                       if ( [delegate respondsToSelector:@selector(tableView:copyRows:)] ) {
+                               [pb setData:[delegate tableView:self copyRows:[self selectedRows]] forType:type];
+                       }
+               }
+               else {
+                       [pb declareTypes:[NSArray arrayWithObjects:NSStringPboardType, nil] owner:self];
+               }
+               [pb setString:[self _copyString] forType:NSStringPboardType];
+       }
+}
+
+- (IBAction)paste:(id)sender
+{
+       if (  _canCopyPaste ) {
+               id delegate = [self delegate];
+               NSPasteboard *pb = [NSPasteboard generalPasteboard];
+               NSString *type = nil;
+               // allow the delegate specify the type of data
+               if ( [delegate respondsToSelector:@selector(tableViewPasteboardType:)] ) {
+                       type = [delegate tableViewPasteboardType:self];
+               }
+               if ( type && [pb availableTypeFromArray:[NSArray arrayWithObject:type]] ) {
+                       // allow the delegate to paste data
+                       if ( [delegate respondsToSelector:@selector(tableView:pasteRowsWithData:)] ) {
+                               [delegate tableView:self pasteRowsWithData:[pb dataForType:type]];
+                       }
+               }
+       }
+}
+
+- (IBAction)cut:(id)sender
+{
+       [self copy:sender];
+       [self delete:sender];
+}
+
+- (IBAction)delete:(id)sender
+{
+       if ( _canDelete && [self selectedRow] != -1 ) {
+               id delegate = [self delegate];
+               if ( [delegate respondsToSelector:@selector(tableView:deleteRows:)] ) {
+                       [delegate tableView:self deleteRows:[self selectedRows]];
+               }
+       }
+}
+
+
+- (void)keyDown:(NSEvent *)theEvent
+{      
+       unsigned short keyCode = [theEvent keyCode];
+       // if something is selected and deleting is enabled and the delete key was pressed
+       if ( _canDelete && [self selectedRow] != -1 && (keyCode == 0x75 || keyCode == 0x33) ) {
+               // a delete key was pressed
+               [self delete:nil];
+               return;
+       }
+       else if ( keyCode == 0x24 || keyCode == 0x4C ) {
+               id delegate = [self delegate];
+               if ( [delegate respondsToSelector:@selector(tableViewDidReceiveEnterKey:)] ) {
+                       if ( [delegate tableViewDidReceiveEnterKey:self] ) {
+                               return;
+                       }
+               }
+       }
+       else if ( keyCode == 0x31 ) {
+               // space key
+               id delegate = [self delegate];
+               if ( [delegate respondsToSelector:@selector(tableViewDidReceiveSpaceKey:)] ) {
+                       if ( [delegate tableViewDidReceiveSpaceKey:self] ) {
+                               return;
+                       }
+               }
+       }
+       [super keyDown:theEvent];
+}
+
+
+// NEW STUFF HERE
+
+- (BOOL)canDelete
+{
+       return _canDelete;
+}
+
+- (void)setCanDelete:(BOOL)flag
+{
+       _canDelete = flag;
+}
+
+
+- (BOOL)canCopyPaste
+{
+       return _canCopyPaste;
+}
+
+- (void)setCanCopyPaste:(BOOL)flag
+{
+       _canCopyPaste = flag;
+}
+
+
+- (NSArray *)selectedRows
+{
+       return [[self selectedRowEnumerator] allObjects];
+}
+
+
+// PRIVATE METHODS
+
+- (NSString *)_copyString
+{
+       NSArray *rows, *columns;
+       int i, j, top, columnCount;
+       NSMutableString *string;
+       id delegate = [self delegate];
+       
+       // check delegate
+       if ( ![delegate respondsToSelector:@selector(tableView:objectValueForTableColumn:row:)] ) {
+               return @"";
+       }
+       
+       string = [[NSMutableString alloc] init];
+       
+       columns = [self tableColumns];
+       columnCount = [self numberOfColumns];
+       
+       // loop thru all selected cells and put the text into the string
+       rows = [self selectedRows];
+       top = [rows count];
+       for ( i = 0; i < top; i++ ) {
+               int row = [[rows objectAtIndex:i] unsignedIntValue];
+               for ( j = 0; j < columnCount; j++ ) {
+                       id object = [delegate tableView:self objectValueForTableColumn:[columns objectAtIndex:j] row:row];
+                       [string appendFormat:@"%@%@", j > 0? @"\t" : @"", object];
+               }
+               if ( i + 1 != top ) {
+                       [string appendString:@"\n"];
+               }
+       }
+       return [string autorelease];
+}
+
+
+@end
diff --git a/ChazLog.h b/ChazLog.h
new file mode 100644 (file)
index 0000000..bc329a5
--- /dev/null
+++ b/ChazLog.h
@@ -0,0 +1,51 @@
+//
+//  ChazLog.h
+//  Niobium
+//
+//  Created by NB McGarvey on 9/6/04.
+//  Copyright 2004 NB McGarvey. All rights reserved.
+//
+
+#ifndef _ChazLog_h_
+#define _ChazLog_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#import <Cocoa/Cocoa.h>
+
+
+/* Enable and disable logging to the standard console. */
+void ChazLogEnable();
+void ChazLogDisable();
+
+/* Required for logging to a debug file. */
+void ChazDebugSetup();
+void ChazDebugCleanup();
+
+/* Print a log message to the standard console. */
+void ChazLog( NSString *format, ... );
+/* Print a log message to the debug file (if available). */
+void ChazDebug( NSString *format, ... );
+
+/* Returns true if debug mode is active. */
+BOOL ChazIsDebugging();
+/* Returns the absolute filepath of the debug log. */
+NSString *ChazDebugLogPath();
+
+/* Makes ChazLog() equivalent to ChazDebug(). */
+// call this after ChazDebugSetup()
+// this will automatically enable logs
+void ChazMapLogToDebug();
+
+/* Opens the log file using the default text editor. */
+void ChazOpenDebugLog();
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif /* _ChazLog_h_ */
\ No newline at end of file
diff --git a/ChazLog.m b/ChazLog.m
new file mode 100644 (file)
index 0000000..1637e56
--- /dev/null
+++ b/ChazLog.m
@@ -0,0 +1,155 @@
+//
+//  ChazLog.m
+//  Niobium
+//
+//  Created by NB McGarvey on 9/6/04.
+//  Copyright 2004 NB McGarvey. All rights reserved.
+//
+
+#include "ChazLog.h"
+
+#include "stdio.h"
+#include "stdlib.h"
+
+
+// PrivateAPI
+void static _ChazPrint( FILE *output, NSString *format, va_list args );
+
+
+// Static Globals
+BOOL static _gLogEnabled = NO;
+FILE static *_gLogFile = stdout;
+FILE static *_gDebugFile = NULL;
+
+
+#pragma mark -
+#pragma mark Setup
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+void ChazLogEnable()
+{
+       _gLogEnabled = YES;
+}
+
+void ChazLogDisable()
+{
+       if ( _gLogFile != _gDebugFile ) {
+               _gLogEnabled = NO;
+       }
+}
+
+
+void ChazDebugSetup()
+{
+       NSString *filepath = ChazDebugLogPath();
+       FILE *file;
+       
+       // look for debug file
+       file = fopen( [filepath lossyCString], "r+" );
+       
+       if ( !file ) {
+               // there is no debug file or we don't have permissions
+               return;
+       }
+       
+       fclose( file );
+       
+       _gDebugFile = fopen( [filepath lossyCString], "w" );
+       
+       ChazDebug( @"Debug log found (obviously).  Entering debug mode." );
+}
+
+void ChazDebugCleanup()
+{
+       if ( _gDebugFile ) {
+               ChazDebug( @"Debug log cleaned up." );
+               
+               fclose ( _gDebugFile );
+       }
+}
+
+
+#pragma mark -
+#pragma mark Logs
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+void ChazLog( NSString *format, ... )
+{
+       va_list args;
+       
+       if ( !_gLogEnabled ) {
+               return;
+       }
+       
+    va_start( args, format );
+       // print log to standard i/o
+       _ChazPrint( _gLogFile, format, args );
+    va_end( args );
+}
+
+void ChazDebug( NSString *format, ... )
+{
+       va_list args;
+       
+       if ( !_gDebugFile ) {
+               return;
+       }
+       
+    va_start( args, format );
+       // print log to the debug file
+       _ChazPrint( _gDebugFile, format, args );
+    va_end( args );
+}
+
+
+#pragma mark -
+#pragma mark Miscellaneous
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+BOOL ChazIsDebugging()
+{
+       return (_gDebugFile != NULL);
+}
+
+NSString *ChazDebugLogPath()
+{
+       // get filepath
+       return [[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"debug.txt"];
+}
+
+
+void ChazMapLogToDebug()
+{
+       if ( _gDebugFile ) {
+               _gLogEnabled = YES;
+               _gLogFile = _gDebugFile;
+       }
+}
+
+
+void ChazOpenDebugLog()
+{
+       [[NSWorkspace sharedWorkspace] openFile:ChazDebugLogPath()];
+}
+
+
+#pragma mark -
+#pragma mark PrivateAPI
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+void _ChazPrint( FILE *output, NSString *format, va_list args )
+{
+       NSString *string;
+       
+       // get formatted string
+    string = [[NSString alloc] initWithFormat:format arguments:args];
+       
+       fprintf( output, "[%s] %s\n", [[[NSDate date] descriptionWithCalendarFormat:@"%Y-%m-%d %H:%M:%S.%F"
+                                                                                                                                          timeZone:nil
+                                                                                                                                                locale:nil] lossyCString], [string lossyCString] );
+       fflush( output );
+       
+       [string release];
+}
+
+
diff --git a/ChazUpdate.h b/ChazUpdate.h
new file mode 100644 (file)
index 0000000..ea69f4e
--- /dev/null
@@ -0,0 +1,32 @@
+//
+//  ChazUpdate.h
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 1/5/05.
+//  Copyright 2005 Chaz McGarvey. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+#import "ChazLog.h"
+
+
+// This is my update system.  It is extremely simple to use.  Just pass the URL
+// where the version information can be obtained.  The version information will
+// be loaded in the background and a dialog will show up presenting the user
+// with the results of the check.  If userRequested is NO, then the system will
+// not do anything if an error occured or if there is no available update.
+// Depending on the tags given in the version file, the presented dialog can
+// have buttons which link to a "more info" page or a direct download, using the
+// default web browser of the system.
+
+
+// url can either be an NSURL or an NSString containing a valid URL.
+void ChazCheckForUpdate( id url, BOOL userRequested ); // uses default app name.
+void ChazCheckForUpdateWithName( id url, NSString *appName, BOOL userRequested );
+
+// these return empty strings if they can't be determined.
+NSString *ChazAppName(); // returns the name ChazCheckForUpdate() uses.
+NSString *ChazAppVersion(); // returns the current version of the app.
+NSDate *ChazAppBuildDate(); // returns the build date used to check for updates.
+
+
diff --git a/ChazUpdate.m b/ChazUpdate.m
new file mode 100644 (file)
index 0000000..33de369
--- /dev/null
@@ -0,0 +1,323 @@
+//
+//  ChazUpdate.m
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 1/5/05.
+//  Copyright 2005 Chaz McGarvey. All rights reserved.
+//
+
+#import "ChazUpdate.h"
+
+
+// an NSError that an have an error statement associated with it
+@interface ChazUpdateError : NSError
+{
+       NSString *_errorString;
+}
++ (id)errorWithString:(NSString *)string;
+- (id)initWithString:(NSString *)string;
+- (void)setErrorString:(NSString *)string;
+- (NSString *)localizedDescription;
+@end
+@implementation ChazUpdateError
++ (id)errorWithString:(NSString *)string
+{
+       return [[[ChazUpdateError alloc] initWithString:string] autorelease];
+}
+- (id)initWithString:(NSString *)string
+{
+       if ( self = [super initWithDomain:@"ChazUpdateError" code:1 userInfo:nil] ) {
+               [self setErrorString:string];
+       }
+       return self;
+}
+- (void)setErrorString:(NSString *)string
+{
+       [string retain];
+       [_errorString release];
+       _errorString = string;
+}
+- (NSString *)localizedDescription
+{
+       return _errorString;
+}
+@end
+
+
+@interface ChazUpdate : NSObject
+{
+       NSString *_name;
+       
+       NSURLConnection *_connection;
+       NSHTTPURLResponse *_response;
+       NSMutableData *_responseData;
+       
+       BOOL _verbose;
+}
+
+- (id)initWithURL:(id)url name:(NSString *)name verbose:(BOOL)verbose;
+- (void)kill;
+
+@end
+
+
+@implementation ChazUpdate
+
+
+#pragma mark Initialization
+
+- (id)initWithURL:(id)url name:(NSString *)name verbose:(BOOL)verbose
+{
+       NSURL *theURL;
+       
+       if ( self = [super init] )
+       {
+               // figure out what type of URL was passed
+               if ( [url isKindOfClass:[NSURL class]] ) {
+                       theURL = url;
+               }
+               else if ( [url isKindOfClass:[NSString class]] ) {
+                       theURL = [[[NSURL alloc] initWithString:url] autorelease];
+               }
+               else {
+                       if ( verbose ) {
+                               NSRunAlertPanel( @"Update Check Failed",
+                                                                @"Could not determine the location of the version information file.", @"OK", nil, nil );
+                       }
+                       [self release];
+                       return nil;
+               }
+               // save the name
+               if ( name ) {
+                       _name = [name retain];
+               }
+               else {
+                       _name = [[NSString stringWithString:@""] retain];
+               }
+               _verbose = verbose;
+               
+               // create the request
+               _connection = [[NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:theURL
+                                                                                                                                                          cachePolicy:NSURLRequestReloadIgnoringCacheData
+                                                                                                                                                  timeoutInterval:30.0] delegate:self] retain];
+               _response = nil;
+               _responseData = [[NSMutableData alloc] init];
+       }
+       return self;
+}
+
+
+- (void)dealloc
+{
+       // cleanup
+       [_name release];
+       
+       [_connection release];
+       [_response release];
+       [_responseData release];
+       
+       [super dealloc];
+}
+
+- (void)kill
+{
+       [self release];
+       self = nil;
+}
+
+
+#pragma mark NSURLConnection Delegate
+
+- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
+{
+       if ( _response ) {
+               // another response, chop the data
+               [_responseData setLength:0];
+               [_response release];
+       }
+       _response = [response retain];
+}
+
+- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
+{
+       // just save the data
+       [_responseData appendData:data];
+}
+
+-(void)connectionDidFinishLoading:(NSURLConnection *)connection
+{
+       NSDictionary *plistDictionary;
+       NSPropertyListFormat plistFormat;
+       NSString *plistError;
+       
+       NSDictionary *appDictionary;
+       
+       NSString *appRedirect;
+       NSString *appVersion;
+       NSString *appOnline;
+       NSDate *appReleaseDate;
+       NSString *appDownload;
+       NSString *appDescription;
+       
+       // read in the recently downloaded plist
+       plistDictionary = [NSPropertyListSerialization propertyListFromData:_responseData
+                                                                                                          mutabilityOption:NSPropertyListImmutable
+                                                                                                                                format:&plistFormat
+                                                                                                          errorDescription:&plistError];
+       if ( !plistDictionary ) {
+               [self connection:connection didFailWithError:[ChazUpdateError errorWithString:plistError]];
+               return;
+       }
+       // make sure the root object is a dictionary
+       if ( ![NSStringFromClass([plistDictionary class]) isEqualToString:@"NSCFDictionary"] ) {
+               [self connection:connection didFailWithError:[ChazUpdateError errorWithString:@"the version information file is ill-formatted"]];
+               return;
+       }
+       appDictionary = [plistDictionary objectForKey:_name];
+       if ( !appDictionary ) {
+               [self connection:connection didFailWithError:[ChazUpdateError errorWithString:@"no version information for this application"]];
+               return;
+       }
+       
+       // see if the version information for this app is in another file
+       if ( appRedirect = [appDictionary objectForKey:@"Redirect"] ) {
+               // recursively follow the redirection
+               [[ChazUpdate alloc] initWithURL:appRedirect name:_name verbose:_verbose];
+               [self kill];
+               return;
+       }
+       
+       // read other useful information about the app
+       appVersion = [appDictionary objectForKey:@"Version"];
+       appReleaseDate = [NSDate dateWithNaturalLanguageString:[appDictionary objectForKey:@"ReleaseDate"]];
+       appOnline = [appDictionary objectForKey:@"MoreInfoURL"];
+       appDownload = [appDictionary objectForKey:@"DownloadURL"];
+       appDescription = [appDictionary objectForKey:@"Description"];
+       
+       if ( !appReleaseDate ) {
+               [self connection:connection didFailWithError:[ChazUpdateError errorWithString:@"missing version information"]];
+               return;
+       }
+       
+       if ( !appVersion ) {
+               appVersion = @"";
+       }
+       
+       if ( [ChazAppBuildDate() compare:appReleaseDate] == NSOrderedAscending ) {
+               // there is a new version, display message
+               int choice;
+               
+               NSString *desc;
+               NSString *mainBtn;
+               NSString *alternate;
+               NSString *other;
+               
+               if ( appDescription ) {
+                       desc = appDescription;
+               }
+               else {
+                       desc = [NSString stringWithFormat:@"A new version of %@ is available!  Would you like to learn more about the new version now?", _name];
+               }
+               if ( appOnline ) {
+                       mainBtn = @"Learn More";
+                       other = @"Cancel";
+               }
+               else {
+                       mainBtn = @"OK";
+                       other = nil;
+               }
+               if ( appDownload ) {
+                       alternate = @"Download";
+               }
+               else {
+                       alternate = nil;
+               }
+               
+               choice = NSRunInformationalAlertPanel( [NSString stringWithFormat:@"New Version: %@ %@", _name, appVersion],
+                                                                                          desc, mainBtn, alternate, other );
+               
+               if ( choice == NSAlertDefaultReturn && appOnline ) {
+                       [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:appOnline]];
+               }
+               else if ( choice == NSAlertAlternateReturn ) {
+                       [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:appDownload]];
+               }
+       }
+       else if ( _verbose ) {
+               // alert that the user has the latest version if we're in verbose mode
+               NSRunInformationalAlertPanel( [NSString stringWithFormat:@"%@ %@", _name, ChazAppVersion()],
+                                                                         @"You have the latest version of %@.", @"OK", nil, nil, _name );
+       }
+       
+       [self kill];
+}
+
+- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
+{
+       if ( _verbose )
+       {
+               // check failed, display an error
+               NSRunAlertPanel( @"Update Check Failed", @"Check could not get new version data.\nError code #%i (%@)", @"OK", nil, nil, [error code], [error localizedDescription] );
+       }
+       
+       [self kill];
+}
+
+- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse
+{
+       // handle http redirection
+       return request;
+}
+
+
+@end
+
+
+#pragma mark API Functions
+
+void ChazCheckForUpdate( id url, BOOL userRequested )
+{
+       [[ChazUpdate alloc] initWithURL:url name:ChazAppName() verbose:userRequested];
+}
+
+void ChazCheckForUpdateWithName( id url, NSString *appName, BOOL userRequested )
+{
+       [[ChazUpdate alloc] initWithURL:url name:appName verbose:userRequested];
+}
+
+
+NSString *ChazAppName()
+{
+       NSString *name;
+       
+       name = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleExecutable"];
+       if ( name && ![name isEqualToString:@""] ) {
+               return name;
+       }
+       name = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
+       if ( name && ![name isEqualToString:@""] ) {
+               return name;
+       }
+       return @"";
+}
+
+NSString *ChazAppVersion()
+{
+       NSString *vers;
+       
+       vers = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
+       if ( vers && ![vers isEqualToString:@""] ) {
+               return vers;
+       }
+       vers = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
+       if ( vers && ![vers isEqualToString:@""] ) {
+               return vers;
+       }
+       return @"";
+}
+
+NSDate *ChazAppBuildDate()
+{
+       return [NSDate dateWithNaturalLanguageString:[NSString stringWithFormat:@"%s %s", __TIME__, __DATE__]];
+}
+
diff --git a/CheatClient.h b/CheatClient.h
deleted file mode 100644 (file)
index 227fcb6..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      CheatClient.h
-// Created:   Mon Sep 22 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#import <Cocoa/Cocoa.h>
-#import <Chaz/Chaz.h>
-
-#include "cheat_types.h"
-#include "cheat_globals.h"
-#include "cheat_net.h"
-
-
-@interface CheatClient : NSObject
-{
-       id                                      rootProxy;
-       int                                     sockfd;
-}
-
-+ (NSConnection *)clientWithDelegate:(id)delegate server:(NSData *)server name:(NSString *)name;
-+ (void)clientThread:(NSArray *)array;
-
-- (id)initWithRootProxy:(id)proxy;
-
-- (void)connectToServer:(NSData *)data name:(NSString *)name;
-- (void)run;
-
-@end
\ No newline at end of file
diff --git a/CheatClient.m b/CheatClient.m
deleted file mode 100644 (file)
index dac94e2..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      CheatClient.m
-// Created:   Mon Sep 22 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#import "CheatClient.h"
-
-#import "SessionController.h"
-
-
-@implementation CheatClient
-
-
-+ (NSConnection *)clientWithDelegate:(id)delegate server:(NSData *)server name:(NSString *)name
-{
-       NSPort                          *rPort = [NSPort port], *sPort = [NSPort port];
-       NSConnection            *connection;
-       NSArray                         *array;
-
-       connection = [[NSConnection alloc] initWithReceivePort:rPort sendPort:sPort];
-       [connection setRootObject:delegate];
-
-       array = [NSArray arrayWithObjects:sPort, rPort, server, name, nil];
-       [NSThread detachNewThreadSelector:@selector(clientThread:) toTarget:self withObject:array];
-
-       return [connection autorelease];
-}
-
-+ (void)clientThread:(NSArray *)array
-{
-       NSAutoreleasePool       *pool = [[NSAutoreleasePool alloc] init];
-    NSConnection               *connection = [NSConnection connectionWithReceivePort:[array objectAtIndex:0] sendPort:[array objectAtIndex:1]];
-    CheatClient                        *object = [[self alloc] initWithRootProxy:[connection rootProxy]];
-
-       [object connectToServer:[array objectAtIndex:2] name:[array objectAtIndex:3]];
-       [object run];
-    
-    [object release];
-    [pool release];
-}
-
-
-- (id)initWithRootProxy:(id)proxy
-{
-       if ( self = [super init] )
-       {
-               rootProxy = proxy;
-               sockfd = -1;
-       }
-
-       return self;
-}
-
-
-- (void)connectToServer:(NSData *)data name:(NSString *)name
-{
-       struct sockaddr         identifier;
-
-       [data getBytes:&identifier length:sizeof(identifier)];
-
-       if ( (sockfd = socket( identifier.sa_family, SOCK_STREAM, 0 )) == -1 )
-       {
-               CMLog( @"ERROR: socket() failed" );
-               [rootProxy clientError:@"Network Error" message:@"Attempt to connect to server failed."];
-               return;
-       }
-
-       if ( identifier.sa_family == AF_INET )
-       {
-               struct sockaddr_in              addr;
-
-               [data getBytes:&addr];
-
-               if ( connect( sockfd, (struct sockaddr *)(&addr), sizeof(addr) ) == -1 )
-               {
-                       close( sockfd );
-
-                       CMLog( @"ERROR: connect() failed" );
-                       [rootProxy clientError:@"Network Error" message:@"Attempt to connect to server failed."];
-                       return;
-               }
-       }
-       else
-       {
-               struct sockaddr_un              addr;
-
-               [data getBytes:&addr];
-               
-               if ( connect( sockfd, (struct sockaddr *)(&addr), sizeof(addr) ) == -1 )
-               {
-                       close( sockfd );
-
-                       CMLog( @"ERROR: connect() failed" );
-                       [rootProxy clientError:@"Network Error" message:@"Attempt to connect to server failed."];
-                       return;
-               }
-       }
-
-       [rootProxy clientConnectedWithSocket:sockfd name:name];
-}
-
-- (void)run
-{
-       int                                     result;
-
-       PacketHeader            header;
-
-       NSData                          *data;
-       char                            *bytes = NULL;
-       
-       if ( sockfd == -1 )
-       {
-               CMLog( @"ERROR: can't run when not connected" );
-               return;
-       }
-
-       CMLog( @"CLIENT start" );
-
-       for (;;)
-       {
-               if ( (result = ReadBuffer( sockfd, (char *)(&header), sizeof(header) )) != sizeof(header) )
-               {
-                       if ( result != 0 && result != -1 )
-                       {
-                               CMLog( @"ERROR: incomplete header received" );
-                               close( sockfd );
-                               break;
-                       }
-
-                       break;
-               }
-
-               if ( !VerifyChecksum( header.checksum ) )
-               {
-                       CMLog( @"ERROR: checksum verification failed" );
-                       close( sockfd );
-                       break;
-               }
-
-               //CMLog( @"CLIENT message %i/%i/%i", header.checksum, header.function, header.size );
-
-               if ( header.size != 0 )
-               {
-                       if ( (bytes = (char *)malloc( header.size )) == NULL )
-                       {
-                               CMLog( @"ERROR: failed to allocate buffer for reading a network packet" );
-                               close( sockfd );
-                               break;
-                       }
-
-                       if ( (result = ReadBuffer( sockfd, bytes, header.size )) != header.size )
-                       {
-                               CMLog( @"ERROR: failed to read the data of a network packet; only read %i bytes out of %i", result, header.size );
-                               free( bytes );
-                               close( sockfd );
-                               break;
-                       }
-               }
-
-               data = [NSData dataWithBytes:bytes length:header.size];
-
-               switch ( header.function )
-               {
-                       case 2:
-                               [rootProxy receivedProcessList:data];
-                               break;
-
-                       case 6:
-                               [rootProxy receivedSearchFinished];
-                               break;
-
-                       case 7:
-                               [rootProxy receivedVariableList:data];
-                               break;
-
-                       case 9:
-                               [rootProxy receivedChangeFinished];
-                               break;
-
-                       case 11:
-                               [rootProxy receivedError:data];
-                               break;
-                               
-                       case 15:
-                               [rootProxy receivedUndoFinished];
-                               break;
-                               
-                       case 17:
-                               [rootProxy receivedRedoFinished];
-                               break;
-                               
-                       case 19:
-                               [rootProxy receivedUndoRedoStatus:data];
-                               break;
-
-                       case 21:
-                               [rootProxy receivedAppLaunched:data];
-                               break;
-
-                       case 22:
-                               [rootProxy receivedAppQuit:data];
-                               break;
-
-                       case 23:
-                               [rootProxy receivedTargetQuit];
-                               break;
-
-                       case 24:
-                               [rootProxy receivedPauseFinished:data];
-                               break;
-               }
-
-               if ( header.size != 0 )
-               {
-                       free( bytes );
-               }
-       }
-
-       [rootProxy clientDisconnected];
-
-       CMLog( @"CLIENT close" );
-}
-
-
-@end
\ No newline at end of file
diff --git a/CheatData.h b/CheatData.h
new file mode 100644 (file)
index 0000000..9c9b776
--- /dev/null
@@ -0,0 +1,87 @@
+
+// **********************************************************************
+// 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 <Cocoa/Cocoa.h>
+
+#import "Process.h"
+#import "Variable.h"
+
+
+@interface CheatData : NSObject < NSCoding >
+{
+       NSString *myWindowTitle;
+       NSString *myCheatInfo;
+       
+       Process *myProcess;
+       NSMutableArray *myVariables;
+       
+       BOOL myRepeats;
+       NSTimeInterval myRepeatInterval;
+}
+
+// #############################################################################
+#pragma mark NSCoding
+// #############################################################################
+
+- (id)initWithCoder:(NSCoder *)coder;
+- (void)encodeWithCoder:(NSCoder *)coder;
+
+
+// #############################################################################
+#pragma mark Accessing Properties
+// #############################################################################
+
+- (NSString *)windowTitle;
+- (NSString *)cheatInfo;
+- (NSString *)gameName;
+- (NSString *)gameVersion;
+- (Process *)process;
+- (BOOL)repeats;
+- (NSTimeInterval)repeatInterval;
+
+- (void)setWindowTitle:(NSString *)title;
+- (void)setCheatInfo:(NSString *)info;
+- (void)setProcess:(Process *)process;
+- (void)setRepeats:(BOOL)repeats;
+- (void)setRepeatInterval:(NSTimeInterval)interval;
+
+
+// #############################################################################
+#pragma mark Variables
+// #############################################################################
+
+- (NSArray *)variables;
+- (unsigned)variableCount;
+- (unsigned)indexOfVariable:(Variable *)variable;
+- (Variable *)variableAtIndex:(unsigned)index;
+- (Variable *)lastVariable;
+
+- (void)addVariable:(Variable *)variable;
+- (void)insertVariable:(Variable *)variable atIndex:(unsigned)index;
+
+- (void)removeAllVariables;
+- (void)removeVariable:(Variable *)variable;
+- (void)removeVariableAtIndex:(unsigned)index;
+
+- (NSArray *)enabledVariables;
+- (unsigned)enabledVariableCount;
+
+
+@end
diff --git a/CheatData.m b/CheatData.m
new file mode 100644 (file)
index 0000000..b02d999
--- /dev/null
@@ -0,0 +1,249 @@
+
+// **********************************************************************
+// 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 "CheatData.h"
+
+
+@implementation CheatData
+
+
+// #############################################################################
+#pragma mark Initialization
+// #############################################################################
+
+- (id)init
+{
+       if ( self = [super init] )
+       {
+               // set defaults
+               [self setWindowTitle:@""];
+               [self setCheatInfo:@""];
+               [self setProcess:[[[Process alloc] initWithName:@"No Target Set" version:@""] autorelease]];
+               
+               myRepeats = NO;
+               myRepeatInterval = 5.0;
+               
+               // create objects
+               myVariables = [[NSMutableArray alloc] init];
+       }
+       return self;
+}
+
+- (void)dealloc
+{
+       // release objects
+       [myWindowTitle release];
+       [myCheatInfo release];
+       [myProcess release];
+       [myVariables release];
+       
+       [super dealloc];
+}
+
+
+// #############################################################################
+#pragma mark NSCoding
+// #############################################################################
+
+- (id)initWithCoder:(NSCoder *)coder
+{
+       if ( self = [super init] )
+       {
+               [self setWindowTitle:[coder decodeObject]];
+               [self setCheatInfo:[coder decodeObject]];
+               [self setProcess:[coder decodeObject]];
+               myVariables = [[coder decodeObject] retain];
+               [coder decodeValueOfObjCType:@encode(BOOL) at:&myRepeats];
+               [coder decodeValueOfObjCType:@encode(NSTimeInterval) at:&myRepeatInterval];
+       }
+       return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)coder
+{
+       [coder encodeObject:myWindowTitle];
+       [coder encodeObject:myCheatInfo];
+       [coder encodeObject:myProcess];
+       [coder encodeObject:myVariables];
+       [coder encodeValueOfObjCType:@encode(BOOL) at:&myRepeats];
+       [coder encodeValueOfObjCType:@encode(NSTimeInterval) at:&myRepeatInterval];
+}
+
+
+// #############################################################################
+#pragma mark Accessing Properties
+// #############################################################################
+
+
+- (NSString *)windowTitle
+{
+       return myWindowTitle;
+}
+
+- (NSString *)cheatInfo
+{
+       return myCheatInfo;
+}
+
+- (NSString *)gameName
+{
+       return [myProcess name];
+}
+
+- (NSString *)gameVersion
+{
+       return [myProcess version];
+}
+
+- (Process *)process
+{
+       return myProcess;
+}
+
+- (BOOL)repeats
+{
+       return myRepeats;
+}
+
+- (NSTimeInterval)repeatInterval
+{
+       return myRepeatInterval;
+}
+
+
+- (void)setWindowTitle:(NSString *)title
+{
+       if ( !title ) {
+               title = [NSString stringWithString:@""];
+       }
+       [title retain];
+       [myWindowTitle release];
+       myWindowTitle = title;
+}
+
+- (void)setCheatInfo:(NSString *)info
+{
+       if ( !info ) {
+               info = [NSString stringWithString:@"Description not provided."];
+       }
+       [info retain];
+       [myCheatInfo release];
+       myCheatInfo = info;
+}
+
+- (void)setProcess:(Process *)process
+{
+       [process retain];
+       [myProcess release];
+       myProcess = process;
+}
+
+- (void)setRepeats:(BOOL)repeats
+{
+       myRepeats = repeats;
+}
+
+- (void)setRepeatInterval:(NSTimeInterval)interval
+{
+       myRepeatInterval = interval;
+}
+
+
+// #############################################################################
+#pragma mark Variables
+// #############################################################################
+
+- (NSArray *)variables
+{
+       return [NSArray arrayWithArray:myVariables];
+}
+
+- (unsigned)variableCount
+{
+       return [myVariables count];
+}
+
+- (unsigned)indexOfVariable:(Variable *)variable
+{
+       return [myVariables indexOfObject:variable];
+}
+
+- (Variable *)variableAtIndex:(unsigned)index
+{
+       return [myVariables objectAtIndex:index];
+}
+
+- (Variable *)lastVariable
+{
+       return [myVariables lastObject];
+}
+
+
+- (void)addVariable:(Variable *)variable
+{
+       [myVariables addObject:variable];
+}
+
+- (void)insertVariable:(Variable *)variable atIndex:(unsigned)index
+{
+       [myVariables insertObject:variable atIndex:index];
+}
+
+
+- (void)removeAllVariables
+{
+       [myVariables removeAllObjects];
+}
+
+- (void)removeVariable:(Variable *)variable
+{
+       [myVariables removeObject:variable];
+}
+
+- (void)removeVariableAtIndex:(unsigned)index
+{
+       [myVariables removeObjectAtIndex:index];
+}
+
+
+- (NSArray *)enabledVariables
+{
+       NSMutableArray *vars;
+       int i, top;
+       
+       top = [myVariables count];
+       vars = [[NSMutableArray alloc] init];
+       
+       for ( i = 0; i < top; i++ ) {
+               Variable *var = [myVariables objectAtIndex:i];
+               if ( [var isEnabled] ) {
+                       [vars addObject:var];
+               }
+       }
+       return [vars autorelease];
+}
+
+- (unsigned)enabledVariableCount
+{
+       return [[self enabledVariables] count];
+}
+
+
+@end
diff --git a/CheatDocument.h b/CheatDocument.h
new file mode 100644 (file)
index 0000000..d239804
--- /dev/null
@@ -0,0 +1,252 @@
+
+// **********************************************************************
+// 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 <Cocoa/Cocoa.h>
+#import "ChazLog.h"
+#include "cheat_global.h"
+
+#import "VariableTable.h"
+#import "FadeView.h"
+#import "MenuExtras.h"
+#import "StatusTextField.h"
+
+#import "CheatData.h"
+#import "SearchData.h"
+
+#import "LocalCheater.h"
+#import "RemoteCheater.h"
+#import "Variable.h"
+
+#import "AppController.h"
+
+
+typedef unsigned TCDocumentMode;
+enum {
+       TCSearchMode = 0,
+       TCCheatMode = 1
+};
+
+
+typedef unsigned TCDocumentStatus;
+enum {
+       TCIdleStatus = 0,
+       TCSearchingStatus = 1,
+       TCCheatingStatus = 2,
+       TCDumpingStatus = 3
+};
+
+
+@interface CheatDocument : NSDocument
+{
+       // WINDOW INTERFACE
+       IBOutlet NSWindow *ibWindow;
+       IBOutlet NSPopUpButton *ibServerPopup;
+       IBOutlet NSPopUpButton *ibProcessPopup;
+       IBOutlet NSView *ibPlaceView;
+       IBOutlet StatusTextField *ibStatusText;
+       IBOutlet NSProgressIndicator *ibStatusBar;
+       
+       // SEARCH MODE INTERFACE
+       IBOutlet NSView *ibSearchContentView;
+       IBOutlet NSPopUpButton *ibSearchTypePopup;
+       IBOutlet NSMatrix *ibSearchIntegerSignMatrix;
+       IBOutlet NSPopUpButton *ibSearchOperatorPopup;
+       IBOutlet NSMatrix *ibSearchValueUsedMatrix;
+       IBOutlet NSTextField *ibSearchValueField;
+       IBOutlet VariableTable *ibSearchVariableTable;
+       IBOutlet NSButton *ibSearchClearButton;
+       IBOutlet NSButton *ibSearchButton;
+       IBOutlet NSButton *ibSearchVariableButton;
+       
+       // CHEAT MODE INTERFACE
+       IBOutlet NSView *ibCheatContentView;
+       IBOutlet NSTextField *ibCheatInfoText;
+       IBOutlet BetterTableView *ibCheatVariableTable;
+       IBOutlet NSButton *ibCheatRepeatButton;
+       IBOutlet NSTextField *ibCheatRepeatAuxText;
+       IBOutlet NSTextField *ibCheatRepeatField;
+       IBOutlet NSButton *ibCheatButton;
+       
+       // PROPERTIES INTERFACE
+       IBOutlet NSWindow *ibPropertiesSheet;
+       IBOutlet NSTextField *ibWindowTitleField;
+       IBOutlet NSTextField *ibCheatInfoField;
+       
+       // PASSWORD INTERFACE
+       IBOutlet NSWindow *ibPasswordSheet;
+       IBOutlet NSTextField *ibPasswordField;
+       
+       // CUSTOM SERVER INTERFACE
+       IBOutlet NSWindow *ibCustomServerSheet;
+       IBOutlet NSTextField *ibServerField;
+       IBOutlet NSTextField *ibPortField;
+       
+       // EDIT VARIABLES INTERFACE
+       IBOutlet NSWindow *ibEditVariablesSheet;
+       IBOutlet NSTextField *ibNewValueField;
+       IBOutlet NSButton *ibVariableEnableButton;
+       
+       NSResponder *_lastResponder;
+       
+       // ### IMPORTANT STUFF ###
+       BOOL _connectsOnOpen; // set whether connects automatically on open
+       TCDocumentMode _mode; // 'search' or 'cheat' mode
+       FadeView *_fadeView; // facilitates the fade animation
+       
+       TCDocumentStatus _status; // what the user is doing
+       BOOL _isCancelingTask; // is what the user doing being cancelled
+       BOOL _isTargetPaused; // is the currently selected process paused
+       
+       id _serverObject; // the object represented by the current server
+       Process *_process; // the currently selected process
+       
+       CheatData *_cheatData; // container for the document data
+       SearchData *_searchData; // container for the search data
+       
+       Cheater *_cheater; // the local or remote object to handle the cheating
+       
+       // rendezvous support
+       NSNetService *_resolvingService;
+}
+
+// #############################################################################
+#pragma mark Service Finding
+// #############################################################################
+
++ (NSArray *)cheatServices;
+
+// #############################################################################
+#pragma mark Changing Mode
+// #############################################################################
+
+// used to set the mode before the nib is loaded.
+// do not use after that.
+- (void)setMode:(TCDocumentMode)mode;
+
+// use this after the nib is loaded.
+- (void)switchToCheatMode;
+- (void)switchToSearchMode;
+
+// #############################################################################
+#pragma mark Accessors
+// #############################################################################
+
+- (NSString *)defaultStatusString;
+- (BOOL)isLoadedFromFile;
+
+- (void)addServer:(NSMenuItem *)item;
+- (void)removeServerWithObject:(id)serverObject;
+
+// #############################################################################
+#pragma mark Interface
+// #############################################################################
+
+- (void)updateInterface;
+- (void)setDocumentChanged;
+
+- (void)setActualResults:(unsigned)count;
+
+// #############################################################################
+#pragma mark Utility
+// #############################################################################
+
++ (void)setGlobalTarget:(Process *)target;
++ (Process *)globalTarget;
+
+- (void)showError:(NSString *)error;
+
+// this doesn't update the interface
+// so explicitly call updateInterface after use.
+- (BOOL)shouldConnectWithServer:(NSMenuItem *)item;
+- (void)selectConnectedCheater;
+- (void)connectWithServer:(NSMenuItem *)item;
+- (void)disconnectFromCheater;
+
+- (void)setConnectOnOpen:(BOOL)flag;
+- (void)connectWithURL:(NSString *)url;
+
+- (void)watchVariables;
+
+
+@end
+
+
+// #############################################################################
+
+@interface CheatDocument ( DocInterfaceActions )
+
+- (IBAction)ibSetLocalCheater:(id)sender;
+- (IBAction)ibSetRemoteCheater:(id)sender;
+- (IBAction)ibSetCustomCheater:(id)sender;
+- (IBAction)ibSetNoCheater:(id)sender;
+
+- (IBAction)ibSetProcess:(id)sender;
+
+- (IBAction)ibSetVariableType:(id)sender;
+- (IBAction)ibSetIntegerSign:(id)sender;
+- (IBAction)ibSetOperator:(id)sender;
+- (IBAction)ibSetValueUsed:(id)sender;
+
+- (IBAction)ibClearSearch:(id)sender;
+- (IBAction)ibSearch:(id)sender;
+- (IBAction)ibAddSearchVariable:(id)sender;
+
+- (IBAction)ibSetCheatRepeats:(id)sender;
+- (IBAction)ibSetRepeatInterval:(id)sender;
+- (IBAction)ibCheat:(id)sender;
+
+- (IBAction)ibRunPropertiesSheet:(id)sender;
+- (IBAction)ibEndPropertiesSheet:(id)sender;
+
+- (IBAction)ibRunPasswordSheet:(id)sender;
+- (IBAction)ibEndPasswordSheet:(id)sender;
+
+- (IBAction)ibRunCustomServerSheet:(id)sender;
+- (IBAction)ibEndCustomServerSheet:(id)sender;
+
+- (IBAction)ibRunEditVariablesSheet:(id)sender;
+- (IBAction)ibEndEditVariablesSheet:(id)sender;
+
+- (IBAction)ibPauseTarget:(id)sender;
+- (IBAction)ibResumeTarget:(id)sender;
+
+- (IBAction)ibCancelSearch:(id)sender;
+- (IBAction)ibStopCheat:(id)sender;
+
+- (IBAction)ibDumpMemory:(id)sender;
+- (IBAction)ibCancelDump:(id)sender;
+
+- (IBAction)ibAddCheatVariable:(id)sender;
+- (IBAction)ibSetVariableEnabled:(id)sender;
+
+- (IBAction)ibToggleSearchCheat:(id)sender;
+
+- (IBAction)ibUndo:(id)sender;
+- (IBAction)ibRedo:(id)sender;
+
+@end
+
+
+// #############################################################################
+
+@interface CheatDocument ( DocCheaterDelegate ) < CheaterDelegate >
+
+@end
+
diff --git a/CheatDocument.m b/CheatDocument.m
new file mode 100644 (file)
index 0000000..b058d74
--- /dev/null
@@ -0,0 +1,1287 @@
+
+// **********************************************************************
+// 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 "CheatDocument.h"
+
+
+// GLOBALS
+// service browsing globals
+unsigned static _tc_document_count = 0;
+NSNetServiceBrowser static *_tc_service_browser = nil;
+NSMutableArray static *_tc_cheat_services = nil;
+// global target
+Process static *_tc_target = nil;
+
+
+@interface CheatDocument ( PrivateAPI )
+
+// mode switching
+- (void)_switchTo:(NSView *)destination from:(NSView *)source;
+// using the service browser
++ (void)_documentCreated;
++ (void)_documentDestroyed;
+// service addition/removal
+- (void)_cheatServiceFound:(NSNotification *)note;
+- (void)_cheatServiceRemoved:(NSNotification *)note;
+// interface
+- (void)_setupInitialInterface;
+// notifications
+- (void)_displayValuesPrefChanged:(NSNotification *)note;
+- (void)_windowOnTopPrefChanged:(NSNotification *)note;
+- (void)_hitsDisplayedPrefChanged:(NSNotification *)note;
+
+@end
+
+@interface NSTableView ( PrivateAPI )
+
+- (NSRange)_rowsInRectAssumingRowsCoverVisible:(NSRect)rect;
+
+@end
+
+
+@implementation CheatDocument
+
+
+// #############################################################################
+#pragma mark Initialization
+// #############################################################################
+
+- (id)init // designated
+{
+       if ( self = [super init] )
+       {
+               NSNotificationCenter *nc= [NSNotificationCenter defaultCenter];
+               
+               ChazLog( @"init doc %X", self );
+               [CheatDocument _documentCreated];
+               
+               // register for service change notifications
+               [nc addObserver:self selector:@selector(_cheatServiceFound:) name:TCServiceFoundNote object:nil];
+               [nc addObserver:self selector:@selector(_cheatServiceRemoved:) name:TCServiceRemovedNote object:nil];
+               
+               _cheatData = [[CheatData alloc] init];
+               _searchData = [[SearchData alloc] init];
+               
+               // show search mode when documents are first created
+               _connectsOnOpen = YES;
+               [self setMode:TCSearchMode];
+       }
+       return self;
+}
+
+- (id)initWithContentsOfFile:(NSString *)fileName ofType:(NSString *)docType
+{
+       if ( self = [super initWithContentsOfFile:fileName ofType:docType] )
+       {
+               // if document opened from a file, show cheat mode by default
+               [self setMode:TCCheatMode];
+       }
+       return self;
+}
+
+- (id)initWithContentsOfURL:(NSURL *)aURL ofType:(NSString *)docType
+{
+       if ( self = [super initWithContentsOfURL:aURL ofType:docType] )
+       {
+               // if document opened from a URL, show cheat mode by default
+               [self setMode:TCCheatMode];
+       }
+       return self;
+}
+
+- (void)dealloc
+{
+       ChazLog( @"dealloc doc %X", self );
+       
+       // unregister observers
+       [(NSNotificationCenter *)[NSNotificationCenter defaultCenter] removeObserver:self];
+       
+       [_cheater setDelegate:nil];
+       [self disconnectFromCheater];
+       
+       [_cheatData release];
+       [_searchData release];
+       
+       [_serverObject release];
+       [_process release];
+       
+       // release the fade if one is occuring
+       [_fadeView removeFromSuperview];
+       [_fadeView release];
+       
+       [CheatDocument _documentDestroyed];
+       
+       [super dealloc];
+}
+
+
+// #############################################################################
+#pragma mark Nib Loading
+// #############################################################################
+
+- (NSString *)windowNibName
+{
+    return @"CheatDocument";
+}
+
+- (void)windowControllerDidLoadNib:(NSWindowController *)aController
+{
+       [super windowControllerDidLoadNib:aController];
+       
+       NSNotificationCenter *nc= [NSNotificationCenter defaultCenter];
+       
+       // register for app launch/quit notifications
+       [nc addObserver:self selector:@selector(_displayValuesPrefChanged:) name:TCDisplayValuesChangedNote object:nil];
+       [nc addObserver:self selector:@selector(_windowOnTopPrefChanged:) name:TCWindowsOnTopChangedNote object:nil];
+       [nc addObserver:self selector:@selector(_hitsDisplayedPrefChanged:) name:TCHitsDisplayedChangedNote object:nil];
+       
+       // setup window frame saving
+       [ibWindow useOptimizedDrawing:YES];
+       [ibWindow setFrameAutosaveName:@"TCCheatWindow"];
+       
+       // set options
+       if ( [[NSUserDefaults standardUserDefaults] boolForKey:TCWindowsOnTopPref] )
+       {
+               [ibWindow setLevel:NSPopUpMenuWindowLevel];
+       }
+
+       // display one of the modes
+       if ( _mode == TCCheatMode ) {
+               [self _switchTo:ibCheatContentView from:ibPlaceView];
+       }
+       else if ( _mode == TCSearchMode ) {
+               [self _switchTo:ibSearchContentView from:ibPlaceView];
+       }
+       
+       // configure the initial interface
+       [self _setupInitialInterface];
+       
+       // update interface
+       [ibStatusText setDefaultStatus:[self defaultStatusString]];
+       [self updateInterface];
+       
+       // automatically connect to the local cheater
+       if ( _connectsOnOpen ) {
+               [self ibSetLocalCheater:nil];
+       }
+       
+       ChazLog( @"superview: %@", [[ibSearchVariableTable superview] superview] );
+}
+
+
+// #############################################################################
+#pragma mark Handling Files
+// #############################################################################
+
+- (NSData *)dataRepresentationOfType:(NSString *)type
+{
+    return [NSArchiver archivedDataWithRootObject:_cheatData];
+}
+
+- (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)type
+{
+       [_cheatData release];
+       _cheatData = nil;
+       
+       if ( [type isEqualToString:@"Cheat Document"] ) {
+               NS_DURING
+                       _cheatData = [[NSUnarchiver unarchiveObjectWithData:data] retain];
+               NS_HANDLER
+                       if ( !_cheatData ) {
+                               // alert the user of the unparsable file
+                               NSBeep();
+                               NSRunAlertPanel( @"The Cheat can't read file.", @"The file \"%@\" can't be read.  It is probably not a cheat file, or it may be corrupted.", @"OK", nil, nil, [self fileName] );
+                               return NO;
+                       }
+               NS_ENDHANDLER
+       }
+       
+       [self updateInterface];
+       
+    return YES;
+}
+
+
+// #############################################################################
+#pragma mark Service Finding
+// #############################################################################
+
++ (NSArray *)cheatServices
+{
+       return [NSArray arrayWithArray:_tc_cheat_services];
+}
+
+
+- (void)_cheatServiceFound:(NSNotification *)note
+{
+       NSMenuItem *menuItem;
+       NSNetService *item = [note object];
+       
+       // add the newly found service to the server popup
+       menuItem = [[NSMenuItem alloc] init];
+       [menuItem setTarget:self];
+       [menuItem setAction:@selector(ibSetRemoteCheater:)];
+       [menuItem setTitle:[item name]];
+       [menuItem setRepresentedObject:item];
+       [self addServer:menuItem];
+       [menuItem release];
+}
+
+- (void)_cheatServiceRemoved:(NSNotification *)note
+{
+       NSNetService *item = [note object];
+       
+       // remove the service from the menu
+       [self removeServerWithObject:item];
+}
+
+
+// using the service browser
++ (void)_documentCreated
+{
+       _tc_document_count++;
+       
+       if ( _tc_document_count == 1 ) {
+               // first document created, so start the service browser
+               [_tc_service_browser stop];
+               [_tc_cheat_services release];
+               // create and setup the browser
+               _tc_service_browser = [[NSNetServiceBrowser alloc] init];
+               [_tc_service_browser setDelegate:self];
+               [_tc_service_browser searchForServicesOfType:@"_cheat._tcp." inDomain:@""];
+               // create the service array
+               _tc_cheat_services = [[NSMutableArray alloc] init];
+       }
+}
+
++ (void)_documentDestroyed
+{
+       _tc_document_count--;
+       
+       if ( _tc_document_count == 0 ) {
+               // last document destroyed, so stop the service browser
+               [_tc_service_browser stop];
+               [_tc_cheat_services release];
+               // set the globals to nil for safety
+               _tc_service_browser = nil;
+               _tc_cheat_services = nil;
+       }
+}
+
+
+// NSNetServiceBrowser delegate methods
++ (void)netServiceBrowserWillSearch:(NSNetServiceBrowser *)browser
+{
+       ChazLog( @"service browser will search" );
+}
+
++ (void)netServiceBrowserDidStopSearch:(NSNetServiceBrowser *)browser
+{
+       // if the browser stops we assume it needs to die.
+       ChazLog( @"service browser did stop search" );
+       [browser release];
+}
+
++ (void)netServiceBrowser:(NSNetServiceBrowser *)browser didNotSearch:(NSDictionary *)errorDict
+{
+       ChazLog( @"service browser failed with error code: %i", [[errorDict objectForKey:NSNetServicesErrorCode] intValue] );
+}
+
++ (void)netServiceBrowser:(NSNetServiceBrowser *)browser didFindService:(NSNetService *)aNetService moreComing:(BOOL)moreComing
+{
+       ChazLog( @"service browser found service: %@", [aNetService name] );
+       
+       // ignore if this is the local server.
+       if ( [[(AppController *)NSApp cheatServer] isListening] &&
+                [[aNetService name] isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:TCBroadcastNamePref]] ) {
+               return;
+       }
+       
+       [_tc_cheat_services addObject:aNetService];
+       // send a notification for the new service
+       [[NSNotificationCenter defaultCenter] postNotificationName:TCServiceFoundNote object:aNetService];
+}
+
++ (void)netServiceBrowser:(NSNetServiceBrowser *)browser didRemoveService:(NSNetService *)aNetService moreComing:(BOOL)moreComing
+{
+       ChazLog( @"service browser removed service: %@", [aNetService name] );
+       
+       [_tc_cheat_services removeObject:aNetService];
+       // send a notification for the new service
+       [[NSNotificationCenter defaultCenter] postNotificationName:TCServiceRemovedNote object:aNetService];
+}
+
+
+// #############################################################################
+#pragma mark Changing Mode
+// #############################################################################
+
+- (void)setMode:(TCDocumentMode)mode
+{
+       // if the nib isn't loaded, change the mode
+       if ( !ibWindow ) {
+               _mode = mode;
+       }
+}
+
+
+- (void)switchToCheatMode
+{
+       NSResponder *responder = [ibWindow firstResponder];
+       
+       if ( [responder isKindOfClass:[NSText class]] ) {
+               /* Since text views et al. make the field editor the first
+               responder, you have to take its delegate since that will
+               be set to the actual text view. */
+               responder = [(NSText *)responder delegate];
+       }
+       
+       if ( _mode == TCCheatMode ) {
+               return;
+       }
+       _mode = TCCheatMode;
+       [self _switchTo:ibCheatContentView from:ibSearchContentView];
+       
+       // update the next key view
+       [ibProcessPopup setNextKeyView:ibCheatVariableTable];
+       // update current key view
+       if ( !_lastResponder || _lastResponder == ibWindow ) {
+               // set default responder
+               [ibWindow makeFirstResponder:ibCheatVariableTable];
+       }
+       else {
+               [ibWindow makeFirstResponder:_lastResponder];
+       }
+       _lastResponder = responder;
+}
+
+- (void)switchToSearchMode
+{
+       NSResponder *responder = [ibWindow firstResponder];
+       
+       if ( [responder isKindOfClass:[NSText class]] ) {
+               responder = [(NSText *)responder delegate];
+       }
+       
+       if ( _mode == TCSearchMode ) {
+               return;
+       }
+       _mode = TCSearchMode;
+       [self _switchTo:ibSearchContentView from:ibCheatContentView];
+       
+       // update the next key view
+       [ibProcessPopup setNextKeyView:ibSearchTypePopup];
+       // update current key view
+       if ( !_lastResponder || _lastResponder == ibWindow ) {
+               [ibWindow makeFirstResponder:ibSearchValueField];
+       }
+       else {
+               [ibWindow makeFirstResponder:_lastResponder];
+       }
+       _lastResponder = responder;
+}
+
+
+- (void)_switchTo:(NSView *)destination from:(NSView *)source
+{
+       NSView *contentView = [ibWindow contentView];
+       NSRect frame = [source frame];
+       NSImage *fadeImage = nil;
+       
+       if ( gFadeAnimationDuration != 0.0 && [source lockFocusIfCanDraw] ) {
+               // draw the view to the representation
+               NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[source bounds]];
+               [source unlockFocus];
+               
+               // create the image object
+               fadeImage = [[NSImage alloc] initWithSize:frame.size];
+               [fadeImage addRepresentation:imageRep];
+               
+               if ( _fadeView ) {
+                       // remove the old fade view
+                       [_fadeView removeFromSuperview];
+                       [_fadeView release];
+               }
+               
+               // create the new fade view and start the fade
+               _fadeView = [[FadeView alloc] initWithFrame:frame];
+               [_fadeView setAutoresizingMask:[source autoresizingMask]];
+               [_fadeView setDelegate:self];
+               [_fadeView setImage:fadeImage];
+               [_fadeView setFadeDuration:gFadeAnimationDuration];
+               [contentView addSubview:_fadeView];
+               [_fadeView startFadeAnimation];
+               
+               [fadeImage release];
+       }
+       
+       // update view size of incoming view
+       [destination setFrame:frame];
+       // replace the views
+       [contentView replaceSubview:source with:destination];
+}
+
+
+// FadeView Delegate
+- (void)fadeViewFinishedAnimation:(FadeView *)theView
+{
+       [_fadeView removeFromSuperview];
+       [_fadeView release];
+       _fadeView = nil;
+}
+
+
+// #############################################################################
+#pragma mark Accessors
+// #############################################################################
+
+- (NSString *)defaultStatusString
+{
+       if ( !_cheater ) {
+               return @"Not Connected";
+       }
+       return [NSString stringWithFormat:@"Connected to %@.", [_cheater hostAddress]];
+}
+
+- (BOOL)isLoadedFromFile
+{
+       return ([self fileName] != nil);
+}
+
+
+- (void)addServer:(NSMenuItem *)item
+{
+       NSMenu *serverMenu = [ibServerPopup menu];
+       
+       if ( item ) {
+               if ( [serverMenu numberOfItems] <= 2 ) {
+                       // separator line
+                       [serverMenu addItem:[NSMenuItem separatorItem]];
+               }
+               [serverMenu addItem:item];
+       }
+}
+
+- (void)removeServerWithObject:(id)serverObject
+{
+       NSMenu *serverMenu = [ibServerPopup menu];
+       
+       if ( serverObject ) {
+               [serverMenu removeItemWithRepresentedObject:serverObject];
+               if ( [serverMenu numberOfItems] == 3 ) {
+                       // separator line
+                       [serverMenu removeItemAtIndex:2];
+               }
+       }
+}
+
+
+// #############################################################################
+#pragma mark Interface
+// #############################################################################
+
+- (void)_setupInitialInterface
+{
+       NSMenu *serverMenu;
+       NSMenuItem *menuItem;
+       
+       NSArray *cheatServices;
+       unsigned i, len;
+       
+       // create and set the server popup menu
+       serverMenu = [[NSMenu alloc] init];
+       [serverMenu setAutoenablesItems:YES];
+       // add menu items
+       // local connection item
+       menuItem = [[NSMenuItem alloc] init];
+       [menuItem setTarget:self];
+       [menuItem setAction:@selector(ibSetLocalCheater:)];
+       [menuItem setTitle:@"On This Computer"];
+       [menuItem setRepresentedObject:[NSNull null]];
+       [serverMenu addItem:menuItem];
+       [menuItem release];
+       // arbitrary connection item
+       menuItem = [[NSMenuItem alloc] init];
+       [menuItem setTarget:self];
+       [menuItem setAction:@selector(ibRunCustomServerSheet:)];
+       [menuItem setTitle:[NSString stringWithFormat:@"Other Server%C", 0x2026]];
+       [menuItem setKeyEquivalent:@"k"];
+       [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask];
+       [serverMenu addItem:menuItem];
+       [menuItem release];
+       // set the menu
+       [ibServerPopup setMenu:serverMenu];
+       [serverMenu release];
+       
+       // add current list of rendezvous services
+       cheatServices = [CheatDocument cheatServices];
+       len = [cheatServices count];
+       for ( i = 0; i < len; i++ ) {
+               NSNetService *item = [cheatServices objectAtIndex:i];
+               menuItem = [[NSMenuItem alloc] init];
+               [menuItem setTarget:self];
+               [menuItem setAction:@selector(ibSetRemoteCheater:)];
+               [menuItem setTitle:[item name]];
+               [menuItem setRepresentedObject:item];
+               [self addServer:menuItem];
+               [menuItem release];
+       }
+       
+       [ibSearchVariableTable setDoubleAction:@selector(ibAddSearchVariable:)];
+       [ibSearchVariableTable setCanDelete:NO];
+       
+       // BUG: for some reason IB doesn't like to set the default selection
+       // for an NSMatrix to anything but the first cell, so set this explicitly.
+       [ibSearchValueUsedMatrix selectCellWithTag:TCGivenValue];
+       
+       // we use undoing/redoing for reverting search results
+       [self setHasUndoManager:NO];
+}
+
+- (void)updateInterface
+{
+       if ( _cheatData )
+       {
+               // if there is cheat data, fill in the data information
+               [ibWindow setTitle:[self displayName]];
+               if ( [_cheatData process] ) {
+                       if ( [[_cheatData cheatInfo] isEqualToString:@""] ) {
+                               [ibCheatInfoText setStringValue:[NSString stringWithFormat:@"%@ %@",
+                                       [_cheatData gameName],
+                                       [_cheatData gameVersion]]];
+                       }
+                       else {
+                               [ibCheatInfoText setStringValue:[NSString stringWithFormat:@"%@ %@ - %@",
+                                       [_cheatData gameName],
+                                       [_cheatData gameVersion],
+                                       [_cheatData cheatInfo]]];
+                       }
+               }
+               else {
+                       [ibCheatInfoText setStringValue:[_cheatData cheatInfo]];
+               }
+               
+               [ibCheatRepeatButton setState:[_cheatData repeats]];
+               [ibCheatRepeatField setDoubleValue:[_cheatData repeatInterval]];
+       }
+       
+       // if we're connected...
+       if ( _cheater )
+       {
+               if ( _status == TCIdleStatus )
+               {
+                       // WINDOW
+                       [ibServerPopup setEnabled:YES];
+                       [ibProcessPopup setEnabled:YES];
+                       // SEARCH MODE
+                       [ibSearchValueUsedMatrix setEnabled:YES];
+                       if ( [_searchData hasSearchedOnce] ) {
+                               [ibSearchTypePopup setEnabled:NO];
+                               [ibSearchIntegerSignMatrix setEnabled:NO];
+                               [[ibSearchValueUsedMatrix cellWithTag:TCLastValue] setEnabled:YES];
+                               if ( [_searchData valueUsed] == TCGivenValue ) {
+                                       [ibSearchValueField setEnabled:YES];
+                               }
+                               else {
+                                       [ibSearchValueField setEnabled:NO];
+                               }
+                               [ibSearchClearButton setEnabled:YES];
+                               [ibSearchVariableTable setEnabled:YES];
+                               int selectedRows = [ibSearchVariableTable numberOfSelectedRows];
+                               if ( selectedRows > 0 ) {
+                                       [ibSearchVariableButton setEnabled:YES];
+                               }
+                               else {
+                                       [ibSearchVariableButton setEnabled:NO];
+                               }
+                       }
+                       else {
+                               [ibSearchTypePopup setEnabled:YES];
+                               if ( [_searchData isTypeInteger] ) {
+                                       [ibSearchIntegerSignMatrix setEnabled:YES];
+                               }
+                               else {
+                                       [ibSearchIntegerSignMatrix setEnabled:NO];
+                               }
+                               [[ibSearchValueUsedMatrix cellWithTag:TCLastValue] setEnabled:NO];
+                               [ibSearchValueUsedMatrix selectCellWithTag:[_searchData valueUsed]];
+                               [ibSearchValueField setEnabled:YES];
+                               [ibSearchClearButton setEnabled:NO];
+                               [ibSearchVariableTable setEnabled:NO];
+                               [ibSearchVariableButton setEnabled:NO];
+                       }
+                       if ( [_searchData variableType] != TCString ) {
+                               [ibSearchOperatorPopup setEnabled:YES];
+                       }
+                       else {
+                               [ibSearchOperatorPopup setEnabled:NO];
+                       }
+                       [ibSearchButton setTitle:@"Search"];
+                       [ibSearchButton setAction:@selector(ibSearch:)];
+                       [ibSearchButton setKeyEquivalent:@""];
+                       [ibSearchButton setEnabled:YES];
+                       // CHEAT MODE
+                       [ibCheatVariableTable setEnabled:YES];
+                       [ibCheatRepeatButton setEnabled:YES];
+                       [ibCheatRepeatAuxText setTextColor:[NSColor controlTextColor]];
+                       [ibCheatRepeatField setEnabled:[_cheatData repeats]];
+                       [ibCheatButton setTitle:@"Apply Cheat"];
+                       [ibCheatButton setAction:@selector(ibCheat:)];
+                       [ibCheatButton setKeyEquivalent:@"\r"];
+                       if ( [_cheatData enabledVariableCount] > 0 ) {
+                               [ibCheatButton setEnabled:YES];
+                               if ( [[_cheatData process] sameApplicationAs:_process] ) {
+                                       [ibCheatButton setKeyEquivalent:@"\r"];
+                               }
+                               else {
+                                       [ibCheatButton setKeyEquivalent:@""];
+                               }
+                       }
+                       else {
+                               [ibCheatButton setEnabled:NO];
+                       }
+               }
+               else
+               {
+                       // WINDOW
+                       [ibServerPopup setEnabled:NO];
+                       [ibProcessPopup setEnabled:NO];
+                       // SEARCH MODE
+                       [ibSearchTypePopup setEnabled:NO];
+                       [ibSearchIntegerSignMatrix setEnabled:NO];
+                       [ibSearchOperatorPopup setEnabled:NO];
+                       [ibSearchValueUsedMatrix setEnabled:NO];
+                       [ibSearchValueField setEnabled:NO];
+                       [ibSearchClearButton setEnabled:NO];
+                       [ibSearchVariableTable setEnabled:NO];
+                       [ibSearchVariableButton setEnabled:NO];
+                       // CHEAT MODE
+                       [ibCheatVariableTable setEnabled:NO];
+                       [ibCheatRepeatButton setEnabled:NO];
+                       [ibCheatRepeatAuxText setTextColor:[NSColor disabledControlTextColor]];
+                       [ibCheatRepeatField setEnabled:NO];
+                       
+                       if ( _status == TCSearchingStatus ) {
+                               [ibSearchButton setTitle:@"Cancel"];
+                               [ibSearchButton setAction:@selector(ibCancelSearch:)];
+                               [ibSearchButton setKeyEquivalent:@"\E"];
+                               [ibSearchButton setEnabled:!_isCancelingTask];
+                               [ibCheatButton setTitle:@"Apply Cheat"];
+                               [ibCheatButton setAction:@selector(ibCheat:)];
+                               if ( [[_cheatData process] sameApplicationAs:_process] ) {
+                                       [ibCheatButton setKeyEquivalent:@"\r"];
+                               }
+                               else {
+                                       [ibCheatButton setKeyEquivalent:@""];
+                               }
+                               [ibCheatButton setEnabled:NO];
+                       }
+                       else if ( _status == TCCheatingStatus ) {
+                               [ibSearchButton setTitle:@"Search"];
+                               [ibSearchButton setAction:@selector(ibSearch:)];
+                               [ibSearchButton setKeyEquivalent:@""];
+                               [ibSearchButton setEnabled:NO];
+                               [ibCheatButton setTitle:@"Stop Cheat"];
+                               [ibCheatButton setAction:@selector(ibStopCheat:)];
+                               [ibCheatButton setKeyEquivalent:@"\E"];
+                               [ibCheatButton setEnabled:!_isCancelingTask];
+                       }
+                       else {
+                               [ibSearchButton setTitle:@"Search"];
+                               [ibSearchButton setAction:@selector(ibSearch:)];
+                               [ibSearchButton setKeyEquivalent:@""];
+                               [ibSearchButton setEnabled:NO];
+                               [ibCheatButton setTitle:@"Apply Cheat"];
+                               [ibCheatButton setAction:@selector(ibCheat:)];
+                               if ( [[_cheatData process] sameApplicationAs:_process] ) {
+                                       [ibCheatButton setKeyEquivalent:@"\r"];
+                               }
+                               else {
+                                       [ibCheatButton setKeyEquivalent:@""];
+                               }
+                               [ibCheatButton setEnabled:NO];
+                       }
+               }
+       }
+       else
+       {
+               // WINDOW
+               [ibServerPopup setEnabled:YES];
+               [ibProcessPopup setEnabled:NO];
+               // SEARCH MODE
+               [ibSearchTypePopup setEnabled:NO];
+               [ibSearchIntegerSignMatrix setEnabled:NO];
+               [ibSearchOperatorPopup setEnabled:NO];
+               [ibSearchValueUsedMatrix setEnabled:NO];
+               [ibSearchValueField setEnabled:NO];
+               [ibSearchButton setEnabled:NO];
+               [ibSearchClearButton setEnabled:NO];
+               [ibSearchVariableTable setEnabled:NO];
+               [ibSearchVariableButton setEnabled:NO];
+               // CHEAT MODE
+               [ibCheatVariableTable setEnabled:NO];
+               [ibCheatRepeatButton setEnabled:NO];
+               [ibCheatRepeatAuxText setTextColor:[NSColor disabledControlTextColor]];
+               [ibCheatRepeatField setEnabled:NO];
+               [ibCheatButton setEnabled:NO];
+       }
+}
+
+
+- (void)setActualResults:(unsigned)count
+{
+       unsigned recieved = [_searchData numberOfResults];
+       
+       if ( count == 0 ) {
+               [ibSearchVariableTable setToolTip:@""];
+       }
+       else if ( recieved == count ) {
+               if ( count == 1 ) {
+                       [ibSearchVariableTable setToolTip:[NSString stringWithFormat:@"Displaying one result."]];
+               }
+               else {
+                       [ibSearchVariableTable setToolTip:[NSString stringWithFormat:@"Displaying %i results.", count]];
+               }
+       }
+       else if ( recieved < count ) {
+               [ibSearchVariableTable setToolTip:[NSString stringWithFormat:@"Displaying %i of %i results.", recieved, count]];
+       }
+}
+
+
+- (NSString *)displayName
+{
+       // override the default window title if there is a custom one
+       NSString *title = [_cheatData windowTitle];
+       
+       if ( !title || [title isEqualToString:@""] ) {
+               return [super displayName];
+       }
+       return title;
+}
+
+- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
+{
+       //ChazLog( @"validate menuitem: %@", [menuItem title] );
+       
+       // the undo/redo
+       if ( [menuItem action] == @selector(ibUndo:) ) {
+               if ( [_searchData undoesLeft] > 0 ) {
+                       return YES;
+               }
+               else {
+                       return NO;
+               }
+       }
+       if ( [menuItem action] == @selector(ibRedo:) ) {
+               if ( [_searchData redoesLeft] > 0 ) {
+                       return YES;
+               }
+               else {
+                       return NO;
+               }
+       }
+       
+       // the add variables items
+       if ( [menuItem action] == @selector(ibAddCheatVariable:) && _status == TCCheatingStatus ) {
+               return NO;
+       }
+
+       // the 'pause' menu item
+       if ( [menuItem tag] == 1000 ) {
+               if ( !_cheater ) {
+                       return NO;
+               }
+               if ( _isTargetPaused ) {
+                       [menuItem setTitle:@"Resume Target"];
+                       [menuItem setAction:@selector(ibResumeTarget:)];
+               }
+               else {
+                       [menuItem setTitle:@"Pause Target"];
+                       [menuItem setAction:@selector(ibPauseTarget:)];
+               }
+       }
+       
+       // the 'memory dump' menu item
+       else if ( [menuItem tag] == 1001 ) {
+               if ( !_cheater || _status != TCIdleStatus ) {
+                       return NO;
+               }
+       }
+       // the 'mode switch' menu item
+       else if ( [menuItem tag] == 1002 ) {
+               if ( _mode == TCSearchMode ) {
+                       [menuItem setTitle:@"Show Cheat Mode"];
+               }
+               else /* _mode == TCCheatMode */ {
+                       [menuItem setTitle:@"Show Search Mode"];
+               }
+       }
+       // the 'edit variables' menu item
+       else if ( [menuItem tag] == 1003 ) {
+               return (_mode == TCCheatMode && [ibCheatVariableTable selectedRow] != -1);
+       }
+       // the 'clear search' menu item
+       else if ( [menuItem tag] == 1004 ) {
+               return [ibSearchClearButton isEnabled];
+       }
+       // the cancel menu item
+       else if ( [menuItem tag] == 1005 ) {
+               if ( !_cheater || _isCancelingTask ) {
+                       return NO;
+               }
+               if ( _status == TCSearchingStatus ) {
+                       [menuItem setTitle:@"Cancel Search"];
+                       [menuItem setAction:@selector(ibCancelSearch:)];
+               }
+               else if ( _status == TCCheatingStatus ) {
+                       [menuItem setTitle:@"Stop Cheat"];
+                       [menuItem setAction:@selector(ibStopCheat:)];
+               }
+               else if ( _status == TCDumpingStatus ) {
+                       [menuItem setTitle:@"Cancel Dump"];
+                       [menuItem setAction:@selector(ibCancelDump:)];
+               }
+               else {
+                       return NO;
+               }
+       }
+       
+       return [super validateMenuItem:menuItem];
+}
+
+
+- (void)setDocumentChanged
+{
+       // only count document changes if there are variables
+       // and if the pref is set
+       if ( [[NSUserDefaults standardUserDefaults] boolForKey:TCAskForSavePref] &&
+                ([_cheatData variableCount] > 0 || [self isLoadedFromFile]) ) {
+               [self updateChangeCount:NSChangeDone];
+       }
+}
+
+
+- (int)numberOfRowsInTableView:(NSTableView *)aTableView
+{
+       if ( aTableView == ibCheatVariableTable ) {
+               return [_cheatData variableCount];
+       }
+       else if ( aTableView == ibSearchVariableTable ) {
+               return [_searchData numberOfResults];
+       }
+       return 0;
+}
+
+- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
+{
+       NSString *identifier = [aTableColumn identifier];
+       
+       if ( aTableView == ibCheatVariableTable ) {
+               Variable *variable = [_cheatData variableAtIndex:rowIndex];
+               
+               if ( [identifier isEqualToString:@"enable"] ) {
+                       return [NSNumber numberWithBool:[variable isEnabled]];
+               }
+               else if ( [identifier isEqualToString:@"variable"] ) {
+                       return [variable typeString];
+               }
+               else if ( [identifier isEqualToString:@"address"] ) {
+                       return [variable addressString];
+               }
+               else if ( [identifier isEqualToString:@"value"] ) {
+                       return [variable stringValue];
+               }
+       }
+       else if ( aTableView == ibSearchVariableTable ) {
+               return [_searchData stringForRow:rowIndex];
+       }
+       return @"";
+}
+
+- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
+{
+       NSString *identifier = [aTableColumn identifier];
+       
+       if ( aTableView == ibCheatVariableTable ) {
+               Variable *variable = [_cheatData variableAtIndex:rowIndex];
+               
+               if ( [identifier isEqualToString:@"address"] ) {
+                       if ( [variable setAddressString:anObject] ) {
+                               [self setDocumentChanged];
+                       }
+               }
+               else if ( [identifier isEqualToString:@"value"] ) {
+                       if ( [variable setStringValue:anObject] ) {
+                               [self setDocumentChanged];
+                       }
+               }
+       }
+}
+
+- (void)tableViewSelectionDidChange:(NSNotification *)aNotification
+{
+       NSTableView *aTableView = [aNotification object];
+       
+       if ( aTableView == ibSearchVariableTable ) {
+               int selectedRows = [aTableView numberOfSelectedRows];
+               if ( selectedRows > 1 ) {
+                       [ibSearchVariableButton setTitle:@"Add Variables"];
+               }
+               else if (  selectedRows == 1 ) {
+                       [ibSearchVariableButton setTitle:@"Add Variable"];
+               }
+       }
+}
+
+
+- (BOOL)tableViewDidReceiveEnterKey:(NSTableView *)tableView
+{
+       if ( tableView == ibSearchVariableTable ) {
+               [ibSearchVariableButton performClick:nil];
+               return YES;
+       }
+       return NO;
+}
+
+- (BOOL)tableViewDidReceiveSpaceKey:(NSTableView *)tableView
+{
+       if ( tableView == ibCheatVariableTable ) {
+               [self ibSetVariableEnabled:nil];
+               return YES;
+       }
+       return NO;
+}
+
+- (NSString *)tableViewPasteboardType:(NSTableView *)tableView
+{
+       return @"TCVariablePboardType";
+}
+
+- (NSData *)tableView:(NSTableView *)tableView copyRows:(NSArray *)rows
+{
+       NSMutableArray *vars;
+       int i, top;
+       
+       top = [rows count];
+       vars = [[NSMutableArray alloc] initWithCapacity:top];
+       
+       // add the new variables
+       if ( tableView == ibSearchVariableTable ) {
+               for ( i = 0; i < top; i++ ) {
+                       unsigned index = [[rows objectAtIndex:i] unsignedIntValue];
+                       [vars addObject:[_searchData variableAtIndex:index]];
+               }
+       }
+       else {
+               for ( i = 0; i < top; i++ ) {
+                       unsigned index = [[rows objectAtIndex:i] unsignedIntValue];
+                       [vars addObject:[_cheatData variableAtIndex:index]];
+               }
+       }
+       
+       return [NSArchiver archivedDataWithRootObject:[vars autorelease]];
+}
+
+- (void)tableView:(NSTableView *)tableView pasteRowsWithData:(NSData *)rowData
+{
+       NSArray *vars = [NSUnarchiver unarchiveObjectWithData:rowData];
+       int i, top, lastRow;
+       
+       if ( tableView == ibSearchVariableTable ) {
+               NSBeep();
+               return;
+       }
+       
+       top = [vars count];
+       for ( i = 0; i < top; i++ ) {
+               Variable *var = [vars objectAtIndex:i];
+               [_cheatData addVariable:var];
+       }
+       
+       lastRow = [_cheatData variableCount]-1;
+       [tableView reloadData];
+       if ( MacOSXVersion() >= 0x1030 ) {
+               [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:lastRow] byExtendingSelection:NO];
+       }
+       else {
+               [tableView selectRow:lastRow byExtendingSelection:NO];
+       }
+       [tableView scrollRowToVisible:lastRow];
+       
+       [self setDocumentChanged];
+       [self updateInterface];
+}
+
+- (void)tableView:(NSTableView *)tableView deleteRows:(NSArray *)rows
+{
+       int i, len;
+       
+       if ( tableView == ibCheatVariableTable ) {
+               len = [rows count];
+               for ( i = len-1; i >= 0; i-- ) {
+                       [_cheatData removeVariableAtIndex:[[rows objectAtIndex:i] unsignedIntValue]];
+               }
+               // reselect the last item if the selection is now invalid
+               len = [_cheatData variableCount] - 1;
+               if ( [tableView selectedRow] > len ) {
+                       if ( MacOSXVersion() >= 0x1030 ) {
+                               [tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:len] byExtendingSelection:NO];
+                       }
+                       else {
+                               [tableView selectRow:len byExtendingSelection:NO];
+                       }
+               }
+               [tableView reloadData];
+               
+               [self setDocumentChanged];
+               [self updateInterface];
+       }
+}
+
+// VariableTable Delegate
+- (void)tableView:(NSTableView *)aTableView didChangeVisibleRows:(NSRange)rows
+{
+       ChazLog( @"new visible rows: %@", NSStringFromRange( rows ) );
+       if ( [_searchData valuesLoaded] ) {
+               [self watchVariables];
+       }
+}
+
+
+// #############################################################################
+#pragma mark Utility
+// #############################################################################
+
++ (void)setGlobalTarget:(Process *)target
+{
+       [target retain];
+       [_tc_target release];
+       _tc_target = target;
+}
+
++ (Process *)globalTarget
+{
+       return _tc_target;
+}
+
+
+- (void)showError:(NSString *)error
+{
+       NSColor *red = [NSColor colorWithCalibratedRed:0.7 green:0.0 blue:0.0 alpha:1.0];
+       NSBeep();
+       [ibStatusText setDefaultStatus:[self defaultStatusString]];
+       [ibStatusText setTemporaryStatus:[NSString stringWithFormat:@"Error: %@", error] color:red duration:7.0];
+}
+
+
+- (BOOL)shouldConnectWithServer:(NSMenuItem *)item
+{
+       id serverObject;
+       
+       if ( _resolvingService ) {
+               // don't connect if a service is being resolved
+               [ibServerPopup selectItemAtIndex:[ibServerPopup indexOfItemWithRepresentedObject:_resolvingService]];
+               return NO;
+       }
+       
+       if ( [item respondsToSelector:@selector(representedObject)] ) {
+               serverObject = [item representedObject];
+       }
+       else {
+               serverObject = [NSNull null];
+       }
+       
+       if ( [_serverObject isEqual:serverObject] ) {
+               // already connected, don't connect
+               return NO;
+       }
+       return YES;
+}
+
+- (void)selectConnectedCheater
+{
+       int index = [ibServerPopup indexOfItemWithRepresentedObject:_serverObject];
+       if ( index != -1 ) {
+               [ibServerPopup selectItemAtIndex:index];
+       }
+}
+
+- (void)connectWithServer:(NSMenuItem *)item
+{
+       id serverObject;
+       
+       if ( [item respondsToSelector:@selector(representedObject)] ) {
+               serverObject = [item representedObject];
+       }
+       else {
+               serverObject = [NSNull null];
+       }
+       
+       // save a reference to the server object
+       [serverObject retain];
+       [_serverObject release];
+       _serverObject = serverObject;
+}
+
+- (void)disconnectFromCheater
+{
+       NSMenu *blankMenu;
+       
+       // don't do anything if we are already disconnected
+       if ( !_cheater ) {
+               return;
+       }
+       
+       _status = TCIdleStatus;
+       
+       // clear the search
+       [_searchData clearResults];
+       [ibSearchVariableTable reloadData];
+       
+       // clear the selected process
+       [_process release];
+       _process = nil;
+       [_serverObject release];
+       _serverObject = nil;
+       
+       if ( ![self isLoadedFromFile] ) {
+               [_cheatData setProcess:nil];
+       }
+       
+       // clear the process menu
+       blankMenu = [[NSMenu alloc] initWithTitle:@""];
+       [blankMenu addItemWithTitle:@"" action:NULL keyEquivalent:@""];
+       [ibProcessPopup setMenu:blankMenu];
+       [blankMenu release];
+       
+       // kill the connection
+       [_cheater disconnect];
+       [_cheater release];
+       _cheater = nil;
+}
+
+
+- (void)setConnectOnOpen:(BOOL)flag
+{
+       _connectsOnOpen = flag;
+}
+
+- (void)connectWithURL:(NSString *)url
+{
+       NSMenu *serverMenu = [ibServerPopup menu];
+       NSURL *theUrl = [NSURL URLWithString:url];
+       
+       NSString *host;
+       int port;
+       
+       NSData *addrData;
+       int indexIfAlreadyExists;
+       
+       host = [theUrl host];
+       port = [[theUrl port] intValue];
+       
+       if ( !host ) {
+               NSBeginInformationalAlertSheet( @"The Cheat can't parse the URL.", @"OK", nil, nil, ibWindow, self, NULL, NULL, NULL,
+                                                                               @"The Cheat can't connect to the server because \"%@\" is not a valid URL.", url );
+               goto FAILURE;
+       }
+       
+       // use default port number
+       if ( !port ) {
+               port = TCDefaultListenPort;
+       }
+       
+       addrData = [MySocket addressWithHost:host port:port];
+       if ( !addrData ) {
+               NSBeginInformationalAlertSheet( @"The Cheat can't find the server.", @"OK", nil, nil, ibWindow, self, NULL, NULL, NULL,
+                                                                               @"The Cheat can't connect to the server \"%@\" because it can't be found.", host );
+               goto FAILURE;
+       }
+       
+       indexIfAlreadyExists = [serverMenu indexOfItemWithRepresentedObject:addrData];
+       if ( indexIfAlreadyExists == -1 ) {
+               NSMenuItem *menuItem;
+               // add the newly found service to the server popup
+               menuItem = [[NSMenuItem alloc] init];
+               [menuItem setTarget:self];
+               [menuItem setAction:@selector(ibSetCustomCheater:)];
+               [menuItem setTitle:[NSString stringWithFormat:@"%@:%i", host, port]];
+               [menuItem setRepresentedObject:addrData];
+               [self addServer:menuItem];
+               // select new item
+               [self ibSetCustomCheater:menuItem];
+               // cleanup
+               [menuItem release];
+       }
+       else {
+               // select matching item
+               [self ibSetCustomCheater:[serverMenu itemAtIndex:indexIfAlreadyExists]];
+       }
+       
+FAILURE:;
+       [self selectConnectedCheater];
+}
+
+
+- (void)watchVariables
+{
+       NSRange range;
+       
+       if ( [[NSUserDefaults standardUserDefaults] boolForKey:TCDisplayValuesPref] ) {
+               float interval = [[NSUserDefaults standardUserDefaults] floatForKey:TCValueUpdatePref];
+               
+               range = [ibSearchVariableTable visibleRows];
+               [_cheater watchVariablesAtIndex:range.location count:range.length interval:interval];
+       }
+       else {
+               [_cheater stopWatchingVariables];
+       }
+}
+
+
+// #############################################################################
+#pragma mark Notifications
+// #############################################################################
+
+- (void)_displayValuesPrefChanged:(NSNotification *)note
+{
+       [self watchVariables];
+}
+
+- (void)_windowOnTopPrefChanged:(NSNotification *)note
+{
+       ChazLog( @"_windowOnTopPrefChanged" );
+       if ( [[NSUserDefaults standardUserDefaults] boolForKey:TCWindowsOnTopPref] ) {
+               [ibWindow setLevel:NSPopUpMenuWindowLevel];
+       }
+       else {
+               [ibWindow setLevel:NSNormalWindowLevel];
+       }
+}
+
+- (void)_hitsDisplayedPrefChanged:(NSNotification *)note
+{
+       // send preferences to the cheater
+       [_cheater limitReturnedResults:[[NSUserDefaults standardUserDefaults] integerForKey:TCHitsDisplayedPref]];
+}
+
+
+@end
diff --git a/CheatListener.h b/CheatListener.h
deleted file mode 100644 (file)
index e2a3d66..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      CheatListener.h
-// Created:   Wed Sep 24 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#import <Cocoa/Cocoa.h>
-#import <Chaz/Chaz.h>
-
-#import "ListenerDelegate.h"
-
-#include "cheat_globals.h"
-#include "cheat_net.h"
-
-#include "stdio.h"
-
-@class CheatServer;
-
-
-@interface CheatListener : NSObject
-{
-       id                              rootProxy;
-       int                             sockfd;
-
-       BOOL                    listenRemote;
-}
-
-+ (NSConnection *)listenerWithDelegate:(id)del port:(int)port remote:(BOOL)remote;
-+ (void)listenerThread:(NSArray *)array;
-
-- (id)initWithRootProxy:(id)proxy;
-
-- (void)listenOnPort:(int)port remote:(BOOL)remote;
-- (void)run;
-- (void)cleanup;
-
-@end
\ No newline at end of file
diff --git a/CheatListener.m b/CheatListener.m
deleted file mode 100644 (file)
index 1f3869e..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      CheatListener.m
-// Created:   Wed Sep 24 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#import "CheatListener.h"
-
-#import "CheatServer.h"
-
-#include <string.h>
-
-
-@implementation CheatListener
-
-
-+ (NSConnection *)listenerWithDelegate:(id)del port:(int)port remote:(BOOL)remote
-{
-       NSPort                          *rPort = [NSPort port], *sPort = [NSPort port];
-       NSConnection            *connection;
-       NSArray                         *array;
-
-       connection = [[NSConnection alloc] initWithReceivePort:rPort sendPort:sPort];
-       [connection setRootObject:del];
-
-       array = [NSArray arrayWithObjects:sPort, rPort, [NSNumber numberWithInt:port], [NSNumber numberWithBool:remote], nil];
-       [NSThread detachNewThreadSelector:@selector(listenerThread:) toTarget:self withObject:array];
-
-       return [connection autorelease];
-}
-
-+ (void)listenerThread:(NSArray *)array
-{
-       NSAutoreleasePool       *pool = [[NSAutoreleasePool alloc] init];
-    NSConnection               *connection = [NSConnection connectionWithReceivePort:[array objectAtIndex:0] sendPort:[array objectAtIndex:1]];
-    CheatListener              *object = [[self alloc] initWithRootProxy:[connection rootProxy]];
-
-       [object listenOnPort:[[array objectAtIndex:2] intValue] remote:[[array objectAtIndex:3] boolValue]];
-       [object run];
-       [object cleanup];
-
-    [object release];
-    [pool release];
-}
-
-
-- (id)initWithRootProxy:(id)proxy
-{
-       if ( self = [super init] )
-       {
-               rootProxy = proxy;
-               sockfd = -1;
-       }
-
-       return self;
-}
-
-
-- (void)listenOnPort:(int)port remote:(BOOL)remote
-{
-       short                                   family = remote? AF_INET : AF_UNIX;
-       
-       int                                             yes = 1;        // for setsockopt()
-
-       if ( (sockfd = socket( family, SOCK_STREAM, 0 )) == -1 )
-       {
-               CMLog( @"ERROR: failed to start server because socket() failed" );
-               [rootProxy listenerError:@"Network Error" message:@"Server couldn't start.  Local can't be cheated."];
-               return;
-       }
-
-       if ( family == AF_INET )
-       {
-               struct sockaddr_in              addr;
-
-               addr.sin_family = family;
-               addr.sin_port = htonl( port );
-               addr.sin_addr.s_addr = INADDR_ANY;
-
-               if ( setsockopt( sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int) ) == -1 )
-               {
-                       CMLog( @"ERROR: failed to start server because setsockopt() failed" );
-                       [rootProxy listenerError:@"Network Error" message:@"Server couldn't start.  Local can't be cheated."];
-                       return;
-               }
-
-               if ( bind( sockfd, (struct sockaddr *)(&addr), sizeof(struct sockaddr) ) == -1 )
-               {
-                       CMLog( @"ERROR: failed to start server because bind() failed" );
-                       [rootProxy listenerError:@"Network Error" message:@"The cheat server could not start, probably because the port is already in use.  Local can not be cheated."];
-                       return;
-               }
-       }
-       else
-       {
-               struct sockaddr_un              addr;
-
-               addr.sun_family = family;
-               strncpy( addr.sun_path, TCDefaultListenPath, 103 );
-
-               remove( TCDefaultListenPath );
-
-               if ( bind( sockfd, (struct sockaddr *)(&addr), sizeof(addr) ) == -1 )
-               {
-                       CMLog( @"ERROR: failed to start server because bind() failed" );
-                       [rootProxy listenerError:@"Network Error" message:@"The cheat server could not start, probably because the path is already in use.  Local can not be cheated."];
-                       return;
-               }
-       }
-
-       if ( listen( sockfd, 50 ) == -1 )
-       {
-               CMLog( @"ERROR: failed to start server because listen() failed" );
-               [rootProxy listenerError:@"Network Error" message:@"Server couldn't start.  Local can't be cheated."];
-               return;
-       }
-
-       listenRemote = remote;
-
-       [rootProxy listenerListeningWithSocket:sockfd];
-}
-
-- (void)run
-{
-       int                                             result;
-
-       CMLog( @"LISTENER start" );
-
-       if ( listenRemote )
-       {
-               struct sockaddr_in              addr;
-               int                                             addrLen;
-               
-               for (;;)
-               {
-                       addrLen = sizeof(addr);
-                       
-                       if ( (result = accept( sockfd, (struct sockaddr *)(&addr), &addrLen )) == -1 )
-                       {
-                               break;
-                       }
-
-                       [rootProxy listenerReceivedNewConnection:result];
-               }
-       }
-       else
-       {
-               struct sockaddr_un              addr;
-               int                                             addrLen;
-
-               for (;;)
-               {
-                       addrLen = sizeof(addr);
-                       
-                       if ( (result = accept( sockfd, (struct sockaddr *)(&addr), &addrLen )) == -1 )
-                       {
-                               break;
-                       }
-
-                       [rootProxy listenerReceivedNewConnection:result];
-               }
-       }
-
-       CMLog( @"LISTENER close" );
-
-       [rootProxy listenerDisconnected];
-}
-
-- (void)cleanup
-{
-       if ( listenRemote )
-       {
-               remove( TCDefaultListenPath );
-       }
-}
-
-
-@end
\ No newline at end of file
index 92e602c5dabe09fc4ac38dd7b2231a5bc63d4e5d..f67f748464be69b8639b7d7f01b952217b53e818 100644 (file)
 
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      CheatServer.h
-// Created:   Sun Sep 07 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 <Cocoa/Cocoa.h>
-#import <Chaz/Chaz.h>
+#import "ChazLog.h"
 
-#import "ServerDelegate.h"
+#import "MySocket.h"
 
-#include <mach/vm_map.h>
-#include <mach/mach_traps.h>
+#import "ServerChild.h"
 
-#include <malloc/malloc.h>
 
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <sys/wait.h>
-#include <unistd.h>
+@interface CheatServer : NSObject
+{
+       MySocket *_socket; // the socket that listens for connections
+       NSNetService *_netService; // for rendezvous broadcasting
+       
+       int _port; // port the socket is listening on
+       NSString *_name; // name the service is being broadcast as
+       
+       NSMutableArray *_children; // the server spawns
+       
+       id _delegate;
+}
 
-#include "cheat_types.h"
-#include "cheat_net.h"
+// initialization
+- (id)initWithDelegate:(id)delegate;
 
+// starting and stopping the server
+// it will automatically be stopped on dealloc.
+// pass nil for name to not broadcast.
+- (BOOL)listenOnPort:(int)port broadcast:(NSString *)name;
+- (void)stop;
 
-@class SearchResults;
+// accessing children
+// children are spawned by the server to handle remote sessions.
+// they are instances of the ServerChild class.
+- (int)childCount;
+- (NSArray *)children;
+- (void)removeChildAtIndex:(unsigned)index;
 
+// accessors
+- (BOOL)isListening;
+- (NSString *)host;
+- (int)port;
+- (NSString *)broadcast;
 
-@interface CheatServer : NSObject
-{
-       id                                      rootProxy;
-       int                                     sockfd;
+- (id)delegate;
+- (void)setDelegate:(id)delegate;
 
-       pid_t                           processID;
-       vm_map_t                        processTask;
+@end
 
-       BOOL                            processPaused;
 
-       NSMutableArray          *searchResults;
-       NSMutableArray          *searchResultsUndone;
-       int                                     searchResultsAmountDisplayed;
-}
+@interface NSObject ( CheatServerDelegate )
 
-+ (NSConnection *)serverWithDelegate:(id)delegate socket:(int)sock;
-+ (void)serverThread:(NSArray *)array;
-
-- (id)initWithRootProxy:(id)proxy;
-
-- (void)handleSocket:(int)sock;
-- (void)run;
-
-- (void)setAddress:(NSString *)address;
-- (void)setAction:(NSString *)action;
-
-- (void)firstSearchString8bit:(char const *)value size:(int)vsize;
-- (void)firstSearchIntegerChar:(int8_t)value;
-- (void)firstSearchIntegerShort:(int16_t)value;
-- (void)firstSearchIntegerLong:(int32_t)value;
-- (void)firstSearchDecimalFloat:(float)value;
-- (void)firstSearchDecimalDouble:(double)value;
-
-- (void)searchString8bit:(char const *)value size:(int)vsize;
-- (void)searchIntegerChar:(int8_t)value;
-- (void)searchIntegerShort:(int16_t)value;
-- (void)searchIntegerLong:(int32_t)value;
-- (void)searchDecimalFloat:(float)value;
-- (void)searchDecimalDouble:(double)value;
-
-- (void)changeString8bit:(char const *)value size:(int)vsize addresses:(TCaddress *)addresses count:(int)count;
-- (void)changeIntegerChar:(int8_t)value addresses:(TCaddress *)addresses count:(int)count;
-- (void)changeIntegerShort:(int16_t)value addresses:(TCaddress *)addresses count:(int)count;
-- (void)changeIntegerLong:(int32_t)value addresses:(TCaddress *)addresses count:(int)count;
-- (void)changeDecimalFloat:(float)value addresses:(TCaddress *)addresses count:(int)count;
-- (void)changeDecimalDouble:(double)value addresses:(TCaddress *)addresses count:(int)count;
-
-- (void)sendProcessList;
-- (void)sendSearchFinished;
-- (void)sendVariableList:(TCaddress const *)data amount:(int)amount;
-- (void)sendChangeFinished;
-- (void)sendError:(NSString *)msg fatal:(BOOL)fatal;
-- (void)sendVariableValue:(u_int32_t)index;
-- (void)sendUndoFinished;
-- (void)sendRedoFinished;
-- (void)sendUndoRedoStatus;
-- (void)sendAppLaunched:(NSDictionary *)appInfo;
-- (void)sendAppQuit:(NSDictionary *)appInfo;
-- (void)sendTargetAppQuit;
-- (void)sendPauseFinished:(BOOL)paused;
-
-- (void)handleClearSearch;
-- (void)handleSearch:(char const *)data size:(int)dataSize;
-- (void)handleChange:(char const *)data size:(int)dataSize;
-- (void)handlePauseTarget;
-- (void)handleUndo;
-- (void)handleRedo;
-- (void)handleSetTargetPID:(char const *)data size:(int)size;
-
-- (void)unpause;
-- (void)setPID:(pid_t)pid;
+// when the server dies while running...  would this ever happen?  I doubt it.
+- (void)serverDisconnectedUnexpectedly:(CheatServer *)theServer;
 
-@end
+// broadcast failed, this is much more likely to happen.
+// note that the server will continue running.
+- (void)server:(CheatServer *)theServer failedToBroadcastName:(NSString *)theName;
 
+// a connection was made or lost with the server...
+- (void)serverChildrenChanged:(CheatServer *)theServer;
+
+@end
index 04cbdd92fc877d5cef0c5ff2ff25a77036d1560e..f4a44ece609cd4dc5c9870cc9206cbf18cf657f8 100644 (file)
 
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      CheatServer.m
-// Created:   Sun Sep 07 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 "CheatServer.h"
 
-#import "SearchResults.h"
 
-// for comparing floats
-#import <Chaz/Misc.h>
+@interface CheatServer ( PrivateAPI )
 
-#include <string.h>
-#include <math.h>
-#include <errno.h>
+// delegate methods
+- (void)_performDelegateSelector:(SEL)selector;
+- (void)_performDelegateSelector:(SEL)selector withObject:(id)object;
 
-
-// Internal Functions
-int bmsearch( char *pat, int m, char *text, int n, void *base, void *loc[] );
-//BOOL inline compare_float( float a, float b );
-//BOOL inline compare_double( double a, double b );
+@end
 
 
 @implementation CheatServer
 
 
-+ (NSConnection *)serverWithDelegate:(id)delegate socket:(int)sock
-{
-       NSPort                          *rPort = [NSPort port], *sPort = [NSPort port];
-       NSConnection            *connection;
-       NSArray                         *array;
-
-       connection = [[NSConnection alloc] initWithReceivePort:rPort sendPort:sPort];
-       [connection setRootObject:delegate];
-
-       array = [NSArray arrayWithObjects:sPort, rPort, [NSNumber numberWithInt:sock], nil];
-       [NSThread detachNewThreadSelector:@selector(serverThread:) toTarget:self withObject:array];
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark Initialization
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-       return [connection autorelease];
-}
 
-+ (void)serverThread:(NSArray *)array
+- (id)initWithDelegate:(id)delegate
 {
-       NSAutoreleasePool       *pool = [[NSAutoreleasePool alloc] init];
-    NSConnection               *connection = [NSConnection connectionWithReceivePort:[array objectAtIndex:0] sendPort:[array objectAtIndex:1]];
-    CheatServer                        *object = [[self alloc] initWithRootProxy:[connection rootProxy]];
-
-       [object handleSocket:[[array objectAtIndex:2] intValue]];
-       [object run];
-
-    [object release];
-    [pool release];
-}
-
-
-- (id)initWithRootProxy:(id)proxy
-{
-       if ( self = [super init] )
-       {
-               NSNotificationCenter    *nc = [[NSWorkspace sharedWorkspace] notificationCenter];
-
-               rootProxy = proxy;
-
-               [nc addObserver:self selector:@selector(processListChanged:) name:@"NSWorkspaceDidLaunchApplicationNotification" object:nil];
-               [nc addObserver:self selector:@selector(processListChanged:) name:@"NSWorkspaceDidTerminateApplicationNotification" object:nil];
-
-               [self setPID:[rootProxy serverFirstProcess]];
-
-               processPaused = NO;
-
-               searchResults = [[NSMutableArray alloc] init];
-               searchResultsUndone = [[NSMutableArray alloc] init];
+       if ( self = [super init] ) {
+               _delegate = delegate;
        }
-
        return self;
 }
 
-
-- (void)handleSocket:(int)sock
-{
-       struct sockaddr                 identifier;
-       int                                             addrLen = sizeof(identifier);
-
-       NSString                                *address;
-       char                                    *addressCString;
-
-       sockfd = sock;
-
-       if ( getpeername( sockfd, &identifier, &addrLen ) == -1 )
-       {
-               CMLog( @"ERROR: getpeername() failed" );
-       }
-
-       if ( identifier.sa_family == AF_INET )
-       {
-               struct sockaddr_in              addr;
-
-               addrLen = sizeof(addr);
-
-               if ( getpeername( sockfd, (struct sockaddr *)(&addr), &addrLen ) == -1 )
-               {
-                       CMLog( @"ERROR: getpeername() failed" );
-               }
-
-               if ( (addressCString = inet_ntoa( addr.sin_addr )) == NULL )
-               {
-                       CMLog( @"ERROR: inet_ntoa() failed" );
-               }
-
-               address = [NSString stringWithCString:addressCString];
-       }
-       else
-       {
-               struct sockaddr_un              addr;
-
-               addrLen = sizeof(addr);
-
-               if ( getpeername( sockfd, (struct sockaddr *)(&addr), &addrLen ) == -1 )
-               {
-                       CMLog( @"ERROR: getpeername() failed" );
-               }
-
-               CMLog( @"client connection: %s", addr.sun_path );
-               
-               address = [NSString stringWithString:@"127.0.0.1"];
-       }
-
-       [rootProxy server:self connectedWithSocket:sockfd];
-
-       [self setAddress:address];
-       [self setAction:nil];
-}
-
-- (void)run
-{
-       struct timeval          tv;
-       fd_set                          fdset, master;
-       int                                     numfds;
-
-       int                                     result;
-
-       PacketHeader            header;
-       char                            *data = NULL;
-
-       tv.tv_sec = 2;
-       tv.tv_usec = 0;
-
-       FD_ZERO( &fdset );
-       FD_ZERO( &master );
-       FD_SET( sockfd, &master );
-
-       numfds = sockfd + 1;
-
-       CMLog( @"SERVER start" );
-
-       for (;;)
-       {
-               fdset = master;
-
-               select( numfds, &fdset, NULL, NULL, &tv );
-
-               if ( FD_ISSET( sockfd, &fdset ) )
-               {
-                       if ( (result = ReadBuffer( sockfd, (char *)(&header), sizeof(header) )) != sizeof(header) )
-                       {
-                               break;
-                       }
-
-                       if ( !VerifyChecksum( header.checksum ) )
-                       {
-                               CMLog( @"checksum failed" );
-                       }
-
-                       if ( header.size != 0 )
-                       {
-                               if ( (data = (char *)malloc( header.size )) == NULL )
-                               {
-                                       CMLog( @"failed to allocate buffer for reading a network packet" );
-                                       break;
-                               }
-
-                               if ( (result = ReadBuffer( sockfd, data, header.size )) != header.size )
-                               {
-                                       CMLog( @"failed to read the data of a network packet" );
-                                       free( data );
-                                       break;
-                               }
-                       }
-
-                       //CMLog( @"SERVER message %i/%i/%i", header.checksum, header.function, header.size );
-
-                       switch ( header.function )
-                       {
-                               case 1:
-                                       [self sendProcessList];
-                                       break;
-                                       
-                               case 3:
-                                       [self handleClearSearch];
-                                       break;
-
-                               case 5:
-                                       [self handleSearch:data size:header.size];
-                                       break;
-
-                               case 8:
-                                       [self handleChange:data size:header.size];
-                                       break;
-
-                               case 10:
-                                       [self handlePauseTarget];
-                                       break;
-
-                               case 14:
-                                       [self handleUndo];
-                                       break;
-
-                               case 16:
-                                       [self handleRedo];
-                                       break;
-
-                               case 18:
-                                       [self handleSetTargetPID:data size:header.size];
-                                       break;
-
-                       }
-
-                       if ( header.size != 0 )
-                       {
-                               free( data );
-                       }
-               }
-       }
-
-       close( sockfd );
-
-       CMLog( @"SERVER close" );
-
-       [rootProxy serverDisconnected:self];
-}
-
-
-- (void)setAddress:(NSString *)address
-{
-       [rootProxy server:self changedAddress:address];
-}
-
-- (void)setAction:(NSString *)action
-{
-       if ( action == nil )
-       {
-               [rootProxy server:self changedAction:@"Idle"];
-       }
-       else
-       {
-               [rootProxy server:self changedAction:action];
-       }
-}
-
-- (void)firstSearchString8bit:(char const *)value size:(int)vsize
-{
-       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                                            *data;
-       vm_size_t                                       dataLength;
-       
-       TCaddress                                       *results = NULL;
-       int                                                     resultsAmount = 0;
-       
-       for (;;)
-       {
-               if ( (result = vm_region( processTask, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
-               {
-                       if ( result != KERN_INVALID_ADDRESS )
-                       {
-                               CMLog( @"vm_region returned error: %i", result );
-                       }
-                       break;
-               }
-               
-               if ( (info.protection & VM_PROT_READ) && (info.protection & VM_PROT_WRITE))
-               {
-                       data = (char *)malloc( size );
-                       dataLength = size;
-                       
-                       if ( (result = vm_read_overwrite( processTask, address, size, (vm_address_t)data, &dataLength )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
-                       {
-                               CMLog( @"vm_read_overwrite returned error: %i", result );
-                               free( data );
-                               break;
-                       }
-                       
-                       if ( result == KERN_SUCCESS )
-                       {
-                               //int                           i, top = dataLength - vsize;
-                               
-                               if ( (results = realloc( results, TCAddressSize*resultsAmount + dataLength )) == NULL )
-                               {
-                                       CMLog( @"ERROR: could not expand buffer" );
-                                       exit(0);
-                               }
-                               
-                               resultsAmount += bmsearch( (char *)value, vsize, (char *)data, dataLength, (void *)address, (void **)((char *)results+TCAddressSize*resultsAmount) );
-                               //resultsAmount += TBM( (char *)value, vsize, data, dataLength, (void **)((char *)results+TCAddressSize*resultsAmount) );
-                               //resultsAmount += SMITH( data, dataLength, (char *)value, vsize, (void **)((char *)results+TCAddressSize*resultsAmount) );
-                               
-                               /*for ( i = 0; i < top; i++ )
-                               {
-                                       if ( strncmp( value, data+i, vsize ) == 0 )
-                                       {
-                                               results[resultsAmount++] = (TCaddress)address + i;
-                                       }
-                               }*/
-                       }
-                       
-                       free( data );
-               }
-               
-               address += size;
-       }
-       
-       realloc( results, TCAddressSize*resultsAmount );
-       [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_8_BIT data:results amount:resultsAmount]];
-       
-       CMLog( @"found %i of %i", resultsAmount, value );
-}
-
-- (void)firstSearchIntegerChar:(int8_t)value
-{
-       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;
-       
-       int8_t                                          *data;
-       vm_size_t                                       dataLength;
-       
-       TCaddress                                       *results = NULL;
-       int                                                     resultsAmount = 0;
-       
-       for (;;)
-       {
-               if ( (result = vm_region( processTask, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
-               {
-                       if ( result != KERN_INVALID_ADDRESS )
-                       {
-                               CMLog( @"vm_region returned error: %i", result );
-                       }
-                       break;
-               }
-               
-               if ( (info.protection & VM_PROT_READ) && (info.protection & VM_PROT_WRITE))
-               {
-                       data = (int8_t *)malloc( size );
-                       dataLength = size;
-                       
-                       if ( (result = vm_read_overwrite( processTask, address, size, (vm_address_t)data, &dataLength )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
-                       {
-                               CMLog( @"vm_read_overwrite returned error: %i", result );
-                               free( data );
-                               break;
-                       }
-                       
-                       if ( result == KERN_SUCCESS )
-                       {
-                               int                             i;
-                               
-                               if ( (results = (TCaddress *)realloc( results, TCAddressSize*resultsAmount + TCAddressSize*dataLength )) == NULL )
-                               {
-                                       CMLog( @"ERROR: could not expand buffer" );
-                                       exit(0);
-                               }
-                               
-                               for ( i = 0; i < dataLength; i++ )
-                               {
-                                       if ( *(data+i) == value )
-                                       {
-                                               results[resultsAmount++] = (TCaddress)address + i;
-                                       }
-                               }
-                       }
-                       
-                       free( data );
-               }
-               
-               address += size;
-       }
-       
-       realloc( results, TCAddressSize*resultsAmount );
-       [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_8_BIT data:results amount:resultsAmount]];
-       
-       CMLog( @"found %i of %i", resultsAmount, value );
-}
-
-- (void)firstSearchIntegerShort:(int16_t)value
-{
-       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;
-       
-       int16_t                                         *data;
-       vm_size_t                                       dataLength;
-       
-       TCaddress                                       *results = NULL;
-       int                                                     resultsAmount = 0;
-       
-       for (;;)
-       {
-               if ( (result = vm_region( processTask, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
-               {
-                       if ( result != KERN_INVALID_ADDRESS )
-                       {
-                               CMLog( @"vm_region returned error: %i", result );
-                       }
-                       break;
-               }
-               
-               if ( (info.protection & VM_PROT_READ) && (info.protection & VM_PROT_WRITE))
-               {
-                       data = (int16_t *)malloc( size );
-                       dataLength = size;
-                       
-                       if ( (result = vm_read_overwrite( processTask, address, size, (vm_address_t)data, &dataLength )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
-                       {
-                               CMLog( @"vm_read_overwrite returned error: %i", result );
-                               free( data );
-                               break;
-                       }
-                       
-                       if ( result == KERN_SUCCESS )
-                       {
-                               int                             i, top = dataLength / sizeof(value);
-                               
-                               if ( (results = (TCaddress *)realloc( results, TCAddressSize*resultsAmount + 2*dataLength )) == NULL )
-                               {
-                                       CMLog( @"ERROR: could not expand buffer" );
-                                       exit(0);
-                               }
-                               
-                               for ( i = 0; i < top; i++ )
-                               {
-                                       if ( *(data+i) == value )
-                                       {
-                                               results[resultsAmount++] = (TCaddress)address + i * sizeof(value);
-                                       }
-                               }
-                       }
-                       
-                       free( data );
-               }
-               
-               address += size;
-       }
-       
-       realloc( results, TCAddressSize*resultsAmount );
-       [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_16_BIT data:results amount:resultsAmount]];
-       
-       CMLog( @"found %i of %i", resultsAmount, value );
-}
-
-- (void)firstSearchIntegerLong:(int32_t)value
-{
-       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;
-       
-       int32_t                                         *data;
-       vm_size_t                                       dataLength;
-       
-       TCaddress                                       *results = NULL;
-       int                                                     resultsAmount = 0;
-       
-       /*unsigned                                      zone_count = 10;
-       vm_address_t                            *zones = (vm_address_t *)malloc( zone_count * sizeof(vm_address_t) );
-       //memory_reader_t                               reader;
-       
-       if ( (result = malloc_get_all_zones( processTask, NULL, &zones, &zone_count )) != KERN_SUCCESS )
-       {
-               CMLog( @"malloc_get_all_zones error: %i", result );
-       }
-       else
-       {
-               //address = zones[0];
-               
-               int                     i;
-               
-               for ( i = 0; i < 10; i++ )
-               {
-                       CMLog( @"malloc_get_all_zones[%i] = %X", i, (vm_address_t)zones[i] );
-               }
-       }*/
-       
-       for (;;)
-       {
-               if ( (result = vm_region( processTask, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
-               {
-                       if ( result != KERN_INVALID_ADDRESS )
-                       {
-                               CMLog( @"vm_region returned error: %i", result );
-                       }
-                       break;
-               }
-               
-               if ( (info.protection & VM_PROT_READ) && (info.protection & VM_PROT_WRITE) )
-               {
-                       data = (int32_t *)malloc( size );
-                       dataLength = size;
-                       
-                       //CMLog( @"address: %.8X size: %i", address, size );
-                       
-                       if ( (result = vm_read_overwrite( processTask, address, size, (vm_address_t)data, &dataLength )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
-                       {
-                               CMLog( @"vm_read_overwrite returned error: %i", result );
-                               free( data );
-                               break;
-                       }
-                       
-                       if ( result == KERN_SUCCESS )
-                       {
-                               int                             i, top = dataLength / sizeof(value);
-                               
-                               if ( (results = (TCaddress *)realloc( results, TCAddressSize*resultsAmount + dataLength )) == NULL )
-                               {
-                                       CMLog( @"ERROR: could not expand buffer" );
-                                       exit(0);
-                               }
-
-                               for ( i = 0; i < top; i++ )
-                               {
-                                       if ( *(data+i) == value )
-                                       {
-                                               results[resultsAmount++] = (TCaddress)address + i * sizeof(value);
-                                       }
-                               }
-                       }
-                       
-                       free( data );
-               }
-               
-               address += size;
-       }
-       
-       realloc( results, TCAddressSize*resultsAmount );
-       [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_32_BIT data:results amount:resultsAmount]];
-       
-       CMLog( @"found %i of %i", resultsAmount, value );
-}
-
-- (void)firstSearchDecimalFloat:(float)value
-{
-       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;
-       
-       float                                           *data;
-       vm_size_t                                       dataLength;
-       
-       TCaddress                                       *results = NULL;
-       int                                                     resultsAmount = 0;
-       
-       for (;;)
-       {
-               if ( (result = vm_region( processTask, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
-               {
-                       if ( result != KERN_INVALID_ADDRESS )
-                       {
-                               CMLog( @"vm_region returned error: %i", result );
-                       }
-                       break;
-               }
-               
-               if ( (info.protection & VM_PROT_READ) && (info.protection & VM_PROT_WRITE))
-               {
-                       data = (float *)malloc( size );
-                       dataLength = size;
-                       
-                       if ( (result = vm_read_overwrite( processTask, address, size, (vm_address_t)data, &dataLength )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
-                       {
-                               CMLog( @"vm_read_overwrite returned error: %i", result );
-                               free( data );
-                               break;
-                       }
-                       
-                       if ( result == KERN_SUCCESS )
-                       {
-                               int                             i, top = dataLength / sizeof(value);
-                               
-                               if ( (results = realloc( results, TCAddressSize*resultsAmount + dataLength )) == NULL )
-                               {
-                                       CMLog( @"ERROR: could not expand buffer" );
-                                       exit(0);
-                               }
-                               
-                               for ( i = 0; i < top; i++ )
-                               {
-                                       if ( CMCompareFloatsWithEpsilon( *(data+i), value, 0.1f ) == 0 )
-                                       {
-                                               results[resultsAmount++] = (TCaddress)address + i * sizeof(value);
-                                       }
-                               }
-                       }
-                       
-                       free( data );
-               }
-               
-               address += size;
-       }
-       
-       realloc( results, TCAddressSize*resultsAmount );
-       [searchResults addObject:[SearchResults resultsWithType:TYPE_DECIMAL size:SIZE_32_BIT data:results amount:resultsAmount]];
-       
-       CMLog( @"found %i of %i", resultsAmount, value );
-}
-
-- (void)firstSearchDecimalDouble:(double)value
-{
-       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;
-       
-       double                                          *data;
-       vm_size_t                                       dataLength;
-       
-       TCaddress                                       *results = NULL;
-       int                                                     resultsAmount = 0;
-       
-       CMLog( @"float search" );
-       
-       for (;;)
-       {
-               if ( (result = vm_region( processTask, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
-               {
-                       if ( result != KERN_INVALID_ADDRESS )
-                       {
-                               CMLog( @"vm_region returned error: %i", result );
-                       }
-                       break;
-               }
-               
-               if ( (info.protection & VM_PROT_READ) && (info.protection & VM_PROT_WRITE))
-               {
-                       data = (double *)malloc( size );
-                       dataLength = size;
-                       
-                       if ( (result = vm_read_overwrite( processTask, address, size, (vm_address_t)data, &dataLength )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
-                       {
-                               CMLog( @"vm_read_overwrite returned error: %i", result );
-                               free( data );
-                               break;
-                       }
-                       
-                       if ( result == KERN_SUCCESS )
-                       {
-                               int                             i, top = dataLength / sizeof(value);
-                               
-                               if ( (results = realloc( results, TCAddressSize*resultsAmount + dataLength )) == NULL )
-                               {
-                                       CMLog( @"ERROR: could not expand buffer" );
-                                       exit(0);
-                               }
-                               
-                               for ( i = 0; i < top; i++ )
-                               {
-                                       if ( CMCompareDoublesWithEpsilon( *(data+i), value, 0.1 ) == 0 )
-                                       {
-                                               results[resultsAmount++] = (TCaddress)address + i * sizeof(value);
-                                       }
-                               }
-                       }
-                       
-                       free( data );
-               }
-               
-               address += size;
-       }
-       
-       realloc( results, TCAddressSize*resultsAmount );
-       [searchResults addObject:[SearchResults resultsWithType:TYPE_DECIMAL size:SIZE_64_BIT data:results amount:resultsAmount]];
-       
-       CMLog( @"found %i of %i", resultsAmount, value );
-}
-
-
-- (void)searchString8bit:(char const *)value size:(int)vsize
-{
-       kern_return_t                           result;
-       
-       char                                            *data;
-       vm_size_t                                       dataLength;
-       
-       TCaddress                                       *results;
-       int                                                     resultsAmount = 0;
-       
-       SearchResults                           *lastResults = [searchResults lastObject];
-       TCaddress                                       *lastResultsData = [lastResults data];
-       int                                                     i, lastResultsAmount = [lastResults amount];
-       
-       if ( [lastResults type] != TYPE_INTEGER || [lastResults size] != SIZE_8_BIT )
-       {
-               [self sendError:@"This search is incompatible with the previous search." fatal:NO];
-               return;
-       }
-       
-       if ( (data = (char *)malloc( vsize )) == NULL )
-       {
-               CMLog( @"ERROR: could not create buffer" );
-               
-               [self sendError:@"The server cancelled the search because it ran out of memory." fatal:NO];
-               return;
-       }
-       
-       if ( (results = (TCaddress *)malloc( TCAddressSize*lastResultsAmount )) == NULL )
-       {
-               CMLog( @"ERROR: could not create buffer" );
-               
-               [self sendError:@"The server cancelled the search because it ran out of memory." fatal:NO];
-               free( data );
-               return;
-       }
-       
-       for ( i = 0; i < lastResultsAmount; i++ )
-       {
-               TCaddress               address = lastResultsData[i];
-               
-               //dataLength = sizeof(data);
-               
-               if ( (result = vm_read_overwrite( processTask, address, vsize, (vm_address_t)(data), &dataLength )) == KERN_SUCCESS )
-               {
-                       if ( memcmp( data, value, dataLength ) == 0 )
-                       {
-                               results[resultsAmount++] = address;
-                       }
-               }
-               else
-               {
-                       if ( result != KERN_PROTECTION_FAILURE )
-                       {
-                               CMLog( @"vm_read_overwrite returned error: %i", result );
-                               break;
-                       }
-               }
-       }
-       
-       realloc( results, TCAddressSize*resultsAmount );
-       [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_8_BIT data:results amount:resultsAmount]];
-       
-       free( data );
-       
-       CMLog( @"found %i of %i", resultsAmount, value );
-}
-
-- (void)searchIntegerChar:(int8_t)value
+- (void)dealloc
 {
-       kern_return_t                           result;
-       
-       int8_t                                          data;
-       vm_size_t                                       dataLength;
-       
-       TCaddress                                       *results;
-       int                                                     resultsAmount = 0;
-       
-       SearchResults                           *lastResults = [searchResults lastObject];
-       TCaddress                                       *lastResultsData = [lastResults data];
-       int                                                     i, lastResultsAmount = [lastResults amount];
-       
-       if ( [lastResults type] != TYPE_INTEGER || [lastResults size] != SIZE_8_BIT )
-       {
-               [self sendError:@"This search is incompatible with the previous search." fatal:NO];
-               return;
-       }
-       
-       if ( (results = (TCaddress *)malloc( TCAddressSize*lastResultsAmount )) == NULL )
-       {
-               CMLog( @"ERROR: could not create buffer" );
-               
-               [self sendError:@"The server cancelled the search because it ran out of memory." fatal:NO];
-               return;
-       }
-       
-       for ( i = 0; i < lastResultsAmount; i++ )
-       {
-               TCaddress               address = lastResultsData[i];
-               
-               dataLength = sizeof(data);
-               
-               if ( (result = vm_read_overwrite( processTask, address, sizeof(data), (vm_address_t)(&data), &dataLength )) == KERN_SUCCESS )
-               {
-                       if ( data == value )
-                       {
-                               results[resultsAmount++] = address;
-                       }
-               }
-               else
-               {
-                       if ( result != KERN_PROTECTION_FAILURE )
-                       {
-                               CMLog( @"vm_read_overwrite returned error: %i", result );
-                               break;
-                       }
-               }
-       }
-       
-       realloc( results, TCAddressSize*resultsAmount );
-       [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_8_BIT data:results amount:resultsAmount]];
-       
-       CMLog( @"found %i of %i", resultsAmount, value );
+       [self stop];
+       [super dealloc];
 }
 
-- (void)searchIntegerShort:(int16_t)value
-{
-       kern_return_t                           result;
-       
-       int16_t                                         data;
-       vm_size_t                                       dataLength;
-       
-       TCaddress                                       *results;
-       int                                                     resultsAmount = 0;
-       
-       SearchResults                           *lastResults = [searchResults lastObject];
-       TCaddress                                       *lastResultsData = [lastResults data];
-       int                                                     i, lastResultsAmount = [lastResults amount];
-       
-       if ( [lastResults type] != TYPE_INTEGER || [lastResults size] != SIZE_16_BIT )
-       {
-               [self sendError:@"This search is incompatible with the previous search." fatal:NO];
-               return;
-       }
-       
-       if ( (results = (TCaddress *)malloc( TCAddressSize*lastResultsAmount )) == NULL )
-       {
-               CMLog( @"ERROR: could not create buffer" );
-               
-               [self sendError:@"The server cancelled the search because it ran out of memory." fatal:NO];
-               return;
-       }
-       
-       for ( i = 0; i < lastResultsAmount; i++ )
-       {
-               TCaddress               address = lastResultsData[i];
-               
-               dataLength = sizeof(data);
-               
-               if ( (result = vm_read_overwrite( processTask, address, sizeof(data), (vm_address_t)(&data), &dataLength )) == KERN_SUCCESS )
-               {
-                       if ( data == value )
-                       {
-                               results[resultsAmount++] = address;
-                       }
-               }
-               else
-               {
-                       if ( result != KERN_PROTECTION_FAILURE )
-                       {
-                               CMLog( @"vm_read_overwrite returned error: %i", result );
-                               break;
-                       }
-               }
-       }
-       
-       realloc( results, TCAddressSize*resultsAmount );
-       [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_16_BIT data:results amount:resultsAmount]];
-       
-       CMLog( @"found %i of %i", resultsAmount, value );
-}
 
-- (void)searchIntegerLong:(int32_t)value
-{
-       kern_return_t                           result;
-       
-       int32_t                                         data;
-       vm_size_t                                       dataLength;
-       
-       TCaddress                                       *results;
-       int                                                     resultsAmount = 0;
-       
-       SearchResults                           *lastResults = [searchResults lastObject];
-       TCaddress                                       *lastResultsData = [lastResults data];
-       int                                                     i, lastResultsAmount = [lastResults amount];
-       
-       if ( [lastResults type] != TYPE_INTEGER || [lastResults size] != SIZE_32_BIT )
-       {
-               [self sendError:@"This search is incompatible with the previous search." fatal:NO];
-               return;
-       }
-       
-       if ( (results = (TCaddress *)malloc( TCAddressSize*lastResultsAmount )) == NULL )
-       {
-               CMLog( @"ERROR: could not create buffer" );
-               
-               [self sendError:@"The server cancelled the search because it ran out of memory." fatal:NO];
-               return;
-       }
-       
-       for ( i = 0; i < lastResultsAmount; i++ )
-       {
-               TCaddress               address = lastResultsData[i];
-               
-               dataLength = sizeof(data);
-               
-               if ( (result = vm_read_overwrite( processTask, address, sizeof(data), (vm_address_t)(&data), &dataLength )) == KERN_SUCCESS )
-               {
-                       if ( data == value )
-                       {
-                               results[resultsAmount++] = address;
-                       }
-               }
-               else
-               {
-                       if ( result != KERN_PROTECTION_FAILURE )
-                       {
-                               CMLog( @"vm_read_overwrite returned error: %i", result );
-                               break;
-                       }
-               }
-       }
-       
-       realloc( results, TCAddressSize*resultsAmount );
-       [searchResults addObject:[SearchResults resultsWithType:TYPE_INTEGER size:SIZE_32_BIT data:results amount:resultsAmount]];
-       
-       CMLog( @"found %i of %i", resultsAmount, value );
-}
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark Starting/Stopping
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-- (void)searchDecimalFloat:(float)value
+- (BOOL)listenOnPort:(int)port broadcast:(NSString *)name
 {
-       kern_return_t                           result;
-       
-       float                                           data;
-       vm_size_t                                       dataLength;
-       
-       TCaddress                                       *results;
-       int                                                     resultsAmount = 0;
-       
-       SearchResults                           *lastResults = [searchResults lastObject];
-       TCaddress                                       *lastResultsData = [lastResults data];
-       int                                                     i, lastResultsAmount = [lastResults amount];
-       
-       if ( [lastResults type] != TYPE_DECIMAL || [lastResults size] != SIZE_32_BIT )
-       {
-               [self sendError:@"This search is incompatible with the previous search." fatal:NO];
-               return;
-       }
-       
-       if ( (results = (TCaddress *)malloc( TCAddressSize*lastResultsAmount )) == NULL )
-       {
-               CMLog( @"ERROR: could not create buffer" );
-               
-               [self sendError:@"The server cancelled the search because it ran out of memory." fatal:NO];
-               return;
+       if ( [self isListening] ) {
+               // already running
+               return NO;
        }
        
-       for ( i = 0; i < lastResultsAmount; i++ )
-       {
-               TCaddress               address = lastResultsData[i];
-               
-               dataLength = sizeof(data);
-               
-               if ( (result = vm_read_overwrite( processTask, address, sizeof(data), (vm_address_t)(&data), &dataLength )) == KERN_SUCCESS )
-               {
-                       if ( CMCompareFloatsWithEpsilon( data, value, 0.1f ) == 0 )
-                       {
-                               results[resultsAmount++] = address;
-                       }
-               }
-               else
-               {
-                       if ( result != KERN_PROTECTION_FAILURE )
-                       {
-                               CMLog( @"vm_read_overwrite returned error: %i", result );
-                               break;
-                       }
-               }
+       // start the server
+       _socket = [[MySocket alloc] initWithDelegate:self];
+       if ( ![_socket listenOnPort:port] ) {
+               [_socket release];
+               _socket = nil;
+               return NO;
        }
        
-       realloc( results, TCAddressSize*resultsAmount );
-       [searchResults addObject:[SearchResults resultsWithType:TYPE_DECIMAL size:SIZE_32_BIT data:results amount:resultsAmount]];
-       
-       CMLog( @"found %i of %i", resultsAmount, value );
-}
-
-- (void)searchDecimalDouble:(double)value
-{
-       kern_return_t                           result;
-       
-       double                                          data;
-       vm_size_t                                       dataLength;
-       
-       TCaddress                                       *results;
-       int                                                     resultsAmount = 0;
-       
-       SearchResults                           *lastResults = [searchResults lastObject];
-       TCaddress                                       *lastResultsData = [lastResults data];
-       int                                                     i, lastResultsAmount = [lastResults amount];
+       _children = [[NSMutableArray alloc] init];
        
-       if ( [lastResults type] != TYPE_DECIMAL || [lastResults size] != SIZE_64_BIT )
-       {
-               [self sendError:@"This search is incompatible with the previous search." fatal:NO];
-               return;
-       }
-       
-       if ( (results = (TCaddress *)malloc( TCAddressSize*lastResultsAmount )) == NULL )
-       {
-               CMLog( @"ERROR: could not create buffer" );
-               
-               [self sendError:@"The server cancelled the search because it ran out of memory." fatal:NO];
-               return;
-       }
+       _port = port;
+       _name = [name retain];
        
-       for ( i = 0; i < lastResultsAmount; i++ )
-       {
-               TCaddress               address = lastResultsData[i];
-               
-               dataLength = sizeof(data);
-               
-               if ( (result = vm_read_overwrite( processTask, address, sizeof(data), (vm_address_t)(&data), &dataLength )) == KERN_SUCCESS )
-               {
-                       if ( CMCompareDoublesWithEpsilon( data, value, 0.1 ) == 0 )
-                       {
-                               results[resultsAmount++] = address;
-                       }
-               }
-               else
-               {
-                       if ( result != KERN_PROTECTION_FAILURE )
-                       {
-                               CMLog( @"vm_read_overwrite returned error: %i", result );
-                               break;
-                       }
-               }
+       // start the rendezvous broadcast
+       if ( _name ) { // domain: @"local."
+               _netService = [[NSNetService alloc] initWithDomain:@"" type:@"_cheat._tcp." name:_name port:port];
+               [_netService setDelegate:self];
+               [_netService publish];
        }
        
-       realloc( results, TCAddressSize*resultsAmount );
-       [searchResults addObject:[SearchResults resultsWithType:TYPE_DECIMAL size:SIZE_64_BIT data:results amount:resultsAmount]];
-       
-       CMLog( @"found %i of %i", resultsAmount, value );
+       return YES;
 }
 
-
-- (void)changeString8bit:(char const *)value size:(int)vsize addresses:(TCaddress *)addresses count:(int)count
+- (void)stop
 {
-       int                                     failCount = 0;
-       int                                     i;
-       
-       for ( i = 0; i < count; i++ )
-       {
-               if ( vm_write( processTask, (vm_address_t)addresses[i], (vm_offset_t)value, vsize ) != KERN_SUCCESS )
-               {
-                       failCount++;
-               }
-       }
+       // close the listener
+       [_socket disconnect];
+       [_socket release];
+       _socket = nil;
        
-       if ( failCount > 0 )
-       {
-               [self sendError:[NSString stringWithFormat:@"%i of the selected variables could not be changed.", failCount] fatal:NO];
-       }
-}
-
-- (void)changeIntegerChar:(int8_t)value addresses:(TCaddress *)addresses count:(int)count
-{
-       int                                     failCount = 0;
-       int                                     i;
+       // if broadcasting, stop
+       [_netService stop];
+       _netService = nil;
        
-       for ( i = 0; i < count; i++ )
-       {
-               if ( vm_write( processTask, (vm_address_t)addresses[i], (vm_offset_t)(&value), sizeof(value) ) != KERN_SUCCESS )
-               {
-                       failCount++;
-               }
-       }
+       [_children release];
+       _children = nil;
        
-       if ( failCount > 0 )
-       {
-               [self sendError:[NSString stringWithFormat:@"%i of the selected variables could not be changed.", failCount] fatal:NO];
-       }
+       _port = 0;
+       [_name release];
+       _name = nil;
 }
 
-- (void)changeIntegerShort:(int16_t)value addresses:(TCaddress *)addresses count:(int)count
-{
-       int                                     failCount = 0;
-       int                                     i;
-       
-       for ( i = 0; i < count; i++ )
-       {
-               if ( vm_write( processTask, (vm_address_t)addresses[i], (vm_offset_t)(&value), sizeof(value) ) != KERN_SUCCESS )
-               {
-                       failCount++;
-               }
-       }
-       
-       if ( failCount > 0 )
-       {
-               [self sendError:[NSString stringWithFormat:@"%i of the selected variables could not be changed.", failCount] fatal:NO];
-       }
-}
 
-- (void)changeIntegerLong:(int32_t)value addresses:(TCaddress *)addresses count:(int)count
-{
-       int                                     failCount = 0;
-       int                                     i;
-       
-       for ( i = 0; i < count; i++ )
-       {
-               if ( vm_write( processTask, (vm_address_t)addresses[i], (vm_offset_t)(&value), sizeof(value) ) != KERN_SUCCESS )
-               {
-                       failCount++;
-               }
-       }
-       
-       if ( failCount > 0 )
-       {
-               [self sendError:[NSString stringWithFormat:@"%i of the selected variables could not be changed.", failCount] fatal:NO];
-       }
-}
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark Accessing Children
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-- (void)changeDecimalFloat:(float)value addresses:(TCaddress *)addresses count:(int)count
-{
-       int                                     failCount = 0;
-       int                                     i;
-       
-       for ( i = 0; i < count; i++ )
-       {
-               if ( vm_write( processTask, (vm_address_t)addresses[i], (vm_offset_t)(&value), sizeof(value) ) != KERN_SUCCESS )
-               {
-                       failCount++;
-               }
-       }
-       
-       if ( failCount > 0 )
-       {
-               [self sendError:[NSString stringWithFormat:@"%i of the selected variables could not be changed.", failCount] fatal:NO];
-       }
-}
 
-- (void)changeDecimalDouble:(double)value addresses:(TCaddress *)addresses count:(int)count
+- (int)childCount
 {
-       int                                     failCount = 0;
-       int                                     i;
-       
-       for ( i = 0; i < count; i++ )
-       {
-               if ( vm_write( processTask, (vm_address_t)addresses[i], (vm_offset_t)(&value), sizeof(value) ) != KERN_SUCCESS )
-               {
-                       failCount++;
-               }
-       }
-       
-       if ( failCount > 0 )
-       {
-               [self sendError:[NSString stringWithFormat:@"%i of the selected variables could not be changed.", failCount] fatal:NO];
-       }
+       return [_children count];
 }
 
-
-- (void)sendProcessList
+- (NSArray *)children
 {
-       NSArray                 *processList = [rootProxy serverProcessList];
-       
-       NSNumber                *pid;
-       u_int32_t               pidNum;
-       NSString                *name;
-
-       PacketHeader    header;
-
-       char                    *buffer, *ptr;
-
-       //                       PROCESS COUNT
-       int                             length = sizeof(u_int32_t);
-       int                             lengthAfter;
-
-       u_int32_t               processCount = [processList count];
-
-       int                             i, max = processCount;
-
-       header.checksum = RandomChecksum();
-       header.function = 2;
-
-       for ( i = 0; i < max; i++ )
-       {
-               pid = [[processList objectAtIndex:i] objectForKey:@"NSApplicationProcessIdentifier"];
-               name = [[processList objectAtIndex:i] objectForKey:@"NSApplicationName"];
-
-               //        PID                 NAME
-               length += sizeof(u_int32_t) + [name length] + 1;
-       }
-
-       header.size = length;
-       length += sizeof(header);
-       //        HEADER
-
-       if ( (buffer = (char *)malloc( length ))==NULL )
-       {
-               CMLog( @"sendProcessList failed" );
-               return;
-       }
-
-       ptr = buffer;
-
-       COPY_TO_BUFFER( ptr, &header, sizeof(header) );
-       COPY_TO_BUFFER( ptr, &processCount, sizeof(processCount) );
-
-       for ( i = 0; i < max; i++ )
-       {
-               pidNum = [[[processList objectAtIndex:i] objectForKey:@"NSApplicationProcessIdentifier"] unsignedLongValue];
-               name = [[processList objectAtIndex:i] objectForKey:@"NSApplicationName"];
-
-               COPY_TO_BUFFER( ptr, &pidNum, sizeof(pid) );
-               COPY_TO_BUFFER( ptr, [name lossyCString], [name length] + 1 );
-       }
-
-       lengthAfter = length;
-
-       if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
-       {
-               CMLog( @"sendProcessList failed" );
-       }
-
-       free( buffer );
+       return [NSArray arrayWithArray:_children];
 }
 
-
-- (void)sendSearchFinished
+- (void)removeChildAtIndex:(unsigned)index
 {
-       PacketHeader    header;
-       int                             length = sizeof(header);
-
-       header.checksum = RandomChecksum();
-       header.function = 6;
-       header.size = 0;
-
-       if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
-       {
-               CMLog( @"sendSearchFinished failed" );
-       }
+       [_children removeObjectAtIndex:index];
 }
 
-- (void)sendVariableList:(TCaddress const *)data amount:(int)amount
-{
-       PacketHeader    header;
-       int                             length;
-       int                             lengthAfter;
-       int                             displayAmount = ( searchResultsAmountDisplayed > amount )? amount : searchResultsAmountDisplayed;
-       int                             resultsLength = TCAddressSize * displayAmount;
-
-       char                    *buffer, *ptr;
-
-       header.checksum = RandomChecksum();
-       header.function = 7;
-       header.size = sizeof(amount) + sizeof(displayAmount) + resultsLength;
-       //            AMOUNT           DISPLAY AMOUNT          DATA
-
-       lengthAfter = length = header.size + sizeof(header);
-
-       if ( (buffer = (char *)malloc( length )) == NULL )
-       {
-               CMLog( @"sendVariableList:amount: failed" );
-               return;
-       }
-
-       ptr = buffer;
-
-       COPY_TO_BUFFER( ptr, &header, sizeof(header) );
-       COPY_TO_BUFFER( ptr, &amount, sizeof(amount) );
-       COPY_TO_BUFFER( ptr, &displayAmount, sizeof(displayAmount) );
-       COPY_TO_BUFFER( ptr, data, resultsLength );
-
-       if ( SendBuffer( sockfd, buffer, &length ) == -1 || lengthAfter != length )
-       {
-               CMLog( @"sendVariableList:amount: failed" );
-       }
-
-       free( buffer );
-       
-       CMLog( @"SERVER sending %i out of %i results", displayAmount, amount );
-}
 
-- (void)sendChangeFinished
+- (void)serverChildConnected:(ServerChild *)theChild
 {
-       PacketHeader    header;
-       int                             length = sizeof(header);
-
-       header.checksum = RandomChecksum();
-       header.function = 9;
-       header.size = 0;
-
-       if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
-       {
-               CMLog( @"sendChangeFinished failed" );
+       if ( [self isListening] ) {
+               //[_children addObject:theChild];
+               [self _performDelegateSelector:@selector(serverChildrenChanged:)];
        }
 }
 
-- (void)sendError:(NSString *)msg fatal:(BOOL)fatal
+- (void)serverChildDisconnected:(ServerChild *)theChild
 {
-       PacketHeader    header;
-       int                             length;
-       int                             lengthAfter;
-
-       u_int32_t               type = (fatal)? 1:0;
-
-       char                    *buffer, *ptr;
-
-       header.checksum = RandomChecksum();
-       header.function = 11;
-       header.size = sizeof(type) + [msg length] + 1;
-       //            FATAL          STRING
-
-       lengthAfter = length = header.size + sizeof(header);
-
-       if ( (buffer = (char *)malloc( length )) == NULL )
-       {
-               CMLog( @"sendError:fatal: failed" );
-               return;
+       if ( [self isListening] ) {
+               [_children removeObject:theChild];
+               [self _performDelegateSelector:@selector(serverChildrenChanged:)];
        }
-
-       ptr = buffer;
-
-       COPY_TO_BUFFER( ptr, &header, sizeof(header) );
-       COPY_TO_BUFFER( ptr, &type, sizeof(type) );
-       COPY_TO_BUFFER( ptr, [msg lossyCString], [msg length] + 1 );
-
-       if ( SendBuffer( sockfd, buffer, &length ) == -1 || lengthAfter != length )
-       {
-               CMLog( @"sendError:fatal: failed" );
-       }
-
-       free( buffer );
 }
 
-- (void)sendVariableValue:(u_int32_t)index
+- (void)serverChildChanged:(ServerChild *)theChild
 {
-
+       [self _performDelegateSelector:@selector(serverChildrenChanged:)];
 }
 
-- (void)sendUndoFinished
-{
-       PacketHeader    header;
-       int                             length = sizeof(header);
 
-       header.checksum = RandomChecksum();
-       header.function = 15;
-       header.size = 0;
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark MySocketDelegate
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-       if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
-       {
-               CMLog( @"sendUndoFinished failed" );
-       }
-}
-
-- (void)sendRedoFinished
-{
-       PacketHeader    header;
-       int                             length = sizeof(header);
-
-       header.checksum = RandomChecksum();
-       header.function = 17;
-       header.size = 0;
-
-       if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
-       {
-               CMLog( @"sendRedoFinished failed" );
-       }
-}
 
-- (void)sendUndoRedoStatus
+- (void)socket:(MySocket *)mySocket didAcceptSocket:(MySocket *)newSocket
 {
-       PacketHeader    header;
-       int                             length;
-       int                             lengthAfter;
-       
-       u_int32_t               undoCount = (u_int32_t)[searchResults count];
-       u_int32_t               redoCount = (u_int32_t)[searchResultsUndone count];
-       
-       char                    *buffer, *ptr;
-       
-       header.checksum = RandomChecksum();
-       header.function = 19;
-       header.size = 2 * sizeof(u_int32_t);
-       
-       length = lengthAfter = sizeof(header) + header.size;
-       
-       if ( (buffer = (char *)malloc( length )) == NULL )
-       {
-               CMLog( @"sendSetTargetPID: failed" );
-       }
+       ChazLog( @"CheatServer - MySocket accepted another one!!" );
        
-       ptr = buffer;
+       ServerChild *child;
        
-       COPY_TO_BUFFER( ptr, &header, sizeof(header) );
-       COPY_TO_BUFFER( ptr, &undoCount, sizeof(undoCount) );
-       COPY_TO_BUFFER( ptr, &redoCount, sizeof(redoCount) );
-       
-       if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
-       {
-               CMLog( @"sendUndoRedoStatus: failed" );
-       }
-       
-       free( buffer );
+       // create a new child
+       child = [[ServerChild alloc] initWithSocket:newSocket delegate:self];
+       [_children addObject:child];
+       [child release];
 }
 
-- (void)sendAppLaunched:(NSDictionary *)appInfo
+- (void)socketDidDisconnect:(MySocket *)mySocket
 {
-       PacketHeader    header;
-
-       char                    *buffer, *ptr;
-
-       int                             length = 0;
-       int                             lengthAfter;
-
-       u_int32_t               pid = [[appInfo objectForKey:@"NSApplicationProcessIdentifier"] unsignedLongValue];
-       NSString                *name = [appInfo objectForKey:@"NSApplicationName"];
-
-       //        PID                 NAME
-       length += sizeof(u_int32_t) + [name length] + 1;
-
-       header.checksum = RandomChecksum();
-       header.function = 21;
-       header.size = length;
-
-       length += sizeof(header);
-       //        HEADER
-
-       if ( (buffer = (char *)malloc( length ))==NULL )
-       {
-               CMLog( @"sendAppLaunched: failed" );
-
-               return;
-       }
-
-       ptr = buffer;
-
-       COPY_TO_BUFFER( ptr, &header, sizeof(header) );
-       COPY_TO_BUFFER( ptr, &pid, sizeof(pid) );
-       COPY_TO_BUFFER( ptr, [name lossyCString], [name length] + 1 );
-
-       lengthAfter = length;
-
-       if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
-       {
-               CMLog( @"sendAppLaunched: failed" );
-       }
-
-       free( buffer );
+       ChazLog( @"CheatServer - MySocket disconnected: %p", mySocket );
+       [self _performDelegateSelector:@selector(serverDisconnectedUnexpectedly:)];
 }
 
 
-- (void)sendAppQuit:(NSDictionary *)appInfo
-{
-       PacketHeader    header;
-
-       char                    *buffer, *ptr;
-
-       int                             length = 0;
-       int                             lengthAfter;
-
-       u_int32_t               pid = [[appInfo objectForKey:@"NSApplicationProcessIdentifier"] unsignedLongValue];
-
-       //        PID
-       length += sizeof(pid);
-
-       header.checksum = RandomChecksum();
-       header.function = 22;
-       header.size = length;
-
-       length += sizeof(header);
-       //        HEADER
-
-       if ( (buffer = (char *)malloc( length ))==NULL )
-       {
-               CMLog( @"sendAppQuit: failed" );
-
-               return;
-       }
-
-       ptr = buffer;
-
-       COPY_TO_BUFFER( ptr, &header, sizeof(header) );
-       COPY_TO_BUFFER( ptr, &pid, sizeof(pid) );
-
-       lengthAfter = length;
-
-       if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
-       {
-               CMLog( @"sendAppQuit: failed" );
-       }
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark NetService Delegate
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-       free( buffer );
-}
 
-- (void)sendTargetAppQuit
+- (void)netServiceWillPublish:(NSNetService *)sender
 {
-       PacketHeader    header;
-       int                             length = sizeof(header);
-
-       header.checksum = RandomChecksum();
-       header.function = 23;
-       header.size = 0;
-
-       if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
-       {
-               CMLog( @"sendTargetAppQuit failed" );
-       }
+       ChazLog( @"service will publish" );
+       //[sender resolve];
 }
 
-- (void)sendPauseFinished:(BOOL)paused
+- (void)netService:(NSNetService *)sender didNotPublish:(NSDictionary *)errorDict
 {
-       PacketHeader    header;
-
-       char                    *buffer, *ptr;
-
-       //                       PAUSED
-       int                             length = sizeof(paused);
-       int                             lengthAfter;
-
-       header.checksum = RandomChecksum();
-       header.function = 24;
-       header.size = length;
-
-       length += sizeof(header);
-       //        HEADER
-
-       if ( (buffer = (char *)malloc( length ))==NULL )
-       {
-               CMLog( @"sendPauseFinished: failed" );
-
-               return;
-       }
-
-       ptr = buffer;
-
-       COPY_TO_BUFFER( ptr, &header, sizeof(header) );
-       COPY_TO_BUFFER( ptr, &paused, sizeof(paused) );
-
-       lengthAfter = length;
-
-       if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
-       {
-               CMLog( @"sendPauseFinished: failed" );
-       }
-
-       free( buffer );
+       ChazLog( @"service did not publish" );
+       // just inform the delegate and let it decide what to do 
+       [self _performDelegateSelector:@selector(server:failedToBroadcastName:) withObject:[sender name]];
 }
 
-
-- (void)handleClearSearch
+- (void)netServiceDidStop:(NSNetService *)sender
 {
-       [searchResults removeAllObjects];
-       [searchResultsUndone removeAllObjects];
-       
-       [self unpause];
+       ChazLog( @"service stopped" );
+       [sender release];
 }
 
-- (void)handleSearch:(char const *)data size:(int)dataSize
-{
-       TCtype                  type;
-       TCsize                  size;
-       
-       char                    *ptr = (char *)data;
-
-       [self setAction:@"Searching"];
-
-       COPY_FROM_BUFFER( &type, ptr, sizeof(type) );
-       COPY_FROM_BUFFER( &size, ptr, sizeof(size) );
-       
-       // receive the amount of results to return
-       COPY_FROM_BUFFER( &searchResultsAmountDisplayed, ptr, sizeof(searchResultsAmountDisplayed) );
 
-       if ( ![searchResults lastObject] )
-       {
-               switch ( type )
-               {
-                       case TYPE_STRING:
-                       {
-                               switch ( size )
-                               {
-                                       case SIZE_8_BIT:
-                                       {
-                                               [self firstSearchString8bit:ptr size:(dataSize - (ptr - data) - 1)];
-                                       }
-                                               break;
-                               }
-                       }
-                               break;
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark Delegate Methods
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-                       case TYPE_INTEGER:
-                       {
-                               switch ( size )
-                               {
-                                       case SIZE_8_BIT:
-                                       {
-                                               int8_t                  value;
 
-                                               COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
-                                               [self firstSearchIntegerChar:value];
-                                       }
-                                               break;
-
-                                       case SIZE_16_BIT:
-                                       {
-                                               int16_t                 value;
-
-                                               COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
-                                               [self firstSearchIntegerShort:value];
-                                       }
-                                               break;
-
-                                       case SIZE_32_BIT:
-                                       {
-                                               int32_t                 value;
-
-                                               COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
-                                               [self firstSearchIntegerLong:value];
-                                       }
-                                               break;
-                               }
-                       }
-                               break;
-
-                       case TYPE_DECIMAL:
-                       {
-                               switch ( size )
-                               {
-                                       case SIZE_32_BIT:
-                                       {
-                                               float                   value;
-
-                                               COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
-                                               [self firstSearchDecimalFloat:value];
-                                       }
-                                               break;
-
-                                       case SIZE_64_BIT:
-                                       {
-                                               double                  value;
-
-                                               COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
-                                               [self firstSearchDecimalDouble:value];
-                                       }
-                                               break;
-                               }
-                       }
-                               break;
-               }
-       }
-       else
-       {
-               switch ( type )
-               {
-                       case TYPE_STRING:
-                       {
-                               switch ( size )
-                               {
-                                       case SIZE_8_BIT:
-                                       {
-                                               [self searchString8bit:ptr size:(dataSize - (ptr - data))];
-                                               
-                                               break;
-                                       }
-                               }
-                       }
-                               break;
-
-                       case TYPE_INTEGER:
-                       {
-                               switch ( size )
-                               {
-                                       case SIZE_8_BIT:
-                                       {
-                                               int8_t                  value;
-
-                                               COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
-                                               [self searchIntegerChar:value];
-                                               
-                                               break;
-                                       }
-
-                                       case SIZE_16_BIT:
-                                       {
-                                               int16_t                 value;
-
-                                               COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
-                                               [self searchIntegerShort:value];
-                                               
-                                               break;
-                                       }
-
-                                       case SIZE_32_BIT:
-                                       {
-                                               int32_t                 value;
-
-                                               COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
-                                               [self searchIntegerLong:value];
-                                               
-                                               break;
-                                       }
-                               }
-                       }
-                               break;
-
-                       case TYPE_DECIMAL:
-                       {
-                               switch ( size )
-                               {
-                                       case SIZE_32_BIT:
-                                       {
-                                               float                   value;
-                                               
-                                               COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
-                                               [self searchDecimalFloat:value];
-                                       }
-                                               break;
-
-                                       case SIZE_64_BIT:
-                                       {
-                                               double                  value;
-
-                                               COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
-                                               [self searchDecimalDouble:value];
-                                       }
-                                               break;
-                               }
-                       }
-                               break;
-               }
-       }
-
-       [self sendVariableList:[(SearchResults *)[searchResults lastObject] data] amount:[[searchResults lastObject] amount]];
-       [self sendSearchFinished];
-       [self sendUndoRedoStatus];
-
-       [self setAction:nil];
-}
-
-- (void)handleChange:(char const *)data size:(int)dataSize
+- (void)_performDelegateSelector:(SEL)selector
 {
-       TCtype                  type;
-       TCsize                  size;
-       
-       TCaddress               *addresses = NULL;
-       int                             count;
-       
-       char                    *ptr = (char *)data;
-       
-       [self setAction:@"Changing"];
-       
-       // read out the type and size of the variable.
-       COPY_FROM_BUFFER( &type, ptr, sizeof(type) );
-       COPY_FROM_BUFFER( &size, ptr, sizeof(size) );
-       
-       // read the amount of addresses.
-       COPY_FROM_BUFFER( &count, ptr, sizeof(count) );
-       
-       // save the pointer to the addresses.
-       addresses = (TCaddress *)ptr;
-       ptr += TCAddressSize*count;
-       
-       switch ( type )
-       {
-               case TYPE_STRING:
-               {
-                       switch ( size )
-                       {
-                               case SIZE_8_BIT:
-                               {
-                                       [self changeString8bit:ptr size:(dataSize - (ptr - data)) addresses:addresses count:count];
-                               }
-                                       break;
-                       }
-               }
-                       break;
-                       
-               case TYPE_INTEGER:
-               {
-                       switch ( size )
-                       {
-                               case SIZE_8_BIT:
-                               {
-                                       int8_t                  value;
-                                       
-                                       COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
-                                       [self changeIntegerChar:value addresses:addresses count:count];
-                               }
-                                       break;
-                                       
-                               case SIZE_16_BIT:
-                               {
-                                       int16_t                 value;
-                                       
-                                       COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
-                                       [self changeIntegerShort:value addresses:addresses count:count];
-                               }
-                                       break;
-                                       
-                               case SIZE_32_BIT:
-                               {
-                                       int32_t                 value;
-                                       
-                                       COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
-                                       [self changeIntegerLong:value addresses:addresses count:count];
-                               }
-                                       break;
-                       }
-               }
-                       break;
-                       
-               case TYPE_DECIMAL:
-               {
-                       switch ( size )
-                       {
-                               case SIZE_32_BIT:
-                               {
-                                       float                   value;
-                                       
-                                       COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
-                                       [self changeDecimalFloat:value addresses:addresses count:count];
-                               }
-                                       break;
-                                       
-                               case SIZE_64_BIT:
-                               {
-                                       double                  value;
-                                       
-                                       COPY_FROM_BUFFER( &value, ptr, sizeof(value) );
-                                       [self changeDecimalDouble:value addresses:addresses count:count];
-                               }
-                                       break;
-                       }
-               }
-                       break;
+       if ( [_delegate respondsToSelector:selector] ) {
+               [_delegate performSelector:selector withObject:self];
        }
-       
-       [self sendChangeFinished];
-       
-       [self setAction:nil];
 }
 
-- (void)handlePauseTarget
+- (void)_performDelegateSelector:(SEL)selector withObject:(id)object
 {
-       if ( !processPaused )
-       {
-               int                     wait_status;
-               
-               NS_DURING
-               {
-                       if ( ptrace( PT_ATTACH, processID, 0, 0 ) != -1 )
-                       {
-                               if ( waitpid( processID, &wait_status, WUNTRACED ) == processID )
-                               {
-                                       if ( WIFSTOPPED(wait_status) )
-                                       {
-                                               processPaused = YES;
-                                               [self sendPauseFinished:YES];
-                                       }
-                                       else
-                                       {
-                                               CMLog( @"ERROR: process couldn't be paused" );
-                                               [self sendPauseFinished:NO];
-                                               [self sendError:@"Could not pause target because of an unknown error." fatal:NO];
-                                       }
-                               }
-                               else
-                               {
-                                       CMLog( @"ERROR: process couldn't be paused" );
-                                       [self sendPauseFinished:NO];
-                                       [self sendError:@"Could not pause target because of an unknown error." fatal:NO];
-                               }
-                       }
-                       else
-                       {
-                               CMLog( @"ERROR: process couldn't be paused" );
-                               [self sendPauseFinished:NO];
-                               
-                               switch ( errno )
-                               {
-                                       case ESRCH:
-                                               [self sendError:@"Could not pause target because there is no valid target to pause." fatal:NO];
-                                               break;
-                                               
-                                       case EINVAL:
-                                               [self sendError:@"Could not pause target because a process cannot pause itself." fatal:NO];
-                                               break;
-                                               
-                                       case EBUSY:
-                                               [self sendError:@"Could not pause target because the target is being controlled by another instance or application." fatal:NO];
-                                               break;
-                                               
-                                       case EPERM:
-                                               [self sendError:@"Could not pause target because this type of application cannot be paused." fatal:NO];
-                                               break;
-                                               
-                                       default:
-                                               [self sendError:@"Could not pause target because of an unknown error." fatal:NO];
-                                               break;
-                               }
-                       }
-               }
-               NS_HANDLER
-               {
-                       [self sendPauseFinished:NO];
-                       [self sendError:[NSString stringWithFormat:@"Could not pause target because an exception (%@) was raised: %@", [localException name], [localException reason]] fatal:NO];
-               }
-               NS_ENDHANDLER
-       }
-       else
-       {
-               ptrace( PT_DETACH, processID, 0, 0 );
-
-               processPaused = NO;
-               [self sendPauseFinished:NO];
+       if ( [_delegate respondsToSelector:selector] ) {
+               [_delegate performSelector:selector withObject:self withObject:object];
        }
 }
 
-- (void)handleUndo
-{
-       SearchResults           *results = [searchResults lastObject];
-       
-       if ( results )
-       {
-               [searchResultsUndone addObject:results];
-               [searchResults removeLastObject];
-       }
 
-       results = [searchResults lastObject];
-       if ( results )
-       {
-               [self sendVariableList:[results data] amount:[results amount]];
-       }
-       else
-       {
-               [self sendVariableList:NULL amount:0];
-       }
-       
-       [self sendUndoFinished];
-       [self sendUndoRedoStatus];
-}
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark Accessors
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-- (void)handleRedo
+- (BOOL)isListening
 {
-       SearchResults           *results = [searchResultsUndone lastObject];
-       
-       if ( results )
-       {
-               [searchResults addObject:results];
-               [searchResultsUndone removeLastObject];
-       }
-
-       results = [searchResults lastObject];
-       if ( results )
-       {
-               [self sendVariableList:[results data] amount:[results amount]];
-       }
-       else
-       {
-               [self sendVariableList:NULL amount:0];
-       }
-       
-       [self sendRedoFinished];
-       [self sendUndoRedoStatus];
+       return _socket != nil;
 }
 
-- (void)handleSetTargetPID:(char const *)data size:(int)size
+- (NSString *)host
 {
-       char                    *ptr = (char *)data;
-
-       pid_t                   pid;
-
-       COPY_FROM_BUFFER( &pid, ptr, sizeof(pid) );
-
-       [self setPID:pid];
+       return [_socket localHost];
 }
 
-
-- (void)unpause
+- (int)port
 {
-       if ( processPaused )
-       {
-               [self handlePauseTarget];
-       }
+       return _port;
 }
 
-- (void)setPID:(pid_t)pid
+- (NSString *)broadcast
 {
-       kern_return_t                           result;
-
-       [self unpause];
-       
-       processID = pid;
-
-       if ( (result = task_for_pid( current_task(), processID, &processTask)) != KERN_SUCCESS )
-       {
-               CMLog( @"task_for_pid returned error: %i", result );
-       }
+       return _name;
 }
 
-
-- (void)dealloc
+- (id)delegate
 {
-       [self unpause];
-
-       [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
-
-       [searchResults release];
-       [searchResultsUndone release];
-
-       [super dealloc];
+       return _delegate;
 }
 
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%   NSWorkspaceDidLaunchApplicationNotification Notification
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-- (void)processListChanged:(NSNotification *)note
+- (void)setDelegate:(id)delegate
 {
-       pid_t                   pid = [[[note userInfo] objectForKey:@"NSApplicationProcessIdentifier"] intValue];
-
-       if ( /*pid != getpid()*/ sockfd != -1 )
-       {
-               if ( [[note name] isEqualToString:@"NSWorkspaceDidLaunchApplicationNotification"] )
-               {
-                       [self sendAppLaunched:[note userInfo]];
-               }
-               else
-               {
-                       [self sendAppQuit:[note userInfo]];
-
-                       if ( pid == processID )
-                       {
-                               [self sendTargetAppQuit];
-
-                               // we can't set the new target here because this method is not called
-                               // in the server thread.  the client will have to change it.
-                               //[self setPID:[rootProxy serverFirstProcess]];
-                               processPaused = NO;
-                       }
-               }
-       }
+       _delegate = delegate;
 }
 
 
 @end
-
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%   Internal Functions
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-#define ASIZE 256
-int bmsearch( char *pat, int m, char *text, int n, void *base, void *loc[] )
-{
-       int count = 0;
-       int i, j, k, skip[ASIZE];
-       
-       if( m==0 ) return 0;
-       for( k=0; k<ASIZE; k++ ) skip[k] = m;
-       for( k=0; k<m-1; k++ ) skip[(int)pat[k]] = m-k-1;
-       
-       for( k=m-1; k < n; k += skip[(int)text[k] & (ASIZE-1)] ) {
-               for( j=m-1, i=k; j>=0 && text[i] == pat[j]; j-- ) i--;
-               if( j == (-1) )
-                       /* SAVE LOCATION */
-                       loc[count++] = (void *)( base+i+1 );
-                       //return( text+i+1 );
-       }
-       return count;
-}
-
-/*
-BOOL compare_float( float a, float b )
-{
-       float const             feps = 0.0001f;
-       
-       return feps > fabsf( a - b );
-}
-
-BOOL compare_double( double a, double b )
-{
-       double const    deps = 0.0000001;
-       
-       return deps > fabs( a - b );
-}*/
\ No newline at end of file
diff --git a/CheatURLCommand.h b/CheatURLCommand.h
new file mode 100644 (file)
index 0000000..146f516
--- /dev/null
@@ -0,0 +1,20 @@
+//
+//  CheatURLCommand.h
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 2/19/05.
+//  Copyright 2005 Chaz McGarvey. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+#import "ChazLog.h"
+
+#import "CheatDocument.h"
+
+
+@interface CheatURLCommand : NSScriptCommand
+{
+
+}
+
+@end
diff --git a/CheatURLCommand.m b/CheatURLCommand.m
new file mode 100644 (file)
index 0000000..3eda345
--- /dev/null
@@ -0,0 +1,30 @@
+//
+//  CheatURLCommand.m
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 2/19/05.
+//  Copyright 2005 Chaz McGarvey. All rights reserved.
+//
+
+#import "CheatURLCommand.h"
+
+
+@implementation CheatURLCommand
+
+- (id)performDefaultImplementation
+{
+       NSDocumentController    *controller = [NSDocumentController sharedDocumentController];
+       CheatDocument                   *doc = [controller makeUntitledDocumentOfType:@"Cheat Document"];
+       if ( !doc ) {
+               ChazLog( @"nil document" );
+       }
+       [doc setMode:TCSearchMode];
+       [doc setConnectOnOpen:NO];
+       [controller addDocument:doc];
+       [doc makeWindowControllers];
+       [doc showWindows];
+       [doc connectWithURL:[self directParameter]];
+       return nil;
+}
+
+@end
diff --git a/CheatURLHandler.scriptSuite b/CheatURLHandler.scriptSuite
new file mode 100644 (file)
index 0000000..b26e94c
--- /dev/null
@@ -0,0 +1,15 @@
+
+// CheatURLHandler.scriptSuite
+
+{
+       Name = CheatURLHandler;
+       AppleEventCode = "UrHD";
+       
+       Commands = {
+               "GetURL" = {
+                       CommandClass = CheatURLCommand;
+                       AppleEventCode = GURL;
+                       AppleEventClassCode = GURL;
+               };
+       };
+}
\ No newline at end of file
diff --git a/CheatURLHandler.scriptTerminology b/CheatURLHandler.scriptTerminology
new file mode 100644 (file)
index 0000000..fe6c422
--- /dev/null
@@ -0,0 +1,14 @@
+
+// CheatURLHandler.scriptTerminology
+
+{
+       Name = "CheatURLHandler";
+       Description = "Handles cheat:// URLs";
+       
+       Commands = {
+               "GetURL" = {
+                       Name = "Get URL";
+                       Description = "Launches a new cheat session with a remote server.";
+               };
+       };
+}
\ No newline at end of file
diff --git a/Cheater.h b/Cheater.h
new file mode 100644 (file)
index 0000000..883f78a
--- /dev/null
+++ b/Cheater.h
@@ -0,0 +1,147 @@
+
+// **********************************************************************
+// 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 <Cocoa/Cocoa.h>
+#import "ChazLog.h"
+
+#import "CheaterTypes.h"
+
+#import "Process.h"
+#import "Variable.h"
+
+
+// The network protocol The Cheat uses is way simple.  the header is
+// a fixed size: 24 bytes.  Immediately following the header is the
+// packet data.
+
+typedef struct _TCPacketHeader
+{
+       unsigned nifty; // always the same: 'DENT' or 0x44454E54.
+       unsigned size; // the size of the packet (excluding this header).
+       char name[16]; // NULL-terminated string describing the packet.
+} TCPacketHeader;
+
+
+// network definitions
+#define TC_NIFTY (0x44454E54)
+
+
+@interface Cheater : NSObject
+{
+       BOOL _isConnected;
+       BOOL _isAuthenticated;
+       id _delegate;
+}
+
+// #############################################################################
+#pragma mark Initialization
+// #############################################################################
+
+- (id)initWithDelegate:(id)delegate;
+
+// delegation
+- (id)delegate;
+- (void)setDelegate:(id)delegate;
+
+// accessors
+- (BOOL)isConnected;
+- (BOOL)isAuthenticated;
+- (NSString *)hostAddress;
+
+// #############################################################################
+#pragma mark Cheating Control
+// #############################################################################
+
+// Methods with AUTH require authentication.
+
+- (void)connect;
+- (void)disconnect;
+- (void)authenticateWithPassword:(NSString *)password;
+
+- (void)getProcessList;
+
+- (void)setTarget:(Process *)target;
+- (void)pauseTarget; // AUTH
+- (void)resumeTarget; // AUTH
+
+- (void)limitReturnedResults:(unsigned)limit;
+- (void)searchForVariable:(Variable *)var comparison:(TCSearchOperator)op; // AUTH
+- (void)searchLastValuesComparison:(TCSearchOperator)op; // AUTH
+- (void)cancelSearch; // AUTH
+- (void)clearSearch; // AUTH
+
+- (void)getMemoryDump; // AUTH
+- (void)cancelMemoryDump; // AUTH
+
+- (void)makeVariableChanges:(NSArray *)variables repeat:(BOOL)doRepeat interval:(NSTimeInterval)repeatInterval; // AUTH
+- (void)stopChangingVariables; // AUTH
+
+- (void)undo; // AUTH
+- (void)redo; // AUTH
+
+- (void)watchVariablesAtIndex:(unsigned)index count:(unsigned)count interval:(NSTimeInterval)checkInterval; // AUTH
+- (void)stopWatchingVariables; // AUTH
+
+@end
+
+
+// #############################################################################
+@protocol CheaterDelegate
+// #############################################################################
+
+- (void)cheaterDidConnect:(Cheater *)cheater;
+- (void)cheaterDidDisconnect:(Cheater *)cheater;
+
+- (void)cheaterRequiresAuthentication:(Cheater *)cheater;
+- (void)cheaterRejectedPassword:(Cheater *)cheater;
+- (void)cheaterAcceptedPassword:(Cheater *)cheater;
+
+- (void)cheater:(Cheater *)cheater didFindProcesses:(NSArray *)processes;
+- (void)cheater:(Cheater *)cheater didAddProcess:(Process *)process;
+- (void)cheater:(Cheater *)cheater didRemoveProcess:(Process *)process;
+
+- (void)cheater:(Cheater *)cheater didSetTarget:(Process *)target;
+- (void)cheaterPausedTarget:(Cheater *)cheater;
+- (void)cheaterResumedTarget:(Cheater *)cheater;
+
+- (void)cheater:(Cheater *)cheater didFindVariables:(TCArray)variables actualAmount:(unsigned)count;
+- (void)cheater:(Cheater *)cheater didFindValues:(TCArray)values;
+- (void)cheaterDidCancelSearch:(Cheater *)cheater;
+- (void)cheaterDidClearSearch:(Cheater *)cheater;
+
+- (void)cheater:(Cheater *)cheater didDumpMemory:(NSData *)memoryDump;
+- (void)cheaterDidCancelMemoryDump:(Cheater *)cheater;
+
+- (void)cheater:(Cheater *)cheater didChangeVariables:(unsigned)changeCount;
+- (void)cheaterDidStopChangingVariables:(Cheater *)cheater;
+
+- (void)cheater:(Cheater *)cheater didReportProgress:(int)progress;
+
+- (void)cheater:(Cheater *)cheater didRevertToVariables:(TCArray)variables actualAmount:(unsigned)count;
+
+- (void)cheaterDidUndo:(Cheater *)cheater;
+- (void)cheaterDidRedo:(Cheater *)cheater;
+
+- (void)cheater:(Cheater *)cheater variableAtIndex:(unsigned)index didChangeTo:(Variable *)variable;
+
+- (void)cheater:(Cheater *)cheater didFailLastRequest:(NSString *)reason;
+- (void)cheater:(Cheater *)cheater echo:(NSString *)message;
+
+@end
diff --git a/Cheater.m b/Cheater.m
new file mode 100644 (file)
index 0000000..8e0ca5c
--- /dev/null
+++ b/Cheater.m
@@ -0,0 +1,232 @@
+
+// **********************************************************************
+// 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 "LocalCheater.h"
+
+
+@implementation Cheater
+
+
+// #############################################################################
+#pragma mark Initialization
+// #############################################################################
+
+- (id)initWithDelegate:(id)delegate
+{
+       if ( self = [self init] ) {
+               // set the delegate
+               [self setDelegate:delegate];
+               ChazLog( @"init Cheater %p", self );
+       }
+       return self;
+}
+
+- (void)dealloc
+{
+       ChazLog( @"dealloc Cheater %p", self );
+       [super dealloc];
+}
+
+
+- (id)delegate
+{
+       return _delegate;
+}
+
+- (void)setDelegate:(id)delegate
+{
+       // make sure the delegate is not nil and that it conforms to the CheaterDelegate
+       if ( [delegate conformsToProtocol:@protocol(CheaterDelegate)] ) {
+               _delegate = delegate;
+       }
+       else {
+               _delegate = nil;
+       }
+}
+
+
+- (BOOL)isConnected
+{
+       return _isConnected;
+}
+
+- (BOOL)isAuthenticated
+{
+       return _isAuthenticated;
+}
+
+- (NSString *)hostAddress
+{
+       return @"";
+}
+
+
+// #############################################################################
+#pragma mark Cheating Control
+// #############################################################################
+
+- (void)connect
+{
+       [NSException raise:@"TCNotImplemented" format:@"The subclass of Cheater (%@) needs to implement selector %@.",
+               NSStringFromClass(isa),
+               NSStringFromSelector(_cmd)];
+}
+
+- (void)disconnect
+{
+       [NSException raise:@"TCNotImplemented" format:@"The subclass of Cheater (%@) needs to implement selector %@.",
+               NSStringFromClass(isa),
+               NSStringFromSelector(_cmd)];
+}
+
+- (void)authenticateWithPassword:(NSString *)password
+{
+       [NSException raise:@"TCNotImplemented" format:@"The subclass of Cheater (%@) needs to implement selector %@.",
+               NSStringFromClass(isa),
+               NSStringFromSelector(_cmd)];
+}
+
+
+- (void)getProcessList
+{
+       [NSException raise:@"TCNotImplemented" format:@"The subclass of Cheater (%@) needs to implement selector %@.",
+               NSStringFromClass(isa),
+               NSStringFromSelector(_cmd)];
+}
+
+
+- (void)setTarget:(Process *)target
+{
+       [NSException raise:@"TCNotImplemented" format:@"The subclass of Cheater (%@) needs to implement selector %@.",
+               NSStringFromClass(isa),
+               NSStringFromSelector(_cmd)];
+}
+
+- (void)pauseTarget
+{
+       [NSException raise:@"TCNotImplemented" format:@"The subclass of Cheater (%@) needs to implement selector %@.",
+               NSStringFromClass(isa),
+               NSStringFromSelector(_cmd)];
+}
+
+- (void)resumeTarget
+{
+       [NSException raise:@"TCNotImplemented" format:@"The subclass of Cheater (%@) needs to implement selector %@.",
+               NSStringFromClass(isa),
+               NSStringFromSelector(_cmd)];
+}
+
+
+- (void)limitReturnedResults:(unsigned)limit
+{
+       [NSException raise:@"TCNotImplemented" format:@"The subclass of Cheater (%@) needs to implement selector %@.",
+               NSStringFromClass(isa),
+               NSStringFromSelector(_cmd)];
+}
+
+- (void)searchForVariable:(Variable *)data comparison:(TCSearchOperator)op
+{
+       [NSException raise:@"TCNotImplemented" format:@"The subclass of Cheater (%@) needs to implement selector %@.",
+               NSStringFromClass(isa),
+               NSStringFromSelector(_cmd)];
+}
+
+- (void)searchLastValuesComparison:(TCSearchOperator)op
+{
+       [NSException raise:@"TCNotImplemented" format:@"The subclass of Cheater (%@) needs to implement selector %@.",
+               NSStringFromClass(isa),
+               NSStringFromSelector(_cmd)];
+}
+
+- (void)cancelSearch
+{
+       [NSException raise:@"TCNotImplemented" format:@"The subclass of Cheater (%@) needs to implement selector %@.",
+               NSStringFromClass(isa),
+               NSStringFromSelector(_cmd)];
+}
+
+- (void)clearSearch
+{
+       [NSException raise:@"TCNotImplemented" format:@"The subclass of Cheater (%@) needs to implement selector %@.",
+               NSStringFromClass(isa),
+               NSStringFromSelector(_cmd)];
+}
+
+- (void)getMemoryDump
+{
+       [NSException raise:@"TCNotImplemented" format:@"The subclass of Cheater (%@) needs to implement selector %@.",
+               NSStringFromClass(isa),
+               NSStringFromSelector(_cmd)];
+}
+
+- (void)cancelMemoryDump
+{
+       [NSException raise:@"TCNotImplemented" format:@"The subclass of Cheater (%@) needs to implement selector %@.",
+               NSStringFromClass(isa),
+               NSStringFromSelector(_cmd)];
+}
+
+
+- (void)makeVariableChanges:(NSArray *)variables repeat:(BOOL)doRepeat interval:(NSTimeInterval)repeatInterval
+{
+       [NSException raise:@"TCNotImplemented" format:@"The subclass of Cheater (%@) needs to implement selector %@.",
+               NSStringFromClass(isa),
+               NSStringFromSelector(_cmd)];
+}
+
+- (void)stopChangingVariables
+{
+       [NSException raise:@"TCNotImplemented" format:@"The subclass of Cheater (%@) needs to implement selector %@.",
+               NSStringFromClass(isa),
+               NSStringFromSelector(_cmd)];
+}
+
+
+- (void)undo
+{
+       [NSException raise:@"TCNotImplemented" format:@"The subclass of Cheater (%@) needs to implement selector %@.",
+               NSStringFromClass(isa),
+               NSStringFromSelector(_cmd)];
+}
+
+- (void)redo
+{
+       [NSException raise:@"TCNotImplemented" format:@"The subclass of Cheater (%@) needs to implement selector %@.",
+               NSStringFromClass(isa),
+               NSStringFromSelector(_cmd)];
+}
+
+
+- (void)watchVariablesAtIndex:(unsigned)index count:(unsigned)count interval:(NSTimeInterval)checkInterval
+{
+       [NSException raise:@"TCNotImplemented" format:@"The subclass of Cheater (%@) needs to implement selector %@.",
+               NSStringFromClass(isa),
+               NSStringFromSelector(_cmd)];
+}
+
+- (void)stopWatchingVariables
+{
+       [NSException raise:@"TCNotImplemented" format:@"The subclass of Cheater (%@) needs to implement selector %@.",
+               NSStringFromClass(isa),
+               NSStringFromSelector(_cmd)];
+}
+
+
+@end
diff --git a/CheaterTypes.h b/CheaterTypes.h
new file mode 100644 (file)
index 0000000..cc16e25
--- /dev/null
@@ -0,0 +1,170 @@
+//
+//  CheaterTypes.h
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 12/23/04.
+//  Copyright 2004 Chaz McGarvey. All rights reserved.
+//
+
+#ifndef _CheaterTypes_H
+#define _CheaterTypes_H
+
+#import <Cocoa/Cocoa.h>
+
+#include <mach/vm_types.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+
+/* Compiler macros */
+#if defined( __cplusplus )
+#define CHEAT_EXPORT extern "C"
+#define CHEAT_IMPORT extern "C"
+#else
+#define CHEAT_EXPORT extern
+#define CHEAT_IMPORT extern
+#endif
+
+#if !defined( CHEAT_STATIC_INLINE )
+#define CHEAT_STATIC_INLINE static __inline__
+#endif
+
+#if !defined( CHEAT_EXTERN_INLINE )
+#define CHEAT_EXTERN_INLINE extern __inline__
+#endif
+
+
+#pragma mark -
+#pragma mark Miscellaneous Types
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+typedef vm_address_t TCAddress;
+
+
+typedef unsigned char TCVariableType;
+enum {
+       TCInt64 = 0,
+       TCInt32 = 1, // default
+       TCInt16 = 2,
+       TCInt8 = 3,
+       TCString = 4,
+       TCFloat = 5,
+       TCDouble = 6
+};
+
+typedef unsigned char TCIntegerSign;
+enum {
+       TCSigned = 0, // default
+       TCUnsigned = 1
+};
+
+typedef unsigned char TCSearchOperator;
+enum {
+       TCEqual = 0, // default
+       TCNotEqual = 1,
+       TCLessThan = 2,
+       TCGreaterThan = 3,
+       TCLessThanOrEqual = 4, // not used
+       TCGreaterThanOrEqual = 5 // not used
+};
+
+typedef unsigned char TCSearchType;
+enum {
+       TCGivenValue = 0, // default
+       TCLastValue = 1
+};
+
+
+#pragma mark -
+#pragma mark TCArray
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+typedef struct _TCArray
+{
+       void *_bytes;
+       unsigned _count;
+       unsigned _size;
+       BOOL _ownsBytes;
+} *TCArray;
+
+
+#pragma mark -
+#pragma mark Exported Array Functions
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+CHEAT_EXPORT TCArray TCMakeArray( unsigned count, unsigned size );
+CHEAT_EXPORT TCArray TCMakeArrayWithBytes( unsigned count, unsigned size, void *bytes );
+CHEAT_EXPORT void TCReleaseArray( TCArray array );
+
+CHEAT_EXPORT void TCArrayAppendArray( TCArray array, TCArray other );
+
+CHEAT_EXPORT NSString *TCStringFromArray( TCArray array );
+
+
+#pragma mark -
+#pragma mark Imported Array Functions
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+CHEAT_STATIC_INLINE void *TCArrayBytes( TCArray array )
+{
+       return array->_bytes;
+}
+
+CHEAT_STATIC_INLINE unsigned TCArrayElementCount( TCArray array )
+{
+       return array->_count;
+}
+
+CHEAT_STATIC_INLINE unsigned TCArrayElementSize( TCArray array )
+{
+       return array->_size;
+}
+
+CHEAT_STATIC_INLINE void const *TCArrayElementAtIndex( TCArray array, unsigned index )
+{
+       return array->_bytes + index * array->_size;
+}
+
+CHEAT_STATIC_INLINE void TCArraySetElementAtIndex( TCArray array, unsigned index, void const *element )
+{
+       memcpy( array->_bytes + index * array->_size, element, array->_size );
+}
+
+CHEAT_STATIC_INLINE void TCArrayResize( TCArray array, unsigned count )
+{
+       void *bytes = realloc( array->_bytes, count * array->_size );
+       
+       if ( bytes ) {
+               array->_bytes = bytes;
+               array->_count = count;
+       }
+}
+
+CHEAT_STATIC_INLINE TCArray TCArrayCopyElements( TCArray array, unsigned count )
+{
+       return TCMakeArrayWithBytes( MIN(array->_count,count), array->_size, array->_bytes );
+}
+
+CHEAT_STATIC_INLINE TCArray TCArrayCopy( TCArray array )
+{
+       return TCArrayCopyElements( array, array->_count );
+}
+
+CHEAT_STATIC_INLINE TCArray TCArrayCopyContainer( TCArray array, unsigned count )
+{
+       TCArray copy = TCMakeArray( MIN(array->_count,count), array->_size );
+       copy->_bytes = array->_bytes;
+       copy->_ownsBytes = NO;
+       return copy;
+}
+
+CHEAT_STATIC_INLINE void TCArrayFill( TCArray array, int filler )
+{
+       memset( array->_bytes, filler, array->_count * array->_size );
+}
+
+
+
+#endif /* _CheaterTypes_H */
+
diff --git a/CheaterTypes.m b/CheaterTypes.m
new file mode 100644 (file)
index 0000000..d1acfed
--- /dev/null
@@ -0,0 +1,72 @@
+//
+//  CheaterTypes.m
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 12/29/04.
+//  Copyright 2004 Chaz McGarvey. All rights reserved.
+//
+
+#import "CheaterTypes.h"
+
+
+TCArray TCMakeArray( unsigned count, unsigned size )
+{
+       TCArray array = (TCArray)malloc( sizeof(struct _TCArray) );
+       
+       if ( array ) {
+               array->_bytes = malloc( count * size );
+               
+               if ( array->_bytes ) {
+                       array->_count = count;
+                       array->_size = size;
+                       array->_ownsBytes = YES;
+               }
+               else {
+                       free( array );
+                       return NULL;
+               }
+       }
+       return array;
+}
+
+TCArray TCMakeArrayWithBytes( unsigned count, unsigned size, void *bytes )
+{
+       TCArray array = TCMakeArray( count, size );
+       
+       if ( array && bytes ) {
+               memcpy( array->_bytes, bytes, count * size );
+       }
+       return array;
+}
+
+void TCReleaseArray( TCArray array )
+{
+       if ( array && array->_ownsBytes ) {
+               free( array->_bytes );
+               free( array );
+       }
+}
+
+
+void TCArrayAppendArray( TCArray array, TCArray other )
+{
+       unsigned oldCount = array->_count;
+       unsigned count = oldCount + other->_count;
+       
+       if ( array->_size != other->_size ) {
+               return;
+       }
+       
+       TCArrayResize( array, count );
+       if ( array->_count == count ) {
+               memcpy( array->_bytes + oldCount * array->_size, other->_bytes, other->_count * other->_size );
+       }
+}
+
+
+NSString *TCStringFromArray( TCArray array )
+{
+       return [NSString stringWithFormat:@"{%p,%u,%u}", array->_bytes, array->_count, array->_size];
+}
+
+
diff --git a/ClientDelegate.h b/ClientDelegate.h
deleted file mode 100644 (file)
index 6c5dc79..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      ClientDelegate.h
-// Created:   Wed Sep 24 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#import <Cocoa/Cocoa.h>
-
-
-@protocol ClientDelegate
-
-- (void)clientConnectedWithSocket:(int)sock name:(NSString *)name;
-- (void)clientDisconnected;
-- (void)clientError:(NSString *)error message:(NSString *)message;
-
-@end
\ No newline at end of file
diff --git a/Conversions.h b/Conversions.h
new file mode 100644 (file)
index 0000000..e2b599d
--- /dev/null
@@ -0,0 +1,61 @@
+
+// **********************************************************************
+// The Cheat - A universal game cheater for Mac OS X
+// (C) 2003-2004 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 <Cocoa/Cocoa.h>
+
+#import "Variable.h"
+
+#ifndef _Conversions_h_
+#define _Conversions_h_
+
+
+#pragma mark Prototypes
+
+/* STRING -> VALUE */
+// return YES for a successful conversion
+BOOL StringToInt64( NSString *string, SInt64 *value );
+BOOL StringToInt32( NSString *string, SInt32 *value );
+BOOL StringToInt16( NSString *string, SInt16 *value );
+BOOL StringToInt8( NSString *string, SInt8 *value );
+
+BOOL StringToUInt64( NSString *string, UInt64 *value );
+BOOL StringToUInt32( NSString *string, UInt32 *value );
+BOOL StringToUInt16( NSString *string, UInt16 *value );
+BOOL StringToUInt8( NSString *string, UInt8 *value );
+
+// general case:
+BOOL StringToValue( NSString *string, void *value, TCVariableType type );
+
+/* VALUE -> STRING */
+NSString *Int64ToString( SInt64 value );
+NSString *Int32ToString( SInt32 value );
+NSString *Int16ToString( SInt16 value );
+NSString *Int8ToString( SInt8 value );
+
+NSString *UInt64ToString( UInt64 value );
+NSString *UInt32ToString( UInt32 value );
+NSString *UInt16ToString( UInt16 value );
+NSString *UInt8ToString( UInt8 value );
+
+// general case:
+NSString *ValueToString( void *value, TCVariableType type );
+
+
+#endif /* _Conversions_h_ */
\ No newline at end of file
diff --git a/Conversions.m b/Conversions.m
new file mode 100644 (file)
index 0000000..cf6a54c
--- /dev/null
@@ -0,0 +1,442 @@
+
+// **********************************************************************
+// The Cheat - A universal game cheater for Mac OS X
+// (C) 2003-2004 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 "Conversions.h"
+
+
+BOOL StringToInt32( NSString *string, SInt32 *value )
+{
+       SInt32 integer = 0;
+       int place = 1;
+       unichar characters[16];
+       int i, stringlen;
+       BOOL hasReadNumbers = NO, doneReading = NO;
+       
+       // fart around with the string
+       string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+       stringlen = [string length];
+       if ( stringlen == 0 || stringlen >= 16 ) {
+               // the string has the wrong size to be processed further
+               return NO;
+       }
+       // read the string
+       [string getCharacters:characters];
+       
+       // parse the string backwards
+       for ( i = stringlen-1; i >= 0; i-- ) {
+               // if we're done reading but still in the loop, there's a problem
+               if ( doneReading ) {
+                       return NO;
+               }
+               if ( characters[i] >= 0x30 && characters[i] <= 0x39 ) {
+                       // the character is a number, update our value
+                       integer += (characters[i]-48) * place;
+                       place *= 10;
+                       hasReadNumbers = YES;
+               }
+               else if ( characters[i] == 0x2C /*comma*/ ) {
+                       // ignore these characters
+               }
+               else if ( hasReadNumbers ) {
+                       // check for plus or minus signs
+                       if ( characters[i] == 0x2D ) {
+                               integer = -integer;
+                               doneReading = YES;
+                       }
+                       else if ( characters[i] == 0x2B ) {
+                               doneReading = YES;
+                       }
+                       else {
+                               return NO;
+                       }
+               }
+               else {
+                       // the character is invalid, abort
+                       return NO;
+               }
+       }
+       
+       // success, return the value
+       *value = integer;
+       return YES;
+}
+
+BOOL StringToInt16( NSString *string, SInt16 *value )
+{
+       SInt16 integer = 0;
+       int place = 1;
+       unichar characters[16];
+       int i, stringlen;
+       BOOL hasReadNumbers = NO, doneReading = NO;
+       
+       string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+       stringlen = [string length];
+       if ( stringlen == 0 || stringlen >= 16 ) {
+               return NO;
+       }
+       [string getCharacters:characters];
+       
+       for ( i = stringlen-1; i >= 0; i-- ) {
+               if ( doneReading ) {
+                       return NO;
+               }
+               if ( characters[i] >= 0x30 && characters[i] <= 0x39 ) {
+                       integer += (characters[i]-48) * place;
+                       place *= 10;
+                       hasReadNumbers = YES;
+               }
+               else if ( characters[i] == 0x2C /*comma*/ ) {
+               }
+               else if ( hasReadNumbers ) {
+                       if ( characters[i] == 0x2D ) {
+                               integer = -integer;
+                               doneReading = YES;
+                       }
+                       else if ( characters[i] == 0x2B ) {
+                               doneReading = YES;
+                       }
+                       else {
+                               return NO;
+                       }
+               }
+               else {
+                       return NO;
+               }
+       }
+       
+       *value = integer;
+       return YES;
+}
+
+BOOL StringToInt8( NSString *string, SInt8 *value )
+{
+       SInt8 integer = 0;
+       int place = 1;
+       unichar characters[16];
+       int i, stringlen;
+       BOOL hasReadNumbers = NO, doneReading = NO;
+       
+       string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+       stringlen = [string length];
+       if ( stringlen == 0 || stringlen >= 16 ) {
+               return NO;
+       }
+       [string getCharacters:characters];
+       
+       for ( i = stringlen-1; i >= 0; i-- ) {
+               if ( doneReading ) {
+                       return NO;
+               }
+               if ( characters[i] >= 0x30 && characters[i] <= 0x39 ) {
+                       integer += (characters[i]-48) * place;
+                       place *= 10;
+                       hasReadNumbers = YES;
+               }
+               else if ( characters[i] == 0x2C /*comma*/ ) {
+               }
+               else if ( hasReadNumbers ) {
+                       if ( characters[i] == 0x2D ) {
+                               integer = -integer;
+                               doneReading = YES;
+                       }
+                       else if ( characters[i] == 0x2B ) {
+                               doneReading = YES;
+                       }
+                       else {
+                               return NO;
+                       }
+               }
+               else {
+                       return NO;
+               }
+       }
+       
+       *value = integer;
+       return YES;
+}
+
+
+BOOL StringToUInt32( NSString *string, UInt32 *value )
+{
+       UInt32 integer = 0;
+       int place = 1;
+       unichar characters[16];
+       int i, stringlen;
+       BOOL hasReadNumbers = NO, doneReading = NO;
+       
+       string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+       stringlen = [string length];
+       if ( stringlen == 0 || stringlen >= 16 ) {
+               return NO;
+       }
+       [string getCharacters:characters];
+       
+       for ( i = stringlen-1; i >= 0; i-- ) {
+               if ( doneReading ) {
+                       return NO;
+               }
+               if ( characters[i] >= 0x30 && characters[i] <= 0x39 ) {
+                       integer += (characters[i]-48) * place;
+                       place *= 10;
+                       hasReadNumbers = YES;
+               }
+               else if ( characters[i] == 0x2C /*comma*/ ) {
+               }
+               else if ( hasReadNumbers ) {
+                       if ( characters[i] == 0x2D ) {
+                               integer = -integer;
+                               doneReading = YES;
+                       }
+                       else if ( characters[i] == 0x2B ) {
+                               doneReading = YES;
+                       }
+                       else {
+                               return NO;
+                       }
+               }
+               else {
+                       return NO;
+               }
+       }
+       
+       *value = integer;
+       return YES;
+}
+
+BOOL StringToUInt16( NSString *string, UInt16 *value )
+{
+       UInt16 integer = 0;
+       int place = 1;
+       unichar characters[16];
+       int i, stringlen;
+       BOOL hasReadNumbers = NO, doneReading = NO;
+       
+       string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+       stringlen = [string length];
+       if ( stringlen == 0 || stringlen >= 16 ) {
+               return NO;
+       }
+       [string getCharacters:characters];
+       
+       for ( i = stringlen-1; i >= 0; i-- ) {
+               if ( doneReading ) {
+                       return NO;
+               }
+               if ( characters[i] >= 0x30 && characters[i] <= 0x39 ) {
+                       integer += (characters[i]-48) * place;
+                       place *= 10;
+                       hasReadNumbers = YES;
+               }
+               else if ( characters[i] == 0x2C /*comma*/ ) {
+               }
+               else if ( hasReadNumbers ) {
+                       if ( characters[i] == 0x2D ) {
+                               integer = -integer;
+                               doneReading = YES;
+                       }
+                       else if ( characters[i] == 0x2B ) {
+                               doneReading = YES;
+                       }
+                       else {
+                               return NO;
+                       }
+               }
+               else {
+                       return NO;
+               }
+       }
+       
+       *value = integer;
+       return YES;
+}
+
+BOOL StringToUInt8( NSString *string, UInt8 *value )
+{
+       UInt8 integer = 0;
+       int place = 1;
+       unichar characters[16];
+       int i, stringlen;
+       BOOL hasReadNumbers = NO, doneReading = NO;
+       
+       string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+       stringlen = [string length];
+       if ( stringlen == 0 || stringlen >= 16 ) {
+               return NO;
+       }
+       [string getCharacters:characters];
+       
+       for ( i = stringlen-1; i >= 0; i-- ) {
+               if ( doneReading ) {
+                       return NO;
+               }
+               if ( characters[i] >= 0x30 && characters[i] <= 0x39 ) {
+                       integer += (characters[i]-48) * place;
+                       place *= 10;
+                       hasReadNumbers = YES;
+               }
+               else if ( characters[i] == 0x2C /*comma*/ ) {
+               }
+               else if ( hasReadNumbers ) {
+                       if ( characters[i] == 0x2D ) {
+                               integer = -integer;
+                               doneReading = YES;
+                       }
+                       else if ( characters[i] == 0x2B ) {
+                               doneReading = YES;
+                       }
+                       else {
+                               return NO;
+                       }
+               }
+               else {
+                       return NO;
+               }
+       }
+       
+       *value = integer;
+       return YES;
+}
+
+
+BOOL StringToFloat( NSString *string, float *value )
+{
+       float decimal;
+       int stringlen;
+       
+       stringlen = [string length];
+       if ( stringlen == 0 ) {
+               return NO;
+       }
+       
+       decimal = [string floatValue];
+       
+       *value = decimal;
+       return YES;
+}
+
+BOOL StringToDouble( NSString *string, double *value )
+{
+       double decimal;
+       int stringlen;
+       
+       stringlen = [string length];
+       if ( stringlen == 0 ) {
+               return NO;
+       }
+       
+       decimal = [string doubleValue];
+       
+       *value = decimal;
+       return YES;
+}
+
+
+// general case:
+BOOL StringToValue( NSString *string, void *value, VariableType type )
+{
+       switch ( type ) {
+               case Integer64Type:
+                       return StringToInt64( string, value );
+               case Integer32Type:
+                       return StringToInt32( string, value );
+               case Integer16Type:
+                       return StringToInt16( string, value );
+               case Integer08Type:
+                       return StringToInt8( string, value );
+               case UInteger64Type:
+                       return StringToUInt64( string, value );
+               case UInteger32Type:
+                       return StringToUInt32( string, value );
+               case UInteger16Type:
+                       return StringToUInt16( string, value );
+               case UInteger08Type:
+                       return StringToUInt8( string, value );
+       }
+       return NO;
+}
+
+
+NSString *Int32ToString( SInt32 value )
+{
+       return [NSString stringWithFormat:@"%i", value];
+}
+
+NSString *Int16ToString( SInt16 value )
+{
+       return [NSString stringWithFormat:@"%i", value];
+}
+
+NSString *Int8ToString( SInt8 value )
+{
+       return [NSString stringWithFormat:@"%i", value];
+}
+
+
+NSString *UInt32ToString( UInt32 value )
+{
+       return [NSString stringWithFormat:@"%u", value];
+}
+
+NSString *UInt16ToString( UInt16 value )
+{
+       return [NSString stringWithFormat:@"%u", value];
+}
+
+NSString *UInt8ToString( UInt8 value )
+{
+       return [NSString stringWithFormat:@"%u", value];
+}
+
+
+NSString *FloatToString( float value )
+{
+       return [NSString stringWithFormat:@"%f", value];
+}
+
+NSString *DoubleToString( double value )
+{
+       return [NSString stringWithFormat:@"%f", value];
+}
+
+// general case:
+NSString *ValueToString( void *value, VariableType type )
+{
+       switch ( type ) {
+               case Integer64Type:
+                       return Int64ToString( *(SInt64 *)value );
+               case Integer32Type:
+                       return Int32ToString( *(SInt32 *)value );
+               case Integer16Type:
+                       return Int16ToString( *(SInt16 *)value );
+               case Integer08Type:
+                       return Int8ToString( *(SInt8 *)value );
+               case UInteger64Type:
+                       return UInt64ToString( *(UInt64 *)value );
+               case UInteger32Type:
+                       return UInt32ToString( *(UInt32 *)value );
+               case UInteger16Type:
+                       return UInt16ToString( *(UInt16 *)value );
+               case UInteger08Type:
+                       return UInt8ToString( *(UInt8 *)value );
+       }
+       return NO;
+}
+
+
diff --git a/DocCheaterDelegate.m b/DocCheaterDelegate.m
new file mode 100644 (file)
index 0000000..2673ae6
--- /dev/null
@@ -0,0 +1,444 @@
+//
+//  DocCheaterDelegate.m
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 12/26/04.
+//  Copyright 2004 Chaz McGarvey. All rights reserved.
+//
+
+#import "CheatDocument.h"
+
+
+@implementation CheatDocument ( DocCheaterDelegate )
+
+
+- (void)cheaterDidConnect:(Cheater *)cheater
+{
+       ChazLog( @"cheaterDidConnect:" );
+       [ibStatusText setDefaultStatus:[self defaultStatusString]];
+       // update the interface
+       [self updateInterface];
+}
+
+- (void)cheaterDidDisconnect:(Cheater *)cheater
+{
+       ChazLog( @"cheaterDidDisonnect:" );
+       [self disconnectFromCheater];
+       // update status
+       [self showError:@"Disconnected by server."];
+       [ibStatusBar setIndeterminate:NO];
+       [ibStatusBar setDoubleValue:0.0];
+       [ibStatusBar stopAnimation:self];
+       // update the interface
+       [self updateInterface];
+}
+
+
+- (void)cheaterRequiresAuthentication:(Cheater *)cheater
+{
+       ChazLog( @"cheaterRequiresAuthentication:" );
+       
+       [self ibRunPasswordSheet:nil];
+}
+
+- (void)cheaterRejectedPassword:(Cheater *)cheater
+{
+       ChazLog( @"cheaterRejectedPassword" );
+       
+       
+}
+
+- (void)cheaterAcceptedPassword:(Cheater *)cheater
+{
+       ChazLog( @"cheaterAcceptedPassword" );
+       
+       [ibStatusText setTemporaryStatus:@"Password Accepted"];
+}
+
+
+- (void)cheater:(Cheater *)cheater didFindProcesses:(NSArray *)processes
+{
+       NSMenu *processMenu;
+       NSMenuItem *menuItem;
+       
+       unsigned i, len;
+       
+       Process *selectThis = nil;
+       
+       ChazLog( @"cheater:didFindProcesses:" );
+       
+       // create and set the server popup menu
+       processMenu = [[NSMenu alloc] init];
+       [processMenu setAutoenablesItems:YES];
+
+       // add menu items
+       // processes returned
+       len = [processes count];
+       for ( i = 0; i < len; i++ ) {
+               Process *item = [processes objectAtIndex:i];
+               
+               menuItem = [[NSMenuItem alloc] init];
+               [menuItem setTarget:self];
+               [menuItem setAction:@selector(ibSetProcess:)];
+               [menuItem setTitle:[item name]];
+               [menuItem setImage:[item icon]];
+               [menuItem setRepresentedObject:item];
+               [processMenu addItem:menuItem];
+               [menuItem release];
+               
+               // check and see if our document uses this application
+               if ( [self isLoadedFromFile] && [[_cheatData process] sameApplicationAs:item] ) {
+                       selectThis = item;
+               }
+       }
+       // set the menu
+       [ibProcessPopup setMenu:processMenu];
+       [processMenu release];
+       
+       // if we're loaded from a file, select the process matching
+       // the one saved, if it is launched.
+       if ( selectThis ) {
+               [_cheater setTarget:selectThis];
+       }
+       // otherwise, select the global target
+       else if ( selectThis = [CheatDocument globalTarget] ) {
+               ChazLog( @"setting global target" );
+               [_cheater setTarget:selectThis];
+       }
+       // otherwise, select the first process in this list
+       else if ( len > 0 ) {
+               [_cheater setTarget:[processes objectAtIndex:0]];
+       }
+}
+
+- (void)cheater:(Cheater *)cheater didAddProcess:(Process *)process
+{
+       NSMenu *processMenu = [ibProcessPopup menu];
+       NSMenuItem *menuItem;
+       
+       Process *savedTarget = [_cheatData process];
+       
+       // add the newly found process to the process popup
+       menuItem = [[NSMenuItem alloc] init];
+       [menuItem setTarget:self];
+       [menuItem setAction:@selector(ibSetProcess:)];
+       [menuItem setTitle:[process name]];
+       [menuItem setImage:[process icon]];
+       [menuItem setRepresentedObject:process];
+       [processMenu addItem:menuItem];
+       [menuItem release];
+       
+       // make this the target if appropiate
+       if ( _status == TCIdleStatus &&
+                ![_searchData hasSearchedOnce] &&
+                [savedTarget sameApplicationAs:process] &&
+                ![savedTarget sameApplicationAs:_process] ) {
+               [_cheater setTarget:process];
+       }
+}
+
+- (void)cheater:(Cheater *)cheater didRemoveProcess:(Process *)process
+{
+       NSMenu *processes = [ibProcessPopup menu];
+       // remove the service from the menu
+       [processes removeItemWithRepresentedObject:process];
+       
+       // if this is the current process, select the first one
+       if ( [_process isEqual:process] ) {
+               [_process release];
+               _process = nil;
+               
+               if ( [processes numberOfItems] > 0 ) {
+                       [_cheater setTarget:[[processes itemAtIndex:0] representedObject]];
+               }
+       }
+}
+
+
+- (void)cheater:(Cheater *)cheater didSetTarget:(Process *)target
+{
+       ChazLog( @"cheater:setTarget:" );
+       
+       // save a reference to the process
+       [_process release];
+       _process = [target retain];
+       
+       [CheatDocument setGlobalTarget:_process];
+       
+       // make sure the correct item is selected
+       [ibProcessPopup selectItemAtIndex:[ibProcessPopup indexOfItemWithRepresentedObject:target]];
+       //[ibProcessPopup selectItemWithTitle:[target name]];
+       
+       // apply the name and version to the document if the doc isn't saved
+       if ( ![self isLoadedFromFile] ) {
+               [_cheatData setProcess:target];
+       }
+       
+       [ibStatusText setTemporaryStatus:[NSString stringWithFormat:@"Target is %@.", [target name]] duration:2.0];
+       [self updateInterface];
+}
+
+- (void)cheaterPausedTarget:(Cheater *)cheater
+{
+       _isTargetPaused = YES;
+       [ibStatusText setTemporaryStatus:@"Target Paused"];
+}
+
+- (void)cheaterResumedTarget:(Cheater *)cheater
+{
+       _isTargetPaused = NO;
+       [ibStatusText setTemporaryStatus:@"Target Resumed"];
+}
+
+
+- (void)cheater:(Cheater *)cheater didFindVariables:(TCArray)variables actualAmount:(unsigned)count
+{
+       if ( _status == TCSearchingStatus ) {
+               _status = TCIdleStatus;
+               
+               // do something with the variables
+               [_searchData setAddresses:variables];
+               [_searchData didAddResults];
+               [ibSearchVariableTable reloadData];
+               
+               [self setActualResults:count];
+               
+               [ibStatusText setDefaultStatus:[self defaultStatusString]];
+               if ( count == 1 ) {
+                       NSColor *green = [NSColor colorWithCalibratedRed:0.0 green:0.7 blue:0.0 alpha:1.0];
+                       [ibStatusText setTemporaryStatus:[NSString stringWithFormat:@"Search found one result.", count] color:green duration:6.0];
+               }
+               else if ( count == 0 ) {
+                       NSColor *red = [NSColor colorWithCalibratedRed:0.7 green:0.0 blue:0.0 alpha:1.0];
+                       [ibStatusText setTemporaryStatus:[NSString stringWithFormat:@"Search found no results.", count] color:red duration:6.0];
+               }
+               else {
+                       [ibStatusText setTemporaryStatus:[NSString stringWithFormat:@"Search found %i results.", count] duration:6.0];
+               }
+               [ibStatusBar setIndeterminate:NO];
+               [ibStatusBar setDoubleValue:0.0];
+               [ibStatusBar stopAnimation:self];
+               
+               [self updateInterface];
+               if ( _mode == TCSearchMode ) {
+                       [ibWindow makeFirstResponder:ibSearchValueField];
+               }
+       }
+}
+
+- (void)cheater:(Cheater *)cheater didFindValues:(TCArray)values
+{
+       [_searchData setValues:values];
+       [ibSearchVariableTable reloadData];
+       
+       [self watchVariables];
+}
+
+- (void)cheaterDidCancelSearch:(Cheater *)cheater
+{
+       ChazLog( @"cheaterDidCancelSearch:" );
+       
+       if ( _isCancelingTask ) {
+               _status = TCIdleStatus;
+               _isCancelingTask = NO;
+               
+               [ibStatusText setDefaultStatus:[self defaultStatusString]];
+               [ibStatusText setTemporaryStatus:@"Search cancelled." duration:2.0];
+               [ibStatusBar setIndeterminate:NO];
+               [ibStatusBar setDoubleValue:0.0];
+               [ibStatusBar stopAnimation:self];
+               
+               [self updateInterface];
+               if ( _mode == TCSearchMode ) {
+                       [ibWindow makeFirstResponder:ibSearchValueField];
+               }
+       }
+}
+
+- (void)cheaterDidClearSearch:(Cheater *)cheater
+{
+       [_searchData clearResults];
+       [ibSearchVariableTable reloadData];
+       
+       [self setActualResults:0];
+       
+       [ibStatusText setTemporaryStatus:@"The search was cleared." duration:2.0];
+       [self updateInterface];
+}
+
+
+- (void)cheater:(Cheater *)cheater didDumpMemory:(NSData *)memoryDump
+{
+       NSSavePanel *panel;
+       
+       ChazLog( @"cheater:didDumpMemory:" );
+       
+       ChazLog( @"status: %i", _status );
+       if ( _status == TCDumpingStatus ) {
+               _status = TCIdleStatus;
+               
+               panel = [NSSavePanel savePanel];
+               [panel setRequiredFileType:@"dump"];
+               [panel setExtensionHidden:NO];
+               [panel setCanSelectHiddenExtension:YES];
+               if ( MacOSXVersion() >= 0x1030 ) {
+                       [panel setMessage:@"Dump files are huge!  Exercise patience while saving."];
+               }
+               
+               [panel beginSheetForDirectory:nil
+                                                                file:[NSString stringWithFormat:[NSString stringWithFormat:@"%@.dump", [_process name]]]
+                                          modalForWindow:ibWindow
+                                               modalDelegate:self
+                                          didEndSelector:@selector(saveMemoryDumpDidEnd:returnCode:contextInfo:)
+                                                 contextInfo:memoryDump];
+               [memoryDump retain];
+       }
+}
+
+- (void)saveMemoryDumpDidEnd:(NSSavePanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
+{
+       NSData *dump = (NSData *)contextInfo;
+       
+       [ibStatusText setDefaultStatus:[self defaultStatusString]];
+       
+       if ( returnCode == NSOKButton ) {
+               // write the file
+               [dump writeToFile:[sheet filename] atomically:YES];
+               
+               [ibStatusText setTemporaryStatus:[NSString stringWithFormat:@"Successfully dumped %@'s memory.", [_process name]]];
+       }
+       else {
+               [ibStatusText setTemporaryStatus:@"Dumping memory cancelled."];
+       }
+       
+       [dump release];
+       
+       [ibStatusBar stopAnimation:self];
+       [ibStatusBar setIndeterminate:NO];
+       
+       [self updateInterface];
+       if ( _mode == TCSearchMode ) {
+               [ibWindow makeFirstResponder:ibSearchValueField];
+       }
+}
+
+- (void)cheaterDidCancelMemoryDump:(Cheater *)cheater
+{
+       ChazLog( @"cheaterDidCancelMemoryDump:" );
+       
+       if ( _isCancelingTask ) {
+               _status = TCIdleStatus;
+               _isCancelingTask = NO;
+               
+               [ibStatusText setDefaultStatus:[self defaultStatusString]];
+               [ibStatusText setTemporaryStatus:@"Dumping memory cancelled."];
+               [ibStatusBar stopAnimation:self];
+               [ibStatusBar setIndeterminate:NO];
+               
+               [self updateInterface];
+               if ( _mode == TCSearchMode ) {
+                       [ibWindow makeFirstResponder:ibSearchValueField];
+               }
+       }
+}
+
+
+- (void)cheater:(Cheater *)cheater didChangeVariables:(unsigned)changeCount
+{
+       ChazLog( @"CHEATER changed %u variables.", changeCount );
+       if ( ![_cheatData repeats] ) {
+               _status = TCIdleStatus;
+       }
+       
+       if ( changeCount == 0 ) {
+               [ibStatusText setTemporaryStatus:@"No variables were changed." duration:2.0];
+       }
+       else if ( changeCount == 1 ) {
+               [ibStatusText setTemporaryStatus:@"Changed one variable." duration:2.0];
+       }
+       else {
+               [ibStatusText setTemporaryStatus:[NSString stringWithFormat:@"Changed %i variables.", changeCount] duration:2.0];
+       }
+       
+       [self updateInterface];
+}
+
+- (void)cheaterDidStopChangingVariables:(Cheater *)cheater
+{
+       _status = TCIdleStatus;
+       _isCancelingTask = NO;
+       
+       [ibStatusText setDefaultStatus:[self defaultStatusString]];
+       [ibStatusBar stopAnimation:self];
+       [ibStatusBar setIndeterminate:NO];
+       
+       [self updateInterface];
+       if ( _mode == TCSearchMode ) {
+               [ibWindow makeFirstResponder:ibSearchValueField];
+       }
+}
+
+
+- (void)cheater:(Cheater *)cheater didReportProgress:(int)progress
+{
+       if ( _status == TCSearchingStatus && !_isCancelingTask ) {
+               [ibStatusBar setDoubleValue:(double)progress];
+       }
+}
+
+
+- (void)cheater:(Cheater *)cheater didRevertToVariables:(TCArray)variables actualAmount:(unsigned)count
+{
+       // do something with the variables
+       [_searchData setAddresses:variables];
+       [ibSearchVariableTable reloadData];
+       
+       [self setActualResults:count];
+       
+       [self updateInterface];
+}
+
+
+- (void)cheaterDidUndo:(Cheater *)cheater
+{
+       [_searchData didUndo];
+       
+       [ibStatusText setTemporaryStatus:@"Reverted to previous results." duration:2.0];
+}
+
+- (void)cheaterDidRedo:(Cheater *)cheater
+{
+       [_searchData didRedo];
+       
+       [ibStatusText setTemporaryStatus:@"Reverted to saved results." duration:2.0];
+}
+
+
+- (void)cheater:(Cheater *)cheater variableAtIndex:(unsigned)index didChangeTo:(Variable *)variable
+{
+       [_searchData setValue:variable atIndex:index];
+       [ibSearchVariableTable reloadData];
+}
+
+
+- (void)cheater:(Cheater *)cheater didFailLastRequest:(NSString *)reason
+{
+       _status = TCIdleStatus;
+       
+       // echo the reason to the status
+       [self showError:reason];
+       [ibStatusBar setIndeterminate:NO];
+       [ibStatusBar setDoubleValue:0.0];
+       [ibStatusBar stopAnimation:self];
+       
+       [self updateInterface];
+}
+
+- (void)cheater:(Cheater *)cheater echo:(NSString *)message
+{
+       // echo the message to the status
+       [ibStatusText setTemporaryStatus:message duration:7.0];
+}
+
+
+@end
diff --git a/DocInterfaceActions.m b/DocInterfaceActions.m
new file mode 100644 (file)
index 0000000..f53ddf3
--- /dev/null
@@ -0,0 +1,611 @@
+//
+//  DocumentActions.m
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 12/26/04.
+//  Copyright 2004 Chaz McGarvey. All rights reserved.
+//
+
+#import "CheatDocument.h"
+
+
+@interface CheatDocument (DocumentActionsPrivateAPI )
+
+- (void)_confirmTargetChange:(NSWindow *)sheet returnCode:(int)returnCode context:(void *)contextInfo;
+
+@end
+
+
+@implementation CheatDocument ( DocumentActions )
+
+
+- (IBAction)ibSetLocalCheater:(id)sender
+{
+       ChazLog( @"Selected %@", sender );
+       
+       // if this is the current server, don't reconnect
+       if ( ![self shouldConnectWithServer:sender] ) {
+               return;
+       }
+       
+       // disconnect and prepare to reconnect
+       [self disconnectFromCheater];
+       [self connectWithServer:sender];
+       
+       // create new local cheater
+       _cheater = [[LocalCheater alloc] initWithDelegate:self];
+       [(LocalCheater *)_cheater setShouldCopy:YES];
+       
+       // send initial messages
+       [_cheater connect];
+       [_cheater getProcessList];
+       
+       // send preferences to the cheater
+       [_cheater limitReturnedResults:[[NSUserDefaults standardUserDefaults] integerForKey:TCHitsDisplayedPref]];
+       
+       [ibStatusText setDefaultStatus:[self defaultStatusString]];
+}
+
+- (IBAction)ibSetRemoteCheater:(id)sender
+{
+       ChazLog( @"Selected %@", sender );
+       
+       if ( ![self shouldConnectWithServer:sender] ) {
+               return;
+       }
+       
+       ChazLog( @"resolving rendezvous service..." );
+       
+       _resolvingService = [[sender representedObject] retain];
+       [_resolvingService setDelegate:self];
+       [_resolvingService resolve];
+}
+
+- (void)netServiceDidResolveAddress:(NSNetService *)sender
+{
+       NSArray *addresses;
+       
+       ChazLog( @"service resolved!" );
+       
+       // stop resolving
+       [sender stop];
+       
+       if ( sender != _resolvingService ) {
+               return;
+       }
+       
+       [self disconnectFromCheater];
+       [self connectWithServer:(NSMenuItem *)[ibServerPopup itemAtIndex:[ibServerPopup indexOfItemWithRepresentedObject:_resolvingService]]];
+       
+       addresses = [_resolvingService addresses];
+       
+       _resolvingService = nil;
+       
+       // create new remote cheater
+       ChazLog( @"found %i addresses", [addresses count] );
+       _cheater = [[RemoteCheater alloc] initWithDelegate:self];
+       [(RemoteCheater *)_cheater connectToHostWithData:[addresses objectAtIndex:0]];
+       
+       // send initial messages
+       [_cheater connect];
+       [_cheater getProcessList];
+       
+       // send preferences to the cheater
+       [_cheater limitReturnedResults:[[NSUserDefaults standardUserDefaults] integerForKey:TCHitsDisplayedPref]];
+       
+       [ibStatusText setDefaultStatus:[self defaultStatusString]];
+       [self updateInterface];
+}
+
+- (void)netService:(NSNetService *)sender didNotResolve:(NSDictionary *)errorDict
+{
+       [sender stop];
+       
+       if ( sender != _resolvingService ) {
+               return;
+       }
+       
+       _resolvingService = nil;
+       
+       NSBeginInformationalAlertSheet( @"The Cheat can't find the server.", @"OK", nil, nil, ibWindow, self, NULL, NULL, NULL,
+                                                                       @"The Cheat can't connect to the server \"%@\" because it can't be found.", [sender name] );
+}
+
+- (void)netServiceDidStop:(NSNetService *)sender
+{
+       [sender release];
+}
+
+- (IBAction)ibSetCustomCheater:(id)sender
+{
+       RemoteCheater *cheater;
+       ChazLog( @"Selected %@", [sender description] );
+       
+       if ( ![self shouldConnectWithServer:sender] ) {
+               return;
+       }
+       
+       cheater = [[RemoteCheater alloc] initWithDelegate:self];
+       if ( ![(RemoteCheater *)cheater connectToHostWithData:[sender representedObject]] ) {
+               NSBeginInformationalAlertSheet( @"The Cheat can't find the server.", @"OK", nil, nil, ibWindow, self, NULL, NULL, NULL,
+                                                                               @"The Cheat can't connect to \"%@\" because there is no server at that address.", [sender title] );
+               [cheater release];
+               [self selectConnectedCheater];
+               return;
+       }
+       
+       [self disconnectFromCheater];
+       [self connectWithServer:sender];
+       
+       _cheater = cheater;
+       
+       // send initial messages
+       [_cheater connect];
+       [_cheater getProcessList];
+       
+       // send preferences to the cheater
+       [_cheater limitReturnedResults:[[NSUserDefaults standardUserDefaults] integerForKey:TCHitsDisplayedPref]];
+       
+       [ibStatusText setDefaultStatus:[self defaultStatusString]];
+       [self updateInterface];
+}
+
+- (IBAction)ibSetNoCheater:(id)sender
+{
+       [self disconnectFromCheater];
+       
+       // nil server object
+       [_serverObject release];
+       _serverObject = nil;
+       
+       [ibStatusText setDefaultStatus:[self defaultStatusString]];
+       [self updateInterface];
+}
+
+- (IBAction)ibSetProcess:(id)sender
+{
+       if ( [_process isEqual:(Process *)[sender representedObject]] ) {
+               // this process is already selected, do nothing
+               return;
+       }
+       
+       if ( [_searchData hasSearchedOnce] ) {
+               NSBeginInformationalAlertSheet( @"Confirm target change.", @"OK", @"Cancel", nil, ibWindow, self, NULL,
+                                                                               @selector(_confirmTargetChange:returnCode:context:), [[sender representedObject] retain],
+                                                                               @"If you change the target now, your search will be cleared.  This cannot be undone.  Continue?" );
+       }
+       else {
+               // request the change
+               [_cheater setTarget:(Process *)[sender representedObject]];
+       }
+}
+
+- (void)_confirmTargetChange:(NSWindow *)sheet returnCode:(int)returnCode context:(void *)contextInfo
+{
+       NSMenu *processMenu = [ibProcessPopup menu];
+       Process *process = (Process *)contextInfo;
+       
+       if ( returnCode == NSAlertDefaultReturn ) {
+               // clear the search
+               [self ibClearSearch:nil];
+               // request the change
+               [_cheater setTarget:process];
+       }
+       else {
+               // select the correct server menuitem
+               [ibProcessPopup selectItemAtIndex:[processMenu indexOfItemWithRepresentedObject:_process]];
+       }
+       
+       [process release];
+}
+
+
+- (IBAction)ibSetVariableType:(id)sender
+{
+       [_searchData setVariableType:[sender tag]];
+       [self updateInterface];
+}
+
+- (IBAction)ibSetIntegerSign:(id)sender
+{
+       [_searchData setIntegerSign:[[sender selectedCell] tag]];
+}
+
+- (IBAction)ibSetOperator:(id)sender
+{
+       [_searchData setSearchOperator:[sender tag]];
+}
+
+- (IBAction)ibSetValueUsed:(id)sender
+{
+       [_searchData setValueUsed:[[sender selectedCell] tag]];
+       [self updateInterface];
+}
+
+- (IBAction)ibClearSearch:(id)sender
+{
+       [_cheater clearSearch];
+}
+
+- (IBAction)ibSearch:(id)sender
+{
+       Variable *variable;
+
+       // do the search
+       if ( [_searchData valueUsed] == TCGivenValue ) {
+               variable = [[Variable alloc] initWithType:[_searchData variableType] integerSign:[_searchData integerSign]];
+               [variable setStringValue:[ibSearchValueField stringValue]];
+               if ( [variable isValueValid] && [variable valueSize] > 0 ) {
+                       _status = TCSearchingStatus;
+                       [ibStatusText setDefaultStatus:[NSString stringWithFormat:@"Searching %@'s memory%C", [_process name], 0x2026]];
+                       [ibStatusBar setIndeterminate:NO];
+                       
+                       [_searchData setSearchValue:variable];
+                       [variable release];
+                       [_cheater searchForVariable:[_searchData searchValue] comparison:[_searchData searchOperator]];
+               }
+               else {
+                       NSBeginAlertSheet( @"Invalid Input", @"OK", nil, nil, ibWindow, nil, NULL, NULL, NULL,
+                                                          @"The search value \"%@\" cannot be used with this type of search.", [ibSearchValueField stringValue] );
+               }
+       }
+       else {
+               _status = TCSearchingStatus;
+               [ibStatusText setDefaultStatus:[NSString stringWithFormat:@"Searching %@'s memory%C", [_process name], 0x2026]];
+               [ibStatusBar setIndeterminate:NO];
+               
+               [_cheater searchLastValuesComparison:[_searchData searchOperator]];
+       }
+       
+       [self updateInterface];
+}
+
+- (IBAction)ibAddSearchVariable:(id)sender
+{
+       NSArray *rows;
+       int i, top;
+       
+       // don't do anything if there is nothing selected
+       if ( [ibSearchVariableTable selectedRow] == -1 ) {
+               return;
+       }
+       
+       rows = [ibSearchVariableTable selectedRows];
+       top = [rows count];
+       for ( i = 0; i < top; i++ ) {
+               int rowIndex = [[rows objectAtIndex:i] unsignedIntValue];
+               // transfer the search variable to the cheat data
+               [_cheatData addVariable:[_searchData variableAtIndex:rowIndex]];
+       }
+       
+       // update the variable table
+       [ibCheatVariableTable reloadData];
+
+       if ( [[NSUserDefaults standardUserDefaults] boolForKey:TCSwitchVariablesPref] ) {
+               [self switchToCheatMode];
+               
+               int rowIndex = [_cheatData variableCount]-1;
+               if ( MacOSXVersion() >= 0x1030 ) {
+                       [ibCheatVariableTable selectRowIndexes:[NSIndexSet indexSetWithIndex:rowIndex] byExtendingSelection:NO];
+               }
+               else {
+                       [ibCheatVariableTable selectRow:rowIndex byExtendingSelection:NO];
+               }
+               // start editing the last added variable
+               if ( [[NSUserDefaults standardUserDefaults] boolForKey:TCAutoStartEditingVarsPref] ) {
+                       if ( top > 1 ) {
+                               // edit multiple
+                               if ( MacOSXVersion() >= 0x1030 ) {
+                                       [ibCheatVariableTable selectRowIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(rowIndex-top+1,top-1)]
+                                                                         byExtendingSelection:YES];
+                               }
+                               else {
+                                       for ( i = 1; i < top; i++ ) {
+                                               [ibCheatVariableTable selectRow:rowIndex-i byExtendingSelection:YES];
+                                       }
+                               }
+                               [ibCheatVariableTable scrollRowToVisible:rowIndex];
+                               [self ibRunEditVariablesSheet:nil];
+                       }
+                       else {
+                               // edit one
+                               [ibCheatVariableTable editColumn:[ibCheatVariableTable columnWithIdentifier:@"value"]
+                                                                                        row:rowIndex withEvent:nil select:YES];
+                       }
+               }
+       }
+       
+       // update interface
+       [self setDocumentChanged];
+       [self updateInterface];
+}
+
+
+- (IBAction)ibSetCheatRepeats:(id)sender
+{
+       [_cheatData setRepeats:[sender state]];
+       
+       // update interface
+       [self setDocumentChanged];
+       [self updateInterface];
+}
+
+- (IBAction)ibSetRepeatInterval:(id)sender
+{
+       [_cheatData setRepeatInterval:[sender doubleValue]];
+       
+       // update interface
+       [self setDocumentChanged];
+       [self updateInterface];
+}
+
+- (IBAction)ibCheat:(id)sender
+{
+       _status = TCCheatingStatus;
+       [_cheater makeVariableChanges:[_cheatData enabledVariables] repeat:[_cheatData repeats] interval:[_cheatData repeatInterval]];
+       
+       // update status description
+       if ( [_cheatData repeats] ) {
+               [ibStatusText setDefaultStatus:[NSString stringWithFormat:@"Applying cheats to %@%C", [_process name], 0x2026]];
+               [ibStatusBar setIndeterminate:YES];
+               [ibStatusBar startAnimation:self];
+               
+               [self updateInterface];
+       }
+}
+
+
+- (IBAction)ibRunPropertiesSheet:(id)sender
+{
+       // update fields
+       [ibWindowTitleField setStringValue:[_cheatData windowTitle]];
+       [ibCheatInfoField setStringValue:[_cheatData cheatInfo]];
+       
+       // display sheet
+       [NSApp beginSheet:ibPropertiesSheet modalForWindow:ibWindow modalDelegate:nil didEndSelector:NULL contextInfo:nil];     
+}
+
+- (IBAction)ibEndPropertiesSheet:(id)sender
+{
+       [ibPropertiesSheet orderOut:sender];
+       [NSApp endSheet:ibPropertiesSheet returnCode:0];
+       
+       if ( [sender tag] == 1 ) {
+               // do not update anything if nothing has changed
+               if ( [[ibWindowTitleField stringValue] isEqualToString:[_cheatData windowTitle]] &&
+                        [[ibCheatInfoField stringValue] isEqualToString:[_cheatData cheatInfo]] ) {
+                       return;
+               }
+               // update data
+               [_cheatData setWindowTitle:[ibWindowTitleField stringValue]];
+               [_cheatData setCheatInfo:[ibCheatInfoField stringValue]];
+               
+               [self setDocumentChanged];
+               [self updateInterface];
+       }
+}
+
+
+- (IBAction)ibRunPasswordSheet:(id)sender
+{
+       
+}
+
+- (IBAction)ibEndPasswordSheet:(id)sender
+{
+       
+}
+
+
+- (IBAction)ibRunCustomServerSheet:(id)sender
+{
+       // update fields
+       [ibServerField setStringValue:@""];
+       [ibPortField setStringValue:[NSString stringWithFormat:@"%i", TCDefaultListenPort]];
+       
+       // display sheet
+       [NSApp beginSheet:ibCustomServerSheet modalForWindow:ibWindow modalDelegate:nil didEndSelector:NULL contextInfo:nil];
+}
+
+- (IBAction)ibEndCustomServerSheet:(id)sender
+{
+       NSString *server = [ibServerField stringValue];
+       int port = [[ibPortField stringValue] intValue];
+       
+       ChazLog( @"ibEndCustomServerSheet: %@:%i", server, port );
+       
+       [ibCustomServerSheet orderOut:sender];
+       [NSApp endSheet:ibCustomServerSheet returnCode:0];
+       
+       if ( [sender tag] == 1 ) {
+               [self connectWithURL:[NSString stringWithFormat:@"cheat://%@:%i", server, port]];
+       }
+}
+
+
+- (IBAction)ibRunEditVariablesSheet:(id)sender
+{
+       int row = [ibCheatVariableTable selectedRow];
+       Variable *var;
+       
+       // must have selected items
+       if ( row == -1 ) {
+               return;
+       }
+       
+       var = [_cheatData variableAtIndex:row];
+       
+       // update fields
+       [ibNewValueField setStringValue:[var stringValue]];
+       [ibVariableEnableButton setState:[var isEnabled]];
+       
+       // display sheet
+       [NSApp beginSheet:ibEditVariablesSheet modalForWindow:ibWindow modalDelegate:nil didEndSelector:NULL contextInfo:nil];
+}
+
+- (IBAction)ibEndEditVariablesSheet:(id)sender
+{
+       NSString *newValue = [ibNewValueField stringValue];
+       BOOL enabled = [ibVariableEnableButton state];
+       NSArray *rows;
+       int i, top;
+       
+       [ibEditVariablesSheet orderOut:sender];
+       [NSApp endSheet:ibEditVariablesSheet returnCode:0];
+       
+       if ( [sender tag] == 0 ) {
+               return;
+       }
+       if ( [newValue isEqualToString:@""] ) {
+               newValue = nil;
+       }
+       
+       rows = [ibCheatVariableTable selectedRows];
+       top = [rows count];
+       
+       for ( i = 0; i < top; i++ ) {
+               Variable *var = [_cheatData variableAtIndex:[[rows objectAtIndex:i] unsignedIntValue]];
+               if ( newValue ) {
+                       [var setStringValue:newValue];
+               }
+               [var setEnabled:enabled];
+       }
+       
+       [ibCheatVariableTable reloadData];
+       
+       [self setDocumentChanged];
+       [self updateInterface];
+}
+
+
+- (IBAction)ibPauseTarget:(id)sender
+{
+       [_cheater pauseTarget];
+}
+
+- (IBAction)ibResumeTarget:(id)sender
+{
+       [_cheater resumeTarget];
+}
+
+
+- (IBAction)ibCancelSearch:(id)sender
+{
+       _isCancelingTask = YES;
+       [_cheater cancelSearch];
+       
+       [self updateInterface];
+}
+
+- (IBAction)ibStopCheat:(id)sender
+{
+       _isCancelingTask = YES;
+       [_cheater stopChangingVariables];
+       
+       [self updateInterface];
+}
+
+
+- (IBAction)ibDumpMemory:(id)sender
+{
+       _status = TCDumpingStatus;
+       [_cheater getMemoryDump];
+       
+       // display status
+       [ibStatusText setDefaultStatus:[NSString stringWithFormat:@"Dumping %@'s memory%C", [_process name], 0x2026]];
+       [ibStatusBar setIndeterminate:YES];
+       [ibStatusBar startAnimation:self];
+       
+       [self updateInterface];
+}
+
+- (IBAction)ibCancelDump:(id)sender
+{
+       _isCancelingTask = YES;
+       [_cheater cancelMemoryDump];
+       
+       [self updateInterface];
+}
+
+
+- (IBAction)ibAddCheatVariable:(id)sender
+{
+       ChazLog( @"ibAddCheatVariable:" );
+
+       Variable *var = [[Variable alloc] initWithType:[sender tag]];
+       // add the new variable to the doc data
+       [_cheatData addVariable:var];
+       [var release];
+       // update the variable table
+       [ibCheatVariableTable reloadData];
+       
+       if ( [[NSUserDefaults standardUserDefaults] boolForKey:TCSwitchVariablesPref] ) {
+               [self switchToCheatMode];
+               
+               int row = [_cheatData variableCount]-1;
+               if ( MacOSXVersion() >= 0x1030 ) {
+                       [ibCheatVariableTable selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
+               }
+               else {
+                       [ibCheatVariableTable selectRow:row byExtendingSelection:NO];
+               }
+               // start editing new variable
+               if ( [[NSUserDefaults standardUserDefaults] boolForKey:TCAutoStartEditingVarsPref] ) {
+                       [ibCheatVariableTable editColumn:[ibCheatVariableTable columnWithIdentifier:@"address"] row:row withEvent:nil select:YES];
+               }
+       }
+       
+       // update interface
+       [self setDocumentChanged];
+       [self updateInterface];
+}
+
+- (IBAction)ibSetVariableEnabled:(id)sender
+{
+       NSArray *rows;
+       int i, top;
+       
+       BOOL flag;
+       
+       ChazLog( @"ibSetVariableEnabled: %i", [sender selectedRow] );
+       
+       flag = [[_cheatData variableAtIndex:[ibCheatVariableTable selectedRow]] isEnabled];
+       
+       rows = [ibCheatVariableTable selectedRows];
+       top = [rows count];
+       
+       for ( i = 0; i < top; i++ ) {
+               Variable *var = [_cheatData variableAtIndex:[[rows objectAtIndex:i] unsignedIntValue]];
+               [var setEnabled:!flag];
+       }
+       
+       // update interface
+       [ibCheatVariableTable reloadData];
+       [self setDocumentChanged];
+       [self updateInterface];
+}
+
+
+- (IBAction)ibToggleSearchCheat:(id)sender
+{
+       if ( _mode == TCCheatMode ) {
+               [self switchToSearchMode];
+       }
+       else if ( _mode == TCSearchMode ) {
+               [self switchToCheatMode];
+       }
+}
+
+
+- (IBAction)ibUndo:(id)sender
+{
+       [_cheater undo];
+}
+
+- (IBAction)ibRedo:(id)sender
+{
+       [_cheater redo];
+}
+
+
+@end
diff --git a/DumpContext.h b/DumpContext.h
new file mode 100644 (file)
index 0000000..f0738f7
--- /dev/null
@@ -0,0 +1,31 @@
+//
+//  DumpContext.h
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 12/6/04.
+//  Copyright 2004 Chaz McGarvey. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+
+#import "VMRegion.h"
+
+
+@interface DumpContext : NSObject
+{
+       // for fast access while iterating through the task loop.
+       @public;
+       
+       pid_t process;
+       unsigned regionCount;
+       VMRegion lastRegion;
+       
+       NSMutableData *dump;
+}
+
+// Initialization
+
+- (id)initWithPID:(pid_t)pid;
+
+
+@end
diff --git a/DumpContext.m b/DumpContext.m
new file mode 100644 (file)
index 0000000..eb545b7
--- /dev/null
@@ -0,0 +1,33 @@
+//
+//  DumpContext.m
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 12/6/04.
+//  Copyright 2004 Chaz McGarvey. All rights reserved.
+//
+
+#import "DumpContext.h"
+
+
+@implementation DumpContext
+
+
+- (id)initWithPID:(pid_t)pid
+{
+       if ( self = [super init] ) {
+               process = pid;
+               regionCount = VMCountRegionsWithAttributes( pid, VMREGION_READABLE );
+               dump = [[NSMutableData alloc] init];
+       }
+       return self;
+}
+
+- (void)dealloc
+{
+       //[lastRegion release];
+       [dump release];
+       [super dealloc];
+}
+
+
+@end
index a36e7e581576fe1279d69d4108ea04d5ff3cba92..f9f39203c5901d3707ae19e7704e5728c4dc133b 100644 (file)
@@ -1,10 +1,15 @@
 {
     IBClasses = (
         {
-            ACTIONS = {launchEmailButton = id; launchWebsiteButton = id; }; 
+            ACTIONS = {ibEmailButton = id; ibWebsiteButton = id; }; 
             CLASS = AboutBoxController; 
             LANGUAGE = ObjC; 
-            OUTLETS = {aboutWindow = NSWindow; nameVersionText = NSTextField; }; 
+            OUTLETS = {
+                ibDateText = NSTextField; 
+                ibEmailButton = NSButton; 
+                ibNameVersionText = NSTextField; 
+                ibWebsiteButton = NSButton; 
+            }; 
             SUPERCLASS = NSWindowController; 
         }, 
         {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }
index ff50bd4e52390a1265e161bcf9746b2b42335467..4c7b4ef3e27ca23782d5a6aa2fd8c3f91f6f168b 100644 (file)
@@ -3,14 +3,35 @@
 <plist version="1.0">
 <dict>
        <key>IBDocumentLocation</key>
-       <string>85 110 356 241 0 0 1280 1002 </string>
+       <string>124 93 356 241 0 0 1280 938 </string>
        <key>IBFramework Version</key>
-       <string>349.0</string>
+       <string>364.0</string>
+       <key>IBGroupedObjects</key>
+       <dict>
+               <key>3</key>
+               <array>
+                       <string>93</string>
+                       <string>91</string>
+               </array>
+               <key>7</key>
+               <array>
+                       <string>77</string>
+                       <string>80</string>
+                       <string>87</string>
+               </array>
+               <key>8</key>
+               <array>
+                       <string>89</string>
+                       <string>81</string>
+               </array>
+       </dict>
+       <key>IBLastGroupID</key>
+       <string>9</string>
        <key>IBOpenObjects</key>
        <array>
-               <integer>5</integer>
+               <integer>85</integer>
        </array>
        <key>IBSystem Version</key>
-       <string>7D24</string>
+       <string>7U16</string>
 </dict>
 </plist>
index ebc418d81c84f9f8fc89972478e6b8233c28ca91..7ef2eec207537913e91a8f51c1832eb4c6ce0404 100644 (file)
Binary files a/English.lproj/AboutBox.nib/keyedobjects.nib and b/English.lproj/AboutBox.nib/keyedobjects.nib differ
diff --git a/English.lproj/AboutBox.nib/objects.nib b/English.lproj/AboutBox.nib/objects.nib
deleted file mode 100644 (file)
index 919dcdb..0000000
Binary files a/English.lproj/AboutBox.nib/objects.nib and /dev/null differ
index a36e7e581576fe1279d69d4108ea04d5ff3cba92..f9f39203c5901d3707ae19e7704e5728c4dc133b 100644 (file)
@@ -1,10 +1,15 @@
 {
     IBClasses = (
         {
-            ACTIONS = {launchEmailButton = id; launchWebsiteButton = id; }; 
+            ACTIONS = {ibEmailButton = id; ibWebsiteButton = id; }; 
             CLASS = AboutBoxController; 
             LANGUAGE = ObjC; 
-            OUTLETS = {aboutWindow = NSWindow; nameVersionText = NSTextField; }; 
+            OUTLETS = {
+                ibDateText = NSTextField; 
+                ibEmailButton = NSButton; 
+                ibNameVersionText = NSTextField; 
+                ibWebsiteButton = NSButton; 
+            }; 
             SUPERCLASS = NSWindowController; 
         }, 
         {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }
index ff50bd4e52390a1265e161bcf9746b2b42335467..4c7b4ef3e27ca23782d5a6aa2fd8c3f91f6f168b 100644 (file)
@@ -3,14 +3,35 @@
 <plist version="1.0">
 <dict>
        <key>IBDocumentLocation</key>
-       <string>85 110 356 241 0 0 1280 1002 </string>
+       <string>124 93 356 241 0 0 1280 938 </string>
        <key>IBFramework Version</key>
-       <string>349.0</string>
+       <string>364.0</string>
+       <key>IBGroupedObjects</key>
+       <dict>
+               <key>3</key>
+               <array>
+                       <string>93</string>
+                       <string>91</string>
+               </array>
+               <key>7</key>
+               <array>
+                       <string>77</string>
+                       <string>80</string>
+                       <string>87</string>
+               </array>
+               <key>8</key>
+               <array>
+                       <string>89</string>
+                       <string>81</string>
+               </array>
+       </dict>
+       <key>IBLastGroupID</key>
+       <string>9</string>
        <key>IBOpenObjects</key>
        <array>
-               <integer>5</integer>
+               <integer>85</integer>
        </array>
        <key>IBSystem Version</key>
-       <string>7D24</string>
+       <string>7U16</string>
 </dict>
 </plist>
index 784ed8cc3ff21d245bdbc1bde7895404f97afc91..e795ad6164647738e6a70917214e5c007c62fb3b 100644 (file)
Binary files a/English.lproj/AboutBox~.nib/keyedobjects.nib and b/English.lproj/AboutBox~.nib/keyedobjects.nib differ
diff --git a/English.lproj/AboutBox~.nib/objects.nib b/English.lproj/AboutBox~.nib/objects.nib
deleted file mode 100644 (file)
index a5eb031..0000000
Binary files a/English.lproj/AboutBox~.nib/objects.nib and /dev/null differ
diff --git a/English.lproj/CheatDocument.nib/classes.nib b/English.lproj/CheatDocument.nib/classes.nib
new file mode 100644 (file)
index 0000000..25bc4d7
--- /dev/null
@@ -0,0 +1,97 @@
+{
+    IBClasses = (
+        {
+            ACTIONS = {copy = id; cut = id; delete = id; paste = id; }; 
+            CLASS = BetterTableView; 
+            LANGUAGE = ObjC; 
+            SUPERCLASS = NSTableView; 
+        }, 
+        {
+            ACTIONS = {
+                ibAddCheatVariable = id; 
+                ibAddSearchVariable = id; 
+                ibCancelDump = id; 
+                ibCancelSearch = id; 
+                ibCheat = id; 
+                ibClearSearch = id; 
+                ibDumpMemory = id; 
+                ibEndCustomServerSheet = id; 
+                ibEndEditVariablesSheet = id; 
+                ibEndPasswordSheet = id; 
+                ibEndPropertiesSheet = id; 
+                ibPauseTarget = id; 
+                ibRedo = id; 
+                ibResumeTarget = id; 
+                ibRunCustomServerSheet = id; 
+                ibRunEditVariablesSheet = id; 
+                ibRunPasswordSheet = id; 
+                ibRunPropertiesSheet = id; 
+                ibSearch = id; 
+                ibSetCheatRepeats = id; 
+                ibSetCustomCheater = id; 
+                ibSetIntegerSign = id; 
+                ibSetLocalCheater = id; 
+                ibSetNoCheater = id; 
+                ibSetOperator = id; 
+                ibSetProcess = id; 
+                ibSetRemoteCheater = id; 
+                ibSetRepeatInterval = id; 
+                ibSetValueUsed = id; 
+                ibSetVariableEnabled = id; 
+                ibSetVariableType = id; 
+                ibStopCheat = id; 
+                ibToggleSearchCheat = id; 
+                ibUndo = id; 
+            }; 
+            CLASS = CheatDocument; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {
+                ibCheatButton = NSButton; 
+                ibCheatContentView = NSView; 
+                ibCheatInfoField = NSTextField; 
+                ibCheatInfoText = NSTextField; 
+                ibCheatRepeatAuxText = NSTextField; 
+                ibCheatRepeatButton = NSButton; 
+                ibCheatRepeatField = NSTextField; 
+                ibCheatVariableTable = NSTableView; 
+                ibCustomServerSheet = NSWindow; 
+                ibEditVariablesSheet = NSWindow; 
+                ibNewValueField = NSTextField; 
+                ibPasswordField = NSTextField; 
+                ibPasswordSheet = NSWindow; 
+                ibPlaceView = NSView; 
+                ibPortField = NSTextField; 
+                ibProcessPopup = NSPopUpButton; 
+                ibPropertiesSheet = NSWindow; 
+                ibSearchButton = NSButton; 
+                ibSearchClearButton = NSButton; 
+                ibSearchContentView = NSView; 
+                ibSearchIntegerSignMatrix = NSMatrix; 
+                ibSearchOperatorPopup = NSPopUpButton; 
+                ibSearchTypePopup = NSPopUpButton; 
+                ibSearchValueField = NSTextField; 
+                ibSearchValueUsedMatrix = NSMatrix; 
+                ibSearchVariableButton = NSButton; 
+                ibSearchVariableTable = VariableTable; 
+                ibServerField = NSTextField; 
+                ibServerPopup = NSPopUpButton; 
+                ibStatusBar = NSProgressIndicator; 
+                ibStatusText = StatusTextField; 
+                ibVariableEnableButton = NSButton; 
+                ibWindow = NSWindow; 
+                ibWindowTitleField = NSTextField; 
+            }; 
+            SUPERCLASS = NSDocument; 
+        }, 
+        {
+            ACTIONS = {fadeToCheatMode = id; fadeToSessionMode = id; }; 
+            CLASS = FirstResponder; 
+            LANGUAGE = ObjC; 
+            SUPERCLASS = NSObject; 
+        }, 
+        {CLASS = NSObject; LANGUAGE = ObjC; }, 
+        {CLASS = StatusTextField; LANGUAGE = ObjC; SUPERCLASS = NSTextField; }, 
+        {CLASS = VariableTable; LANGUAGE = ObjC; SUPERCLASS = BetterTableView; }
+    ); 
+    IBVersion = 1; 
+}
\ No newline at end of file
diff --git a/English.lproj/CheatDocument.nib/disc_session.tiff b/English.lproj/CheatDocument.nib/disc_session.tiff
new file mode 100644 (file)
index 0000000..136a3fe
Binary files /dev/null and b/English.lproj/CheatDocument.nib/disc_session.tiff differ
diff --git a/English.lproj/CheatDocument.nib/info.nib b/English.lproj/CheatDocument.nib/info.nib
new file mode 100644 (file)
index 0000000..a99a749
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>IBDocumentLocation</key>
+       <string>540 85 356 394 0 0 1280 938 </string>
+       <key>IBEditorPositions</key>
+       <dict>
+               <key>24</key>
+               <string>420 514 440 253 0 0 1280 938 </string>
+               <key>45</key>
+               <string>420 514 440 253 0 0 1280 938 </string>
+       </dict>
+       <key>IBFramework Version</key>
+       <string>364.0</string>
+       <key>IBOpenObjects</key>
+       <array>
+               <integer>24</integer>
+               <integer>5</integer>
+               <integer>45</integer>
+       </array>
+       <key>IBSystem Version</key>
+       <string>7U16</string>
+</dict>
+</plist>
diff --git a/English.lproj/CheatDocument.nib/keyedobjects.nib b/English.lproj/CheatDocument.nib/keyedobjects.nib
new file mode 100644 (file)
index 0000000..9d3965f
Binary files /dev/null and b/English.lproj/CheatDocument.nib/keyedobjects.nib differ
diff --git a/English.lproj/CheatDocument~.nib/classes.nib b/English.lproj/CheatDocument~.nib/classes.nib
new file mode 100644 (file)
index 0000000..25bc4d7
--- /dev/null
@@ -0,0 +1,97 @@
+{
+    IBClasses = (
+        {
+            ACTIONS = {copy = id; cut = id; delete = id; paste = id; }; 
+            CLASS = BetterTableView; 
+            LANGUAGE = ObjC; 
+            SUPERCLASS = NSTableView; 
+        }, 
+        {
+            ACTIONS = {
+                ibAddCheatVariable = id; 
+                ibAddSearchVariable = id; 
+                ibCancelDump = id; 
+                ibCancelSearch = id; 
+                ibCheat = id; 
+                ibClearSearch = id; 
+                ibDumpMemory = id; 
+                ibEndCustomServerSheet = id; 
+                ibEndEditVariablesSheet = id; 
+                ibEndPasswordSheet = id; 
+                ibEndPropertiesSheet = id; 
+                ibPauseTarget = id; 
+                ibRedo = id; 
+                ibResumeTarget = id; 
+                ibRunCustomServerSheet = id; 
+                ibRunEditVariablesSheet = id; 
+                ibRunPasswordSheet = id; 
+                ibRunPropertiesSheet = id; 
+                ibSearch = id; 
+                ibSetCheatRepeats = id; 
+                ibSetCustomCheater = id; 
+                ibSetIntegerSign = id; 
+                ibSetLocalCheater = id; 
+                ibSetNoCheater = id; 
+                ibSetOperator = id; 
+                ibSetProcess = id; 
+                ibSetRemoteCheater = id; 
+                ibSetRepeatInterval = id; 
+                ibSetValueUsed = id; 
+                ibSetVariableEnabled = id; 
+                ibSetVariableType = id; 
+                ibStopCheat = id; 
+                ibToggleSearchCheat = id; 
+                ibUndo = id; 
+            }; 
+            CLASS = CheatDocument; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {
+                ibCheatButton = NSButton; 
+                ibCheatContentView = NSView; 
+                ibCheatInfoField = NSTextField; 
+                ibCheatInfoText = NSTextField; 
+                ibCheatRepeatAuxText = NSTextField; 
+                ibCheatRepeatButton = NSButton; 
+                ibCheatRepeatField = NSTextField; 
+                ibCheatVariableTable = NSTableView; 
+                ibCustomServerSheet = NSWindow; 
+                ibEditVariablesSheet = NSWindow; 
+                ibNewValueField = NSTextField; 
+                ibPasswordField = NSTextField; 
+                ibPasswordSheet = NSWindow; 
+                ibPlaceView = NSView; 
+                ibPortField = NSTextField; 
+                ibProcessPopup = NSPopUpButton; 
+                ibPropertiesSheet = NSWindow; 
+                ibSearchButton = NSButton; 
+                ibSearchClearButton = NSButton; 
+                ibSearchContentView = NSView; 
+                ibSearchIntegerSignMatrix = NSMatrix; 
+                ibSearchOperatorPopup = NSPopUpButton; 
+                ibSearchTypePopup = NSPopUpButton; 
+                ibSearchValueField = NSTextField; 
+                ibSearchValueUsedMatrix = NSMatrix; 
+                ibSearchVariableButton = NSButton; 
+                ibSearchVariableTable = VariableTable; 
+                ibServerField = NSTextField; 
+                ibServerPopup = NSPopUpButton; 
+                ibStatusBar = NSProgressIndicator; 
+                ibStatusText = StatusTextField; 
+                ibVariableEnableButton = NSButton; 
+                ibWindow = NSWindow; 
+                ibWindowTitleField = NSTextField; 
+            }; 
+            SUPERCLASS = NSDocument; 
+        }, 
+        {
+            ACTIONS = {fadeToCheatMode = id; fadeToSessionMode = id; }; 
+            CLASS = FirstResponder; 
+            LANGUAGE = ObjC; 
+            SUPERCLASS = NSObject; 
+        }, 
+        {CLASS = NSObject; LANGUAGE = ObjC; }, 
+        {CLASS = StatusTextField; LANGUAGE = ObjC; SUPERCLASS = NSTextField; }, 
+        {CLASS = VariableTable; LANGUAGE = ObjC; SUPERCLASS = BetterTableView; }
+    ); 
+    IBVersion = 1; 
+}
\ No newline at end of file
diff --git a/English.lproj/CheatDocument~.nib/disc_session.tiff b/English.lproj/CheatDocument~.nib/disc_session.tiff
new file mode 100644 (file)
index 0000000..136a3fe
Binary files /dev/null and b/English.lproj/CheatDocument~.nib/disc_session.tiff differ
diff --git a/English.lproj/CheatDocument~.nib/info.nib b/English.lproj/CheatDocument~.nib/info.nib
new file mode 100644 (file)
index 0000000..4051914
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>IBDocumentLocation</key>
+       <string>540 85 356 394 0 0 1280 938 </string>
+       <key>IBEditorPositions</key>
+       <dict>
+               <key>24</key>
+               <string>420 514 440 253 0 0 1280 938 </string>
+               <key>45</key>
+               <string>420 514 440 253 0 0 1280 938 </string>
+       </dict>
+       <key>IBFramework Version</key>
+       <string>364.0</string>
+       <key>IBOpenObjects</key>
+       <array>
+               <integer>24</integer>
+               <integer>5</integer>
+               <integer>757</integer>
+               <integer>45</integer>
+       </array>
+       <key>IBSystem Version</key>
+       <string>7U16</string>
+</dict>
+</plist>
diff --git a/English.lproj/CheatDocument~.nib/keyedobjects.nib b/English.lproj/CheatDocument~.nib/keyedobjects.nib
new file mode 100644 (file)
index 0000000..d0d0e51
Binary files /dev/null and b/English.lproj/CheatDocument~.nib/keyedobjects.nib differ
diff --git a/English.lproj/Help.nib/classes.nib b/English.lproj/Help.nib/classes.nib
new file mode 100644 (file)
index 0000000..cd782fb
--- /dev/null
@@ -0,0 +1,12 @@
+{
+    IBClasses = (
+        {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 
+        {
+            CLASS = HelpController; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {helpWindow = NSWindow; webView = WebView; }; 
+            SUPERCLASS = NSWindowController; 
+        }
+    ); 
+    IBVersion = 1; 
+}
\ No newline at end of file
similarity index 73%
rename from English.lproj/Record.nib/info.nib
rename to English.lproj/Help.nib/info.nib
index 036e61dcb3156b2f97ef58b54dd95e3e02a50033..f188829f053602770154f3ca86e91b9e1f5fe683 100644 (file)
@@ -3,14 +3,14 @@
 <plist version="1.0">
 <dict>
        <key>IBDocumentLocation</key>
-       <string>98 99 356 240 0 0 1280 1002 </string>
+       <string>69 61 356 241 0 0 1280 1002 </string>
        <key>IBFramework Version</key>
-       <string>349.0</string>
+       <string>364.0</string>
        <key>IBOpenObjects</key>
        <array>
-               <integer>6</integer>
+               <integer>18</integer>
        </array>
        <key>IBSystem Version</key>
-       <string>7D24</string>
+       <string>7U16</string>
 </dict>
 </plist>
diff --git a/English.lproj/Help.nib/keyedobjects.nib b/English.lproj/Help.nib/keyedobjects.nib
new file mode 100644 (file)
index 0000000..4c75545
Binary files /dev/null and b/English.lproj/Help.nib/keyedobjects.nib differ
diff --git a/English.lproj/Help~.nib/classes.nib b/English.lproj/Help~.nib/classes.nib
new file mode 100644 (file)
index 0000000..cd782fb
--- /dev/null
@@ -0,0 +1,12 @@
+{
+    IBClasses = (
+        {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 
+        {
+            CLASS = HelpController; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {helpWindow = NSWindow; webView = WebView; }; 
+            SUPERCLASS = NSWindowController; 
+        }
+    ); 
+    IBVersion = 1; 
+}
\ No newline at end of file
similarity index 58%
rename from English.lproj/NetTraffic.nib/info.nib
rename to English.lproj/Help~.nib/info.nib
index 851cbfb52e7810589dbb7e22f64a72f7ac8c0370..f188829f053602770154f3ca86e91b9e1f5fe683 100644 (file)
@@ -3,20 +3,14 @@
 <plist version="1.0">
 <dict>
        <key>IBDocumentLocation</key>
-       <string>540 53 356 240 0 0 1280 1002 </string>
+       <string>69 61 356 241 0 0 1280 1002 </string>
        <key>IBFramework Version</key>
-       <string>349.0</string>
-       <key>IBLockedObjects</key>
-       <array>
-               <integer>26</integer>
-       </array>
-       <key>IBOldestOS</key>
-       <integer>2</integer>
+       <string>364.0</string>
        <key>IBOpenObjects</key>
        <array>
-               <integer>26</integer>
+               <integer>18</integer>
        </array>
        <key>IBSystem Version</key>
-       <string>7D24</string>
+       <string>7U16</string>
 </dict>
 </plist>
diff --git a/English.lproj/Help~.nib/keyedobjects.nib b/English.lproj/Help~.nib/keyedobjects.nib
new file mode 100644 (file)
index 0000000..3371e1d
Binary files /dev/null and b/English.lproj/Help~.nib/keyedobjects.nib differ
index 315ce0077e9bef73f95e933839116abdfe59b0a3..c97180b7025564f998ba2213e6a92d1442fcbcfc 100644 (file)
Binary files a/English.lproj/InfoPlist.strings and b/English.lproj/InfoPlist.strings differ
index a30170a624c862114054e8f1068df66ef029218a..73b790f1bcab61569ab90821e76e640dce881673 100644 (file)
@@ -6,9 +6,9 @@
                 launchEmailMenu = id; 
                 launchHelpFile = id; 
                 launchWebsiteMenu = id; 
-                newSessionWindow = id; 
+                newBlankCheatWindow = id; 
+                newSearchWindow = id; 
                 showAboutBoxWindow = id; 
-                showNetTrafficWindow = id; 
                 showPreferenceWindow = id; 
             }; 
             CLASS = AppController; 
             SUPERCLASS = NSApplication; 
         }, 
         {
-            ACTIONS = {redoMenu = id; undoMenu = id; }; 
+            ACTIONS = {
+                ibAddCheatVariable = id; 
+                ibCancelSearch = id; 
+                ibClearSearch = id; 
+                ibDumpMemory = id; 
+                ibPauseTarget = id; 
+                ibRedo = id; 
+                ibRunEditVariablesSheet = id; 
+                ibRunPropertiesSheet = id; 
+                ibToggleSearchCheat = id; 
+                ibUndo = id; 
+            }; 
             CLASS = FirstResponder; 
             LANGUAGE = ObjC; 
             SUPERCLASS = NSObject; 
index acd81cfb746dfef9de73030c8cc5b20b98f00dfa..f485bb8afb0d8597be811521079845a35c97b594 100644 (file)
@@ -3,19 +3,19 @@
 <plist version="1.0">
 <dict>
        <key>IBDocumentLocation</key>
-       <string>485 133 356 240 0 0 1280 1002 </string>
+       <string>485 122 356 240 0 0 1280 938 </string>
        <key>IBEditorPositions</key>
        <dict>
                <key>29</key>
-               <string>412 623 284 44 0 0 1280 1002 </string>
+               <string>179 806 349 44 0 0 1280 938 </string>
        </dict>
        <key>IBFramework Version</key>
-       <string>349.0</string>
+       <string>364.0</string>
        <key>IBOpenObjects</key>
        <array>
                <integer>29</integer>
        </array>
        <key>IBSystem Version</key>
-       <string>7D24</string>
+       <string>7U16</string>
 </dict>
 </plist>
index 9ef368ddd24ddfa373cd51278fee340cd9531237..405da549a0c4cbbd6bff1b850f49b163e9ec55fa 100644 (file)
Binary files a/English.lproj/MainMenu.nib/keyedobjects.nib and b/English.lproj/MainMenu.nib/keyedobjects.nib differ
diff --git a/English.lproj/MainMenu.nib/objects.nib b/English.lproj/MainMenu.nib/objects.nib
deleted file mode 100644 (file)
index 2d16e82..0000000
Binary files a/English.lproj/MainMenu.nib/objects.nib and /dev/null differ
index a30170a624c862114054e8f1068df66ef029218a..063d5ab9855827a94aeba487cd1010688aad14cd 100644 (file)
@@ -6,9 +6,9 @@
                 launchEmailMenu = id; 
                 launchHelpFile = id; 
                 launchWebsiteMenu = id; 
-                newSessionWindow = id; 
+                newBlankCheatWindow = id; 
+                newSearchWindow = id; 
                 showAboutBoxWindow = id; 
-                showNetTrafficWindow = id; 
                 showPreferenceWindow = id; 
             }; 
             CLASS = AppController; 
             SUPERCLASS = NSApplication; 
         }, 
         {
-            ACTIONS = {redoMenu = id; undoMenu = id; }; 
+            ACTIONS = {
+                ibAddCheatVariable = id; 
+                ibClearSearch = id; 
+                ibDumpMemory = id; 
+                ibPauseTarget = id; 
+                ibRedo = id; 
+                ibRunEditVariablesSheet = id; 
+                ibRunPropertiesSheet = id; 
+                ibToggleSearchCheat = id; 
+                ibUndo = id; 
+            }; 
             CLASS = FirstResponder; 
             LANGUAGE = ObjC; 
             SUPERCLASS = NSObject; 
index acd81cfb746dfef9de73030c8cc5b20b98f00dfa..f485bb8afb0d8597be811521079845a35c97b594 100644 (file)
@@ -3,19 +3,19 @@
 <plist version="1.0">
 <dict>
        <key>IBDocumentLocation</key>
-       <string>485 133 356 240 0 0 1280 1002 </string>
+       <string>485 122 356 240 0 0 1280 938 </string>
        <key>IBEditorPositions</key>
        <dict>
                <key>29</key>
-               <string>412 623 284 44 0 0 1280 1002 </string>
+               <string>179 806 349 44 0 0 1280 938 </string>
        </dict>
        <key>IBFramework Version</key>
-       <string>349.0</string>
+       <string>364.0</string>
        <key>IBOpenObjects</key>
        <array>
                <integer>29</integer>
        </array>
        <key>IBSystem Version</key>
-       <string>7D24</string>
+       <string>7U16</string>
 </dict>
 </plist>
index 88943c664419b30d0a8a7a52673ea3d2472b273c..314d45148c34432b72699986267dac0d97209363 100644 (file)
Binary files a/English.lproj/MainMenu~.nib/keyedobjects.nib and b/English.lproj/MainMenu~.nib/keyedobjects.nib differ
diff --git a/English.lproj/MainMenu~.nib/objects.nib b/English.lproj/MainMenu~.nib/objects.nib
deleted file mode 100644 (file)
index 7dc1307..0000000
Binary files a/English.lproj/MainMenu~.nib/objects.nib and /dev/null differ
diff --git a/English.lproj/MyDocument~.nib/classes.nib b/English.lproj/MyDocument~.nib/classes.nib
deleted file mode 100644 (file)
index e8fe7e1..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-{
-    IBClasses = (
-        {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 
-        {
-            ACTIONS = {
-                cancelButton = id; 
-                changeButton = id; 
-                clearSearchButton = id; 
-                okButton = id; 
-                pauseButton = id; 
-                processMenuItem = id; 
-                recurringChangeButton = id; 
-                redoMenu = id; 
-                searchButton = id; 
-                serverMenuDisconnect = id; 
-                serverMenuItem = id; 
-                serverMenuLocal = id; 
-                sizePopup = id; 
-                typePopup = id; 
-                undoMenu = id; 
-            }; 
-            CLASS = MyDocument; 
-            LANGUAGE = ObjC; 
-            OUTLETS = {
-                addressTable = NSTableView; 
-                cancelButton = NSButton; 
-                changeButton = NSButton; 
-                changeSecondsCombo = NSComboBox; 
-                changeSheet = NSWindow; 
-                changeTextField = NSTextField; 
-                cheatWindow = NSWindow; 
-                clearSearchButton = NSButton; 
-                decimalSizeMenu = NSMenu; 
-                descriptionText = NSTextField; 
-                integerSizeMenu = NSMenu; 
-                okButton = NSButton; 
-                pauseButton = NSButton; 
-                processMenu = NSMenu; 
-                processPopup = NSPopUpButton; 
-                recurringChangeButton = NSButton; 
-                searchButton = NSButton; 
-                searchRadioMatrix = NSMatrix; 
-                searchTextField = NSTextField; 
-                serverMenu = NSMenu; 
-                serverPopup = NSPopUpButton; 
-                sizePopup = NSPopUpButton; 
-                statusBar = NSProgressIndicator; 
-                statusText = NSTextField; 
-                stringSizeMenu = NSMenu; 
-                typeMenu = NSMenu; 
-                typePopup = NSPopUpButton; 
-            }; 
-            SUPERCLASS = NSDocument; 
-        }
-    ); 
-    IBVersion = 1; 
-}
\ No newline at end of file
diff --git a/English.lproj/MyDocument~.nib/info.nib b/English.lproj/MyDocument~.nib/info.nib
deleted file mode 100644 (file)
index de4f224..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-       <key>IBDocumentLocation</key>
-       <string>114 -132 356 406 0 0 1280 1002 </string>
-       <key>IBEditorPositions</key>
-       <dict>
-               <key>143</key>
-               <string>402 411 86 87 0 0 1280 1002 </string>
-               <key>192</key>
-               <string>272 343 101 49 0 0 1280 1002 </string>
-               <key>207</key>
-               <string>376 382 134 49 0 0 1280 1002 </string>
-               <key>400</key>
-               <string>202 287 69 87 0 0 1280 1002 </string>
-               <key>405</key>
-               <string>264 308 79 68 0 0 1280 1002 </string>
-               <key>410</key>
-               <string>509 326 69 49 0 0 1280 1002 </string>
-               <key>735</key>
-               <string>499 516 296 322 0 0 1280 1002 </string>
-       </dict>
-       <key>IBFramework Version</key>
-       <string>349.0</string>
-       <key>IBLockedObjects</key>
-       <array/>
-       <key>IBOldestOS</key>
-       <integer>2</integer>
-       <key>IBOpenObjects</key>
-       <array>
-               <integer>285</integer>
-       </array>
-       <key>IBSystem Version</key>
-       <string>7D24</string>
-</dict>
-</plist>
diff --git a/English.lproj/MyDocument~.nib/keyedobjects.nib b/English.lproj/MyDocument~.nib/keyedobjects.nib
deleted file mode 100644 (file)
index 0e00406..0000000
Binary files a/English.lproj/MyDocument~.nib/keyedobjects.nib and /dev/null differ
diff --git a/English.lproj/MyDocument~.nib/objects.nib b/English.lproj/MyDocument~.nib/objects.nib
deleted file mode 100644 (file)
index 46427e8..0000000
Binary files a/English.lproj/MyDocument~.nib/objects.nib and /dev/null differ
diff --git a/English.lproj/NetTraffic.nib/classes.nib b/English.lproj/NetTraffic.nib/classes.nib
deleted file mode 100644 (file)
index 35f6f8c..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-    IBClasses = (
-        {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 
-        {
-            ACTIONS = {killConnectionButton = id; }; 
-            CLASS = NetTrafficController; 
-            LANGUAGE = ObjC; 
-            OUTLETS = {
-                broadcastNameText = id; 
-                connectionCountText = id; 
-                delegate = id; 
-                killConnectionButton = id; 
-                listenPortText = id; 
-                netTrafficWindow = id; 
-                serverListTable = id; 
-            }; 
-            SUPERCLASS = NSWindowController; 
-        }
-    ); 
-    IBVersion = 1; 
-}
\ No newline at end of file
diff --git a/English.lproj/NetTraffic.nib/keyedobjects.nib b/English.lproj/NetTraffic.nib/keyedobjects.nib
deleted file mode 100644 (file)
index b6378b8..0000000
Binary files a/English.lproj/NetTraffic.nib/keyedobjects.nib and /dev/null differ
diff --git a/English.lproj/NetTraffic.nib/objects.nib b/English.lproj/NetTraffic.nib/objects.nib
deleted file mode 100644 (file)
index 2bebec5..0000000
Binary files a/English.lproj/NetTraffic.nib/objects.nib and /dev/null differ
diff --git a/English.lproj/NetTraffic~.nib/classes.nib b/English.lproj/NetTraffic~.nib/classes.nib
deleted file mode 100644 (file)
index 35f6f8c..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-    IBClasses = (
-        {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 
-        {
-            ACTIONS = {killConnectionButton = id; }; 
-            CLASS = NetTrafficController; 
-            LANGUAGE = ObjC; 
-            OUTLETS = {
-                broadcastNameText = id; 
-                connectionCountText = id; 
-                delegate = id; 
-                killConnectionButton = id; 
-                listenPortText = id; 
-                netTrafficWindow = id; 
-                serverListTable = id; 
-            }; 
-            SUPERCLASS = NSWindowController; 
-        }
-    ); 
-    IBVersion = 1; 
-}
\ No newline at end of file
diff --git a/English.lproj/NetTraffic~.nib/info.nib b/English.lproj/NetTraffic~.nib/info.nib
deleted file mode 100644 (file)
index 13785e2..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-       <key>IBDocumentLocation</key>
-       <string>540 53 356 240 0 0 1280 1002 </string>
-       <key>IBFramework Version</key>
-       <string>349.0</string>
-       <key>IBLockedObjects</key>
-       <array>
-               <integer>26</integer>
-       </array>
-       <key>IBOldestOS</key>
-       <integer>2</integer>
-       <key>IBOpenObjects</key>
-       <array>
-               <integer>26</integer>
-       </array>
-       <key>IBSystem Version</key>
-       <string>7C107</string>
-</dict>
-</plist>
diff --git a/English.lproj/NetTraffic~.nib/keyedobjects.nib b/English.lproj/NetTraffic~.nib/keyedobjects.nib
deleted file mode 100644 (file)
index d48ead2..0000000
Binary files a/English.lproj/NetTraffic~.nib/keyedobjects.nib and /dev/null differ
diff --git a/English.lproj/NetTraffic~.nib/objects.nib b/English.lproj/NetTraffic~.nib/objects.nib
deleted file mode 100644 (file)
index d1e1825..0000000
Binary files a/English.lproj/NetTraffic~.nib/objects.nib and /dev/null differ
index fa73c485de807d464f9a4256da53799b760c4f30..4ee476b8310a59bbd953f45f0c55afda20ddf7b5 100644 (file)
@@ -1,22 +1,65 @@
 {
     IBClasses = (
+        {
+            ACTIONS = {copy = id; cut = id; delete = id; paste = id; }; 
+            CLASS = BetterTableView; 
+            LANGUAGE = ObjC; 
+            SUPERCLASS = NSTableView; 
+        }, 
         {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 
         {
-            ACTIONS = {apply = id; cancel = id; change = id; revert = id; save = id; }; 
-            CLASS = PreferenceController; 
+            ACTIONS = {
+                ibDisplayValuesButton = id; 
+                ibSetAskForSave = id; 
+                ibSetFadeSmoothly = id; 
+                ibSetResultsDisplayed = id; 
+                ibSetValueUpdate = id; 
+                ibStartEditingVarsButton = id; 
+                ibSwitchVariablesButton = id; 
+                ibWindowOrderButton = id; 
+            }; 
+            CLASS = GeneralPrefs; 
             LANGUAGE = ObjC; 
             OUTLETS = {
-                allowRemoteButton = id; 
-                broadcastNameTextField = id; 
-                delegate = id; 
-                hitsDisplayedTextField = id; 
-                listenPortTextField = id; 
-                playSoundsButton = id; 
-                prefsWindow = id; 
-                updateAutomaticallyButton = id; 
-                windowsOnTopButton = id; 
+                ibAskForSaveButton = NSButton; 
+                ibDisplayValuesButton = NSButton; 
+                ibFadeSmoothlyButton = NSButton; 
+                ibResultsDisplayedField = NSTextField; 
+                ibStartEditingVarsButton = NSButton; 
+                ibSwitchVariablesButton = NSButton; 
+                ibValueUpdateField = NSTextField; 
+                ibWindowOrderButton = NSButton; 
             }; 
+            SUPERCLASS = NSObject; 
+        }, 
+        {CLASS = NSObject; LANGUAGE = ObjC; }, 
+        {
+            CLASS = PreferenceController; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {ibGeneralView = NSView; ibServerView = NSView; ibUpdateCheckView = NSView; }; 
             SUPERCLASS = NSWindowController; 
+        }, 
+        {
+            ACTIONS = {ibSetBroadcast = id; ibSetListenPort = id; ibStartServer = id; }; 
+            CLASS = ServerPrefs; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {
+                ibDefaultPortText = NSTextField; 
+                ibNameField = NSTextField; 
+                ibPortField = NSTextField; 
+                ibSessionTable = NSTableView; 
+                ibStartButton = NSButton; 
+                ibStatusField = StatusTextField; 
+            }; 
+            SUPERCLASS = NSObject; 
+        }, 
+        {CLASS = StatusTextField; LANGUAGE = ObjC; SUPERCLASS = NSTextField; }, 
+        {
+            ACTIONS = {ibAutoCheckButton = id; ibCheckNowButton = id; }; 
+            CLASS = UpdatePrefs; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {ibAutoCheckButton = NSButton; }; 
+            SUPERCLASS = NSObject; 
         }
     ); 
     IBVersion = 1; 
index efe0c6b76ccc9bf34c274fc8cf669ae4cb9a96db..e4f8d6743b7633329e8452be904dd192399eefbe 100644 (file)
@@ -3,18 +3,26 @@
 <plist version="1.0">
 <dict>
        <key>IBDocumentLocation</key>
-       <string>214 102 356 240 0 0 1280 1002 </string>
+       <string>370 86 431 282 0 0 1280 938 </string>
+       <key>IBEditorPositions</key>
+       <dict>
+               <key>441</key>
+               <string>330 443 476 321 0 0 1280 938 </string>
+               <key>463</key>
+               <string>402 570 476 210 0 0 1280 938 </string>
+               <key>478</key>
+               <string>288 422 476 420 0 0 1280 938 </string>
+       </dict>
        <key>IBFramework Version</key>
-       <string>349.0</string>
+       <string>364.0</string>
        <key>IBLockedObjects</key>
-       <array>
-               <integer>9</integer>
-       </array>
+       <array/>
        <key>IBOpenObjects</key>
        <array>
-               <integer>9</integer>
+               <integer>478</integer>
+               <integer>441</integer>
        </array>
        <key>IBSystem Version</key>
-       <string>7D24</string>
+       <string>7U16</string>
 </dict>
 </plist>
index 8af7affa43b0a64cc01010b52aa50d8ff90d7b48..3457cab144bcd6a8d681ca5dc5aa77d0e3ddb77f 100644 (file)
Binary files a/English.lproj/Preferences.nib/keyedobjects.nib and b/English.lproj/Preferences.nib/keyedobjects.nib differ
diff --git a/English.lproj/Preferences.nib/objects.nib b/English.lproj/Preferences.nib/objects.nib
deleted file mode 100644 (file)
index 83769ec..0000000
Binary files a/English.lproj/Preferences.nib/objects.nib and /dev/null differ
index ab06de0d1c76c0632a62d7b51b2461ee19be0c3b..4ee476b8310a59bbd953f45f0c55afda20ddf7b5 100644 (file)
@@ -1,22 +1,65 @@
 {
     IBClasses = (
+        {
+            ACTIONS = {copy = id; cut = id; delete = id; paste = id; }; 
+            CLASS = BetterTableView; 
+            LANGUAGE = ObjC; 
+            SUPERCLASS = NSTableView; 
+        }, 
         {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 
         {
-            ACTIONS = {cancel = id; change = id; revert = id; save = id; }; 
-            CLASS = PreferenceController; 
+            ACTIONS = {
+                ibDisplayValuesButton = id; 
+                ibSetAskForSave = id; 
+                ibSetFadeSmoothly = id; 
+                ibSetResultsDisplayed = id; 
+                ibSetValueUpdate = id; 
+                ibStartEditingVarsButton = id; 
+                ibSwitchVariablesButton = id; 
+                ibWindowOrderButton = id; 
+            }; 
+            CLASS = GeneralPrefs; 
             LANGUAGE = ObjC; 
             OUTLETS = {
-                allowRemoteButton = id; 
-                broadcastNameTextField = id; 
-                delegate = id; 
-                hitsDisplayedTextField = id; 
-                listenPortTextField = id; 
-                playSoundsButton = id; 
-                prefsWindow = id; 
-                updateAutomaticallyButton = id; 
-                windowsOnTopButton = id; 
+                ibAskForSaveButton = NSButton; 
+                ibDisplayValuesButton = NSButton; 
+                ibFadeSmoothlyButton = NSButton; 
+                ibResultsDisplayedField = NSTextField; 
+                ibStartEditingVarsButton = NSButton; 
+                ibSwitchVariablesButton = NSButton; 
+                ibValueUpdateField = NSTextField; 
+                ibWindowOrderButton = NSButton; 
             }; 
+            SUPERCLASS = NSObject; 
+        }, 
+        {CLASS = NSObject; LANGUAGE = ObjC; }, 
+        {
+            CLASS = PreferenceController; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {ibGeneralView = NSView; ibServerView = NSView; ibUpdateCheckView = NSView; }; 
             SUPERCLASS = NSWindowController; 
+        }, 
+        {
+            ACTIONS = {ibSetBroadcast = id; ibSetListenPort = id; ibStartServer = id; }; 
+            CLASS = ServerPrefs; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {
+                ibDefaultPortText = NSTextField; 
+                ibNameField = NSTextField; 
+                ibPortField = NSTextField; 
+                ibSessionTable = NSTableView; 
+                ibStartButton = NSButton; 
+                ibStatusField = StatusTextField; 
+            }; 
+            SUPERCLASS = NSObject; 
+        }, 
+        {CLASS = StatusTextField; LANGUAGE = ObjC; SUPERCLASS = NSTextField; }, 
+        {
+            ACTIONS = {ibAutoCheckButton = id; ibCheckNowButton = id; }; 
+            CLASS = UpdatePrefs; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {ibAutoCheckButton = NSButton; }; 
+            SUPERCLASS = NSObject; 
         }
     ); 
     IBVersion = 1; 
index efe0c6b76ccc9bf34c274fc8cf669ae4cb9a96db..e4f8d6743b7633329e8452be904dd192399eefbe 100644 (file)
@@ -3,18 +3,26 @@
 <plist version="1.0">
 <dict>
        <key>IBDocumentLocation</key>
-       <string>214 102 356 240 0 0 1280 1002 </string>
+       <string>370 86 431 282 0 0 1280 938 </string>
+       <key>IBEditorPositions</key>
+       <dict>
+               <key>441</key>
+               <string>330 443 476 321 0 0 1280 938 </string>
+               <key>463</key>
+               <string>402 570 476 210 0 0 1280 938 </string>
+               <key>478</key>
+               <string>288 422 476 420 0 0 1280 938 </string>
+       </dict>
        <key>IBFramework Version</key>
-       <string>349.0</string>
+       <string>364.0</string>
        <key>IBLockedObjects</key>
-       <array>
-               <integer>9</integer>
-       </array>
+       <array/>
        <key>IBOpenObjects</key>
        <array>
-               <integer>9</integer>
+               <integer>478</integer>
+               <integer>441</integer>
        </array>
        <key>IBSystem Version</key>
-       <string>7D24</string>
+       <string>7U16</string>
 </dict>
 </plist>
index e686680890375752b45f10e31b9be5f34337ea5f..e7971beb66cb345f4627c1c37972619bbc9a8476 100644 (file)
Binary files a/English.lproj/Preferences~.nib/keyedobjects.nib and b/English.lproj/Preferences~.nib/keyedobjects.nib differ
diff --git a/English.lproj/Preferences~.nib/objects.nib b/English.lproj/Preferences~.nib/objects.nib
deleted file mode 100644 (file)
index 0e8b2b7..0000000
Binary files a/English.lproj/Preferences~.nib/objects.nib and /dev/null differ
diff --git a/English.lproj/Record.nib/classes.nib b/English.lproj/Record.nib/classes.nib
deleted file mode 100644 (file)
index b9b4b09..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-    IBClasses = ({CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }); 
-    IBVersion = 1; 
-}
\ No newline at end of file
diff --git a/English.lproj/Record.nib/keyedobjects.nib b/English.lproj/Record.nib/keyedobjects.nib
deleted file mode 100644 (file)
index 5c01280..0000000
Binary files a/English.lproj/Record.nib/keyedobjects.nib and /dev/null differ
index b9b4b09f6b0d4e35bcaea7125d83273d98cf12dd..b97ccee4d14eb4ec05e1662640af7e2710f03f5a 100644 (file)
@@ -1,4 +1,8 @@
 {
-    IBClasses = ({CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }); 
+    IBClasses = (
+        {CLASS = CMStatusView; LANGUAGE = ObjC; SUPERCLASS = NSTextField; }, 
+        {CLASS = CheatDocument; LANGUAGE = ObjC; SUPERCLASS = NSDocument; }, 
+        {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }
+    ); 
     IBVersion = 1; 
 }
\ No newline at end of file
index 036e61dcb3156b2f97ef58b54dd95e3e02a50033..500695ad18358adccfee90f95010bdba5da741f7 100644 (file)
@@ -3,14 +3,14 @@
 <plist version="1.0">
 <dict>
        <key>IBDocumentLocation</key>
-       <string>98 99 356 240 0 0 1280 1002 </string>
+       <string>129 74 356 240 0 0 1280 938 </string>
        <key>IBFramework Version</key>
-       <string>349.0</string>
+       <string>364.0</string>
        <key>IBOpenObjects</key>
        <array>
                <integer>6</integer>
        </array>
        <key>IBSystem Version</key>
-       <string>7D24</string>
+       <string>7H63</string>
 </dict>
 </plist>
index 5c504287a6ccf0dbd3cda6759bd252448e715a16..9523f1b632a3da2226b3cbcdb15f39c9f7c021dc 100644 (file)
Binary files a/English.lproj/Record~.nib/keyedobjects.nib and b/English.lproj/Record~.nib/keyedobjects.nib differ
diff --git a/English.lproj/Session.nib/classes.nib b/English.lproj/Session.nib/classes.nib
deleted file mode 100644 (file)
index 72ac787..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-{
-    IBClasses = (
-        {CLASS = CMStatusView; LANGUAGE = ObjC; SUPERCLASS = NSTextField; }, 
-        {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 
-        {
-            ACTIONS = {
-                cancelButton = id; 
-                changeButton = id; 
-                clearSearchButton = id; 
-                okButton = id; 
-                pauseButton = id; 
-                processMenuItem = id; 
-                recurringChangeButton = id; 
-                redoMenu = id; 
-                searchButton = id; 
-                serverMenuDisconnect = id; 
-                serverMenuItem = id; 
-                serverMenuLocal = id; 
-                sizePopup = id; 
-                typePopup = id; 
-                undoMenu = id; 
-            }; 
-            CLASS = MyDocument; 
-            LANGUAGE = ObjC; 
-            OUTLETS = {
-                addressTable = NSTableView; 
-                cancelButton = NSButton; 
-                changeButton = NSButton; 
-                changeSecondsCombo = NSComboBox; 
-                changeSheet = NSWindow; 
-                changeTextField = NSTextField; 
-                cheatWindow = NSWindow; 
-                clearSearchButton = NSButton; 
-                decimalSizeMenu = NSMenu; 
-                descriptionText = NSTextField; 
-                integerSizeMenu = NSMenu; 
-                okButton = NSButton; 
-                pauseButton = NSButton; 
-                processMenu = NSMenu; 
-                processPopup = NSPopUpButton; 
-                recurringChangeButton = NSButton; 
-                searchButton = NSButton; 
-                searchRadioMatrix = NSMatrix; 
-                searchTextField = NSTextField; 
-                serverMenu = NSMenu; 
-                serverPopup = NSPopUpButton; 
-                sizePopup = NSPopUpButton; 
-                statusBar = NSProgressIndicator; 
-                statusText = NSTextField; 
-                stringSizeMenu = NSMenu; 
-                typeMenu = NSMenu; 
-                typePopup = NSPopUpButton; 
-            }; 
-            SUPERCLASS = NSDocument; 
-        }
-    ); 
-    IBVersion = 1; 
-}
\ No newline at end of file
diff --git a/English.lproj/Session.nib/info.nib b/English.lproj/Session.nib/info.nib
deleted file mode 100644 (file)
index 5268009..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-       <key>IBDocumentLocation</key>
-       <string>294 88 356 407 0 0 1280 1002 </string>
-       <key>IBEditorPositions</key>
-       <dict>
-               <key>143</key>
-               <string>402 411 86 87 0 0 1280 1002 </string>
-               <key>192</key>
-               <string>272 343 101 49 0 0 1280 1002 </string>
-               <key>207</key>
-               <string>376 382 134 49 0 0 1280 1002 </string>
-               <key>400</key>
-               <string>202 287 69 87 0 0 1280 1002 </string>
-               <key>405</key>
-               <string>264 308 79 68 0 0 1280 1002 </string>
-               <key>410</key>
-               <string>509 326 69 49 0 0 1280 1002 </string>
-               <key>735</key>
-               <string>499 516 296 322 0 0 1280 1002 </string>
-       </dict>
-       <key>IBFramework Version</key>
-       <string>349.0</string>
-       <key>IBLockedObjects</key>
-       <array>
-               <integer>285</integer>
-       </array>
-       <key>IBOldestOS</key>
-       <integer>2</integer>
-       <key>IBOpenObjects</key>
-       <array>
-               <integer>285</integer>
-       </array>
-       <key>IBSystem Version</key>
-       <string>7F44</string>
-</dict>
-</plist>
diff --git a/English.lproj/Session.nib/keyedobjects.nib b/English.lproj/Session.nib/keyedobjects.nib
deleted file mode 100644 (file)
index 4426d8a..0000000
Binary files a/English.lproj/Session.nib/keyedobjects.nib and /dev/null differ
diff --git a/English.lproj/Session.nib/objects.nib b/English.lproj/Session.nib/objects.nib
deleted file mode 100644 (file)
index 3e639c8..0000000
Binary files a/English.lproj/Session.nib/objects.nib and /dev/null differ
index e8fe7e133e39a64a2cf0e35e07cb8baf9586659f..b1b53f09c012e7c167c786aa7e11fb55395eaeca 100644 (file)
@@ -1,5 +1,12 @@
 {
     IBClasses = (
+        {
+            ACTIONS = {switchToFullScreen = id; }; 
+            CLASS = CMOpenGLView; 
+            LANGUAGE = ObjC; 
+            SUPERCLASS = NSOpenGLView; 
+        }, 
+        {CLASS = CMStatusView; LANGUAGE = ObjC; SUPERCLASS = NSTextField; }, 
         {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, 
         {
             ACTIONS = {
                 typePopup = NSPopUpButton; 
             }; 
             SUPERCLASS = NSDocument; 
+        }, 
+        {
+            ACTIONS = {
+                cancelButton = id; 
+                changeButton = id; 
+                clearSearchButton = id; 
+                okButton = id; 
+                pauseButton = id; 
+                processMenuItem = id; 
+                recurringChangeButton = id; 
+                redo = id; 
+                searchButton = id; 
+                serverMenuDisconnect = id; 
+                serverMenuItem = id; 
+                serverMenuLocal = id; 
+                sizePopup = id; 
+                typePopup = id; 
+                undo = id; 
+            }; 
+            CLASS = SessionController; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {
+                addressTable = NSTableView; 
+                cancelButton = NSButton; 
+                changeButton = NSButton; 
+                changeSecondsCombo = NSComboBox; 
+                changeSheet = NSWindow; 
+                changeTextField = NSTextField; 
+                cheatWindow = NSWindow; 
+                clearSearchButton = NSButton; 
+                decimalSizeMenu = NSMenu; 
+                descriptionText = NSTextField; 
+                integerSizeMenu = NSMenu; 
+                okButton = NSButton; 
+                pauseButton = NSButton; 
+                processMenu = NSMenu; 
+                processPopup = NSPopUpButton; 
+                recurringChangeButton = NSButton; 
+                searchButton = NSButton; 
+                searchRadioMatrix = NSMatrix; 
+                searchTextField = NSTextField; 
+                serverMenu = NSMenu; 
+                serverPopup = NSPopUpButton; 
+                sizePopup = NSPopUpButton; 
+                statusBar = NSProgressIndicator; 
+                statusText = CMStatusView; 
+                stringSizeMenu = NSMenu; 
+                typeMenu = NSMenu; 
+                typePopup = NSPopUpButton; 
+            }; 
+            SUPERCLASS = NSWindowController; 
         }
     ); 
     IBVersion = 1; 
index 6150a8285882e426ba7eadcb67dd1a2ccc20f683..2cebd7fdf786bcf8163b0fcc4e4c28293ecf61bc 100644 (file)
@@ -3,7 +3,7 @@
 <plist version="1.0">
 <dict>
        <key>IBDocumentLocation</key>
-       <string>114 -132 356 406 0 0 1280 1002 </string>
+       <string>545 63 356 407 0 0 1280 938 </string>
        <key>IBEditorPositions</key>
        <dict>
                <key>143</key>
                <key>410</key>
                <string>509 326 69 49 0 0 1280 1002 </string>
                <key>735</key>
-               <string>499 516 296 322 0 0 1280 1002 </string>
+               <string>492 479 296 321 0 0 1280 938 </string>
+               <key>777</key>
+               <string>627 581 72 68 0 0 1280 938 </string>
        </dict>
        <key>IBFramework Version</key>
-       <string>349.0</string>
+       <string>364.0</string>
        <key>IBLockedObjects</key>
-       <array>
-               <integer>285</integer>
-       </array>
+       <array/>
        <key>IBOldestOS</key>
        <integer>2</integer>
        <key>IBOpenObjects</key>
@@ -34,6 +34,6 @@
                <integer>285</integer>
        </array>
        <key>IBSystem Version</key>
-       <string>7D24</string>
+       <string>7H63</string>
 </dict>
 </plist>
index 0e00406ad94c7c14884d9f90a5c6db49b86c9a9f..14c30c648c029436aa6b80fc2fae31228682e330 100644 (file)
Binary files a/English.lproj/Session~.nib/keyedobjects.nib and b/English.lproj/Session~.nib/keyedobjects.nib differ
index 46427e8ef3fb8bac1ecbfd3aa34a31f1ea814672..21424809d52d5b550d5dd0d77542e5a755cd83ee 100644 (file)
Binary files a/English.lproj/Session~.nib/objects.nib and b/English.lproj/Session~.nib/objects.nib differ
diff --git a/English.lproj/locversion.plist b/English.lproj/locversion.plist
new file mode 100644 (file)
index 0000000..d36912c
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>LprojCompatibleVersion</key>
+       <string>116.2</string>
+       <key>LprojLocale</key>
+       <string>en</string>
+       <key>LprojRevisionLevel</key>
+       <string>1</string>
+       <key>LprojVersion</key>
+       <string>116.2</string>
+</dict>
+</plist>
diff --git a/FadeView.h b/FadeView.h
new file mode 100644 (file)
index 0000000..912764b
--- /dev/null
@@ -0,0 +1,46 @@
+//
+//  FadeView.h
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 12/6/04.
+//  Copyright 2004 Chaz McGarvey. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface FadeView : NSView
+{
+       NSImage *_fadeImage;
+       double _fadeAlpha;
+       
+       NSTimeInterval _fadeDuration;
+       NSTimeInterval _fadeInterval;
+       NSTimer *_fadeTimer;
+       
+       id _delegate;
+}
+
+- (NSImage *)image;
+- (NSTimeInterval)fadeDuration;
+- (NSTimeInterval)fadeInterval;
+- (double)alpha;
+
+- (void)setImage:(NSImage *)image;
+- (void)setFadeDuration:(NSTimeInterval)seconds;
+- (void)setFadeInterval:(NSTimeInterval)seconds;
+
+- (void)startFadeAnimation;
+- (void)stopFadeAnimation;
+
+- (id)delegate;
+- (void)setDelegate:(id)delegate;
+
+@end
+
+
+@interface NSObject ( FadeViewDelegate )
+
+- (void)fadeViewFinishedAnimation:(FadeView *)theView;
+
+@end
\ No newline at end of file
diff --git a/FadeView.m b/FadeView.m
new file mode 100644 (file)
index 0000000..0e9b7ee
--- /dev/null
@@ -0,0 +1,145 @@
+//
+//  FadeView.m
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 12/6/04.
+//  Copyright 2004 Chaz McGarvey. All rights reserved.
+//
+
+#import "FadeView.h"
+
+
+@interface FadeView ( PrivateAPI )
+
+- (void)_fadeTimer:(NSTimer *)timer;
+
+@end
+
+
+@implementation FadeView
+
+
+- (id)init
+{
+       if ( self = [super init] ) {
+               [self setFadeDuration:1.0];
+               [self setFadeInterval:5.0/60.0];
+       }
+       return self;
+}
+
+- (id)initWithFrame:(NSRect)frame
+{
+       if ( self = [super initWithFrame:frame] ) {
+               [self setFadeDuration:1.0];
+               [self setFadeInterval:5.0/60.0];
+       }
+       return self;
+}
+
+- (void)dealloc
+{
+       [self stopFadeAnimation];
+       [_fadeImage release];
+       [super dealloc];
+}
+
+
+- (void)drawRect:(NSRect)rect
+{
+    [_fadeImage dissolveToPoint:NSMakePoint(0,0) fraction:_fadeAlpha];
+}
+
+
+- (NSImage *)image
+{
+       return _fadeImage;
+}
+
+- (NSTimeInterval)fadeDuration
+{
+       return _fadeDuration;
+}
+
+- (NSTimeInterval)fadeInterval
+{
+       return _fadeInterval;
+}
+
+- (double)alpha
+{
+       return _fadeAlpha;
+}
+
+
+- (void)setImage:(NSImage *)image
+{
+       [image retain];
+       [_fadeImage release];
+       _fadeImage = image;
+}
+
+- (void)setFadeDuration:(NSTimeInterval)seconds
+{
+       if ( seconds != 0.0 ) {
+               _fadeDuration = seconds;
+       }
+       else {
+               _fadeDuration = 1.0;
+       }
+}
+
+- (void)setFadeInterval:(NSTimeInterval)seconds
+{
+       _fadeInterval = seconds;
+}
+
+- (void)startFadeAnimation
+{
+       [self stopFadeAnimation];
+       
+       _fadeAlpha = 1.0;
+       [self setNeedsDisplay:YES];
+       
+       _fadeTimer = [[NSTimer scheduledTimerWithTimeInterval:_fadeInterval target:self selector:@selector(_fadeTimer:) userInfo:nil repeats:YES] retain];
+       [[NSRunLoop currentRunLoop] addTimer:_fadeTimer forMode:NSEventTrackingRunLoopMode];
+       [[NSRunLoop currentRunLoop] addTimer:_fadeTimer forMode:NSModalPanelRunLoopMode];
+       [self release];
+}
+
+- (void)stopFadeAnimation
+{
+       if ( _fadeTimer ) {
+               [self retain];
+               [_fadeTimer invalidate];
+               [_fadeTimer release];
+               _fadeTimer = nil;
+       }
+}
+
+- (void)_fadeTimer:(NSTimer *)timer
+{
+       _fadeAlpha -= [timer timeInterval] / _fadeDuration;
+       [self setNeedsDisplay:YES];
+       
+       if ( _fadeAlpha <= 0.0 ) {
+               [self stopFadeAnimation];
+               if ( [_delegate respondsToSelector:@selector(fadeViewFinishedAnimation:)] ) {
+                       [_delegate fadeViewFinishedAnimation:self];
+               }
+       }
+}
+
+
+- (id)delegate
+{
+       return _delegate;
+}
+
+- (void)setDelegate:(id)delegate
+{
+       _delegate = delegate;
+}
+
+
+@end
diff --git a/General.png b/General.png
new file mode 100644 (file)
index 0000000..3284f60
Binary files /dev/null and b/General.png differ
diff --git a/GeneralPrefs.h b/GeneralPrefs.h
new file mode 100644 (file)
index 0000000..a67d011
--- /dev/null
@@ -0,0 +1,46 @@
+
+// **********************************************************************
+// 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 <Cocoa/Cocoa.h>
+#include "cheat_global.h"
+
+
+@interface GeneralPrefs : NSObject
+{
+       IBOutlet NSButton *ibWindowOrderButton;
+       IBOutlet NSButton *ibAskForSaveButton;
+       IBOutlet NSButton *ibFadeSmoothlyButton;
+       IBOutlet NSButton *ibDisplayValuesButton;
+       IBOutlet NSTextField *ibValueUpdateField;
+       IBOutlet NSTextField *ibResultsDisplayedField;
+       IBOutlet NSButton *ibSwitchVariablesButton;
+       IBOutlet NSButton *ibStartEditingVarsButton;
+}
+
+- (IBAction)ibWindowOrderButton:(id)sender;
+- (IBAction)ibSetAskForSave:(id)sender;
+- (IBAction)ibSetFadeSmoothly:(id)sender;
+- (IBAction)ibDisplayValuesButton:(id)sender;
+- (IBAction)ibSetValueUpdate:(id)sender;
+- (IBAction)ibSetResultsDisplayed:(id)sender;
+- (IBAction)ibSwitchVariablesButton:(id)sender;
+- (IBAction)ibStartEditingVarsButton:(id)sender;
+
+@end
diff --git a/GeneralPrefs.m b/GeneralPrefs.m
new file mode 100644 (file)
index 0000000..afcbe60
--- /dev/null
@@ -0,0 +1,138 @@
+
+// **********************************************************************
+// 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 "GeneralPrefs.h"
+
+
+@implementation GeneralPrefs
+
+
+- (void)awakeFromNib
+{
+       // set initial states
+       [ibWindowOrderButton setState:[[NSUserDefaults standardUserDefaults] boolForKey:TCWindowsOnTopPref]];
+       [ibAskForSaveButton setState:[[NSUserDefaults standardUserDefaults] boolForKey:TCAskForSavePref]];
+       if ( [[NSUserDefaults standardUserDefaults] floatForKey:TCFadeAnimationPref] > 0.0 ) {
+               [ibFadeSmoothlyButton setState:NSOnState];
+       }
+       else {
+               [ibFadeSmoothlyButton setState:NSOffState];
+       }
+       [ibDisplayValuesButton setState:[[NSUserDefaults standardUserDefaults] boolForKey:TCDisplayValuesPref]];
+       [ibValueUpdateField setFloatValue:[[NSUserDefaults standardUserDefaults] floatForKey:TCValueUpdatePref]];
+       [ibValueUpdateField setEnabled:[ibDisplayValuesButton state]];
+       [ibResultsDisplayedField setIntValue:[[NSUserDefaults standardUserDefaults] integerForKey:TCHitsDisplayedPref]];
+       
+       [ibSwitchVariablesButton setState:[[NSUserDefaults standardUserDefaults] boolForKey:TCSwitchVariablesPref]];
+       [ibStartEditingVarsButton setState:[[NSUserDefaults standardUserDefaults] boolForKey:TCAutoStartEditingVarsPref]];
+       [ibStartEditingVarsButton setEnabled:[ibSwitchVariablesButton state]];
+}
+
+
+- (IBAction)ibWindowOrderButton:(id)sender
+{
+       BOOL pref = [sender state];
+       [[NSUserDefaults standardUserDefaults] setBool:pref forKey:TCWindowsOnTopPref];
+       // notify currently opened windows of the change
+       [[NSNotificationCenter defaultCenter] postNotificationName:TCWindowsOnTopChangedNote object:[NSNumber numberWithBool:pref]];
+}
+
+- (IBAction)ibSetAskForSave:(id)sender
+{
+       BOOL pref = [sender state];
+       [[NSUserDefaults standardUserDefaults] setBool:pref forKey:TCAskForSavePref];
+}
+
+- (IBAction)ibSetFadeSmoothly:(id)sender
+{
+       float fade;
+       
+       if ( [sender state] == NSOnState ) {
+               fade = TCDefaultFadeAnimation;
+       }
+       else {
+               fade = 0.0;
+       }
+       [[NSUserDefaults standardUserDefaults] setFloat:fade forKey:TCFadeAnimationPref];
+       gFadeAnimationDuration = fade;
+}
+
+- (IBAction)ibDisplayValuesButton:(id)sender
+{
+       BOOL flag = [ibDisplayValuesButton state];
+       [[NSUserDefaults standardUserDefaults] setBool:flag forKey:TCDisplayValuesPref];
+       
+       [ibValueUpdateField setEnabled:flag];
+       
+       // notify currently opened windows of the change
+       [[NSNotificationCenter defaultCenter] postNotificationName:TCDisplayValuesChangedNote object:nil];
+}
+
+- (IBAction)ibSetValueUpdate:(id)sender
+{
+       float value = [sender floatValue];
+       
+       if ( value < 0.1 ) {
+               value = 0.1;
+               [sender setFloatValue:value];
+       }
+       
+       [[NSUserDefaults standardUserDefaults] setFloat:value forKey:TCValueUpdatePref];
+       
+       // notify currently opened windows of the change
+       [[NSNotificationCenter defaultCenter] postNotificationName:TCDisplayValuesChangedNote object:nil];
+}
+
+- (IBAction)ibSetResultsDisplayed:(id)sender
+{
+       int value = [ibResultsDisplayedField intValue];
+       
+       if ( value < 0 ) {
+               value = 0;
+               [ibResultsDisplayedField setIntValue:value];
+       }
+       
+       [[NSUserDefaults standardUserDefaults] setInteger:value forKey:TCHitsDisplayedPref];
+       
+       // notify currently opened windows of the change
+       [[NSNotificationCenter defaultCenter] postNotificationName:TCHitsDisplayedChangedNote object:nil];
+}
+
+
+- (IBAction)ibSwitchVariablesButton:(id)sender
+{
+       BOOL flag = [ibSwitchVariablesButton state];
+       [[NSUserDefaults standardUserDefaults] setBool:flag forKey:TCSwitchVariablesPref];
+       
+       [ibStartEditingVarsButton setEnabled:[ibSwitchVariablesButton state]];
+       if ( !flag ) {
+               [ibStartEditingVarsButton setState:NO];
+               [[NSUserDefaults standardUserDefaults] setBool:NO forKey:TCAutoStartEditingVarsPref];
+       }
+}
+
+- (IBAction)ibStartEditingVarsButton:(id)sender
+{
+       BOOL flag = [ibStartEditingVarsButton state];
+       [[NSUserDefaults standardUserDefaults] setBool:flag forKey:TCAutoStartEditingVarsPref];
+}
+
+
+@end
diff --git a/Help.html b/Help.html
new file mode 100644 (file)
index 0000000..ed095a8
--- /dev/null
+++ b/Help.html
@@ -0,0 +1,411 @@
+<html>
+<head>
+
+<style type="text/css">
+<!--
+a:link, a:visited {
+       color: #3333ff;
+       text-decoration: none;
+}
+a:hover {
+       color: #9999ff;
+       text-decoration: none;
+}
+a:active {
+       color: #660000;
+       text-decoration: none;
+}
+
+body {
+       font: 14px Lucida Grande, sans-serif;
+       text-align: justify;
+       color: #000000;
+       background-color: #ffffff;
+       padding: 10px 10px 10px 10px;
+}
+
+p {
+       text-indent: 2em;
+}
+
+hr {
+       color: #999999;
+       border-style: dashed;
+}
+
+code {
+       font: 12px Monaco, monospace;
+       color: #006600;
+}
+
+.ind {
+       margin: 0 0 0 2em;
+}
+
+.header {
+       font-size: 16px;
+       font-weight: bold;
+       text-transform: capitalize;
+       border: 1px solid #CCCCCC;
+       padding: 2px 1em 2px 1em;
+}
+
+.tip {
+       font-size: 12px;
+       background-color: #EEEEEE;
+       border: 1px solid #CCCCCC;
+       padding: 5px 20px 5px 20px;
+       margin: 0px 100px 0px 100px;
+}
+-->
+</style>
+
+</head>
+<body>
+
+<a name="0" />
+<br />
+<div align="center"><img src="icon.icns" width="128" height="128" /></div>
+<div align="right" style="font-size: 12px;">
+<i><b>The Cheat Help File</b><br />Chaz McGarvey<br />22 Febuary, 2005</i>
+</div>
+<br />
+
+<div class="header">Table of Contents</div>
+
+<p><div class="ind"><a href="#1">1. How to get help with The Cheat</a>
+       <div class="ind"><a href="#1-1">1.1 About this file</a></div>
+</div></p>
+<p><div class="ind"><a href="#2">2. What is The Cheat?</a>
+       <div class="ind"><a href="#2-1">2.1 How The Cheat works</a></div>
+       <div class="ind"><a href="#2-2">2.2 Is cheating dangerous?</a></div>
+       <div class="ind"><a href="#2-3">2.3 About the program author</a></div>
+</div></p>
+<p><div class="ind"><a href="#3">3. The fundamentals of cheating</a>
+       <div class="ind"><a href="#3-1">3.1 What is cheating?</a></div>
+       <div class="ind"><a href="#3-2">3.2 What is a variable?</a></div>
+       <div class="ind"><a href="#3-3">3.3 Addresses, hexadecimal</a></div>
+</div></p>
+<p><div class="ind"><a href="#4">4. The user interface</a></div>
+</p>
+<p><div class="ind"><a href="#5">5. Searching for variables</a>
+       <div class="ind"><a href="#5-1">5.1 Basic searching strategy</a></div>
+       <div class="ind"><a href="#5-2">5.2 Variable types</a>
+               <div class="ind"><a href="#5-2-1">5.2.1 Integers</a></div>
+               <div class="ind"><a href="#5-2-2">5.2.2 Floating point numbers</a></div>
+               <div class="ind"><a href="#5-2-3">5.2.3 ASCII strings</a></div>
+       </div>
+       <div class="ind"><a href="#5-3">5.3 Advanced searching techniques</a>
+               <div class="ind"><a href="#5-3-1">5.3.1 Search operators</a></div>
+               <div class="ind"><a href="#5-3-2">5.3.2 Last value searching</a></div>
+       </div>
+</div></p>
+<p><div class="ind"><a href="#6">6. Changing variables</a>
+       <div class="ind"><a href="#6-1">6.1 Managing variables</a></div>
+       <div class="ind"><a href="#6-2">6.2 Saving cheat files</a></div>
+       <div class="ind"><a href="#6-3">6.3 Repeating cheats</a></div>
+</div></p>
+<p><div class="ind"><a href="#7">7. Menu commands</a>
+       <div class="ind"><a href="#7-1">7.1 Cheat Properties&#8230 &#8984I</a></div>
+       <div class="ind"><a href="#7-2">7.2 Pause Target &#8984P</a></div>
+       <div class="ind"><a href="#7-3">7.3 Clear Search &#8984&#9003</a></div>
+       <div class="ind"><a href="#7-4">7.4 Dump Memory &#8984D</a></div>
+       <div class="ind"><a href="#7-5">7.5 Add New Variable</a></div>
+       <div class="ind"><a href="#7-6">7.6 Edit Variables &#8984&#8617</a></div>
+       <div class="ind"><a href="#7-7">7.7 Show [...] Mode &#8984T</a></div>
+       <div class="ind"><a href="#7-8">7.8 Other Server&#8230 &#8984K</a></div>
+</div></p>
+<p><div class="ind"><a href="#8">8. Customizing The Cheat</a>
+       <div class="ind"><a href="#8-1">8.1 General settings</a></div>
+       <div class="ind"><a href="#8-2">8.2 Update check</a></div>
+</div></p>
+<p><div class="ind"><a href="#9">9. Remote cheating</a>
+       <div class="ind"><a href="#9-1">9.1 Starting the cheat server</a></div>
+       <div class="ind"><a href="#9-2">9.2 Managing connections</a></div>
+       <div class="ind"><a href="#9-3">9.3 Troubleshooting problems</a></div>
+</div></p>
+
+<a name="1" />
+<div class="header">1. How To Get Help with The Cheat</div>
+
+<p>The Cheat is designed with expert users in mind.  The interface is tailored for rapid use, and it wastes few words in describing its functions.  Nevertheless, the interface is simple and intuitive once you know a little bit about what is going on.  New users should have little trouble in picking up the basics of cheating, and there are many resources available to you to help you get started.  Here are some resources to check out:
+
+<div class="ind"><a href="http://www.brokenzipper.com/thecheat/">Tutorials/FAQs</a></div>
+<div class="ind"><a href="http://forum.brokenzipper.com/">User Support Forum</a></div>
+<div class="ind"><a href="mailto:chaz@brokenzipper.com">Email Me</a></div></p>
+
+<hr />
+
+<a name="1-1" />
+<p>Your main resource as a new user is this file.  This is the most convenient place to get quick help because it is built right into The Cheat, and it points to all of the other resources.  This file contains comprehensive information about using The Cheat and should be consulted before any other resources.  This document is organized to maximize convenience and usefulness.  It can be read straight-through from top to bottom if you have a lot of time on your hands, or you can refer to certain sections whenever you are faced with a question or problem.</p>
+
+<p>Use the table of contents at the top of this page to jump to the sections which interest you.  You can get back to the top of this page using the links labeled "top" which appear at the end of each section.  I have also used a few typographical conventions to make the reading easier.  Variable addresses and variable values will appear in this <code>green mono font</code>.  I have also <i>italicized</i> user interface identifiers to help you follow instructions when they are given.  For example, you might see "From the menu, choose <i>Cheater -> Edit Variables</i>, and set the <i>New Value</i> field to <code>128</code>."</p>
+
+<div class="tip">
+<span style="font-size: 14px; font-weight: bold;">Tip:</span>  You will also see a few "tip" boxes throughout this document.  They typically contain information that is not crucial to understanding, but will surely be beneficial if you take the time to read them.  They will often expand upon certain points.
+</div>
+
+<p>If you come across any material in this document which is unclear or unreasonably vague, please <a href="mailto:chaz@brokenzipper.com">let me know</a>.  Otherwise, enjoy the ride.</p>
+
+<p align="right"><a href="#0">top</a></p>
+
+<a name="2" />
+<div class="header">2. What is The Cheat?</div>
+
+<p>The Cheat is an application referred to as a <b>universal game trainer</b>.  It allows you to alter many different aspects of computer games.  For example, you can change things like the amount of lives your character has, the amount of ammo, the level you're on, the abilities you have, your location in the game, and more.  This all occurs in real-time while the game is running, and it will work for almost any game.  If you are interested in The Cheat from a more technical standpoint, there is also some information available on my web site about the <a href="http://www.brokenzipper.com/developer/">virtual memory system</a>, and of course The Cheat is also open source.</p>
+
+<a name="2-1" />
+<p>To do what it does, The Cheat accesses the memory of other applications.  It first reads through the entire address space, searching for variables based on input you provide.  Search results are then narrowed down by scanning the memory again after the value of the variable you are searching for has changed.  After a few searches, there should only be one variable remaining (ideally).  The Cheat will then allow you to change this variable to whatever you want.  The rest of this document will focus on the best ways to find variables, since that is the trickiest part.</p>
+
+<a name="2-2" />
+<p>Mac OS X includes support for protected memory which disables programs from accessing the memory of the system and other programs.  This causes a more stable system because faulty applications won't be able to trash the memory of other applications which could cause crashes and lockups.  Since The Cheat is able to get around this protection, might this be bad for stability?  Potentially, yes.  However, The Cheat only changes the memory of other programs where you tell it to.  If you are careful, your games should never crash.  Furthermore, assuming you don't run The Cheat as root (which would be a Bad Thing), The Cheat will not be able to alter any system-critical processes, so it would actually be very difficult if not impossible to crash or mess up your system using The Cheat.</p>
+
+<a name="2-3" />
+<p>The Cheat was written by some random guy named Chaz McGarvey.  He is also the guy who is writing this help file, so he will now refer to himself in first-person.  Currently, I'm 19 years old.  Programming is just a hobby of mine; I've never really taken any classes or anything.  I just think it's fun, so I do it sometimes.  I'm going to school at the University of Utah, studying to become who knows what.  Besides programming, I enjoy sleeping and participating in anything that occurs in the water.  A few of my more ambitious goals include taking over the world and being involved with the colonization of Mars.  I also have an <a href="mailto:chaz@brokenzipper.com">email address</a> and a <a href="http://www.brokenzipper.com/">web site</a> if you care to take advantage of either.</p>
+
+<p align="right"><a href="#0">top</a></p>
+
+<a name="3" />
+<div class="header">3. The Fundamentals of Cheating</div>
+
+<p>The process behind cheating is almost as old as computer games themselves.  The idea is this: everything that a computer game "knows" is stored in memory.  The advent of virtual memory has blurred the line between physical memory and hard disk space, but the distinction doesn't apply on a fundamental level.  Given the fact that we know the game is storing what it knows in memory, and also assuming that it's possible to go in there and alter that memory behind the game's back, we can conclude that we have the ability to make the game do whatever we want, up to the limits put upon us by the game's code.</p>
+
+<a name="3-1" />
+<p>Simply put, <b>cheating</b> is altering the memory of a game in order to make it do what we want.  It's time to define some other terms which will surely be used throughout this document and whenever you talk with someone about cheating.</p>
+
+<p>The <b>address space</b> refers to all of the memory that a program is using.  It is the memory that will be searched and changed.  It is important to note that not all addresses in the address space are being used; you'll see why this is important when you learn abut changing variables.</p>
+
+<a name="3-2" />
+<p>A <b>variable</b> is analogous to a "variable" in mathematics.  A variable has two components: an address and a value.  The <b>value</b> is a storable concept, usually a number (i.e. <code>73</code>, <code>0</code>, and <code>73453.236</code> are all values).  The <b>address</b> is a location in the address space where the value is stored.  Given the mathematical expression <code>X=56</code>, the value is <code>56</code> and the address is <code>X</code>.  It takes both the address and the value to define a variable.</p>
+
+<p>Because of how computers are designed, an address will never be as simple as just <code>X</code>.  An address for a computer is actually just a number which points to a location within a program's address space.  Today's 32-bit computers can use addresses from 0 thru 2<sup>32</sup>-1 (that's over four billion different addresses).  A move toward 64-bit processing is occurring, although 32-bit programs on a 64-bit computer will still only be able to access 2<sup>32</sup> addresses.</p>
+
+<a name="3-3" />
+<p>The Cheat uses <b>hexadecimal</b> notation to display addresses.  Hexadecimal is a number system based on 16 digits.  It is often denoted with the "<code>0x</code>" prefix.  The digits used are <code>0</code> thru <code>F</code>.  For example, <code>0x9</code> is equal to <code>9</code> in decimal, and <code>0xA</code> is equal to <code>10</code> in decimal.  <code>0xF</code> is equal to <code>15</code> in decimal, etc.  It is not necessary to understand this notation to use The Cheat.  You just need to be able to recognize an address when you see one.  If you want to learn more about hexadecimal, <a href="http://www.google.com/search?hl=en&q=hexadecimal">Google</a> should be able to help you out.</p>
+
+<hr />
+
+<p>One of the challenges of cheating is knowing what memory to change in order to produce the desired effect.  You have roughly 0.0000000931% chance to randomly guess the correct address.  The Cheat exists to increase those odds.  Nevertheless, cheating is not for the faint of heart.  It can very easily become an exercise in frustration if you lose your cool.</p>
+
+<p>What a variable fundamentally represents is something in a game that changes.  You, as a cheater, want to be able to change that "something" to whatever you want.  In order to do that, we first have to find the address of that variable.  How do we do this, you ask?  Well, by searching of course.  Searching is covered in detail <a href="#5">a little later</a>.  After the variable's address is found, it is only a matter of changing the value to whatever you want, which is also covered <a href="#6">later</a>.  See, cheating really isn't very complicated is it?</p>
+
+<p align="right"><a href="#0">top</a></p>
+
+<a name="4" />
+<div class="header">4. The User Interface</div>
+
+<p>As has been mentioned in the introduction, the interface of The Cheat has been designed with experts in mind.  It is relatively intuitive for people who have used a game trainer before and know how they work.  Therefore, the best way to learn how to use The Cheat is to get to know the process involved in cheating games!</p>
+
+<p>Cheating involves both <a href="#5">searching for variables</a> in memory and <a href="#6">changing those variables</a> to a new value of our choosing.  Both of these components are covered in detailed later in this document.  Because the tasks of searching and changing are fundamentally separate, The Cheat's interface likewise has two modes of operation.</p>
+
+<p>The default mode is the <i>Search Mode</i>.  This mode provides you with the tools you need to find variables in memory.  The other mode is the <i>Cheat Mode</i> which allows you to organize the variables that you have found and change them to new values.  You can toggle between these two modes by choosing <i><a href="#7-7">Cheater -> Show [...] Mode &#8984T</a></i> from the menu.</p>
+
+<p>The Cheat also provides other tools which aid in the entire cheating process.  Such tools are usually accessed from the <i>Cheater</i> menu.  Most commands can also be activated using an alternate key sequence, so you can keep your hands on the keyboard as much as possible if that's your thing.  For a description of the various menu items available to you, check out <a href="#7">section 7</a>.</p>
+
+<div class="tip">
+<span style="font-size: 14px; font-weight: bold;">Tip:</span> You can create multiple "sessions" in order to search for and cheat multiple variables at the same time.  Just choose <i>File -> New Search &#8984N</i>.  You can also choose <i>File -> New Blank Cheat &#8679&#8984N</i> to start a new session which defaults to <i>Cheat Mode</i>.
+</div>
+
+<p>As with any user interface, the best way to learn it is to get your hands dirty and to start playing around with it.  I could write a novel about using the interface, and it still wouldn't be worth 10 minutes of hands-on experience.</p>
+
+<p align="right"><a href="#0">top</a></p>
+
+<a name="5" />
+<div class="header">5. Searching for Variables</div>
+
+<p>The strategy behind finding variables is to do a search when the variable you are looking for has its value changed to something (anything) else.  When searching for variables, you always search for its value because it's the address which we don't know.  The address could be virtually anything, and it doesn't really matter what it is.  The value, on the other hand, we do usually know.</p>
+
+<a name="5-1" />
+<p>For example, assume I'm playing a first-person shooter, and the game displays how many bullets I have at the top of the screen.  You know that somewhere in memory, the game is keeping track of that number with a variable.  You know the value of the variable because its on the screen, but you don't know where in memory that variable resides.  Using this basic example, here is what you would do in order to find the address of that variable.</p>
+
+<p>At any convenient point in the game, just do a search for the current value of the ammunition variable.  For example, if I had 16 bullets I would search for <code>16</code>.  The only problem is there will be thousands of variables in memory which also happen to have that same value.  How do you know which variable refers to the ammunition?  You won't until you narrow down your results by performing another search.</p>
+
+<p>I would go back to the game and fire off a few bullets into space.  Now I have 13 bullets.  Now, by keeping your previous results in memory, you can compare only those results against this new value of <code>13</code>; so just do another search for the value <code>13</code>.</p>
+
+<div class="tip">
+<span style="font-size: 14px; font-weight: bold;">Tip:</span> Sometimes your search will not narrow down to exactly one result, even though you are only searching for one variable.  This may occur if the game happens to be storing that variable at multiple addresses.  Don't worry about this.  You can either change all remaining variables or narrow them down by observing value changes without searching.
+</div>
+
+<p>Each time you do a cross-search against the results you've obtained so far, your results will be narrowed down.  Keep narrowing down the results until you can see which variable is the ammunition variable.  You will be able to tell because you will see the value change as you shoot more bullets or pick up more ammunition.</p>
+
+<hr />
+
+<a name="5-2" />
+<p>There are actually several different types of variables that a game can use.  You are going to have to know a little bit about how variables are stored in memory to understand the different types of variables.  There are three basic types that The Cheat supports: integers, floating point numbers, and byte-streams.</p>
+
+<a name="5-2-1" />
+<p>The most common (and useful) variable type is the <b>integer</b>.  An integer variable can only hold either positive or negative whole numbers.  For example, <code>-56</code>, <code>0</code>, <code>3</code>, and <code>663453234223334</code> are all integers.  There are two things you need to know about integers.  First, an integer can be either signed or unsigned.  An integer that is <b>signed</b> can have both positive and negative values.  An <b>unsigned</b> integer on the other hand can only have positive values.</p>
+
+<p>The other thing you need to know about integers is that there is a finite number of values that any integer can have, and the number of available values depends upon the sign of the integer and how many bits in memory the integer "takes up."  <b>If you are freaking out right about now, please DON'T PANIC!</b>  I wouldn't be covering this if it wasn't necessary, but you don't need to remember all of this at once.  Take a few big breaths and relax.  You can always refer back to this section if you didn't quite get it the first time.</p>
+
+<p>The Cheat supports four different integer sizes: 8-bit, 16-bit, 32-bit, and 64-bit.  An 8-bit integer can hold 2<sup>8</sup> different values, which works out to be 256 values.  What those values can be depends on the sign of the integer.  If you have an 8-bit signed integer, that variable can hold a number between (and including) <code>-128</code> and <code>127</code>, which works out to exactly 256 different values if you do the math.  If you have an 8-bit unsigned integer, that variable can hold a number between (and including) <code>0</code> and <code>255</code>, which also works out to 256 different values.</p>
+
+<p>This concept can be extended to all integers.  A 16-bit integer can hold one of 2<sup>16</sup> (or 65536) values.  If the 16-bit integer is signed, the values can range from <code>-32768</code> to <code>32767</code>; likewise a 16-bit unsigned integer has values that range from <code>0</code> to <code>65535</code>.</p>
+
+<div class="tip">
+<span style="font-size: 14px; font-weight: bold;">Tip:</span> The tricky part about choosing which type of integer to use is that just because you'll never see values get greater than a certain amount, that doesn't mean the variable isn't capable of going higher.  For example, the logic of the game may prohibit a certain value to go higher than a certain point, say 1000, but the variable could still theoretically be a 32-bit integer even though it could be as little as a 16-bit integer.  <b>A 32-bit signed integer is the most common variable.</b>
+</div>
+
+<p>Fortunately, when searching for integer variables, it is not always necessary for you to use the correct sign and integer size in order to find the variable you are looking for.  For example, a 32-bit signed integer with a value of <code>1977</code> is actually equal to a 32-bit unsigned integer with the same value.  A lot of the time you will only discover whether an integer is signed or unsigned after you have found it and are trying to change the value.  For example, if you find a variable which you think is a signed integer, but it becomes a large positive number when you try to change it to a negative value, then you know it is actually unsigned.  The distinction between signed and unsigned rarely needs to be considered while searching.</p>
+
+<a name="5-2-2" />
+<p>The next variable type is the <b>floating point number</b>.  Like the integer, a floating point variable also has number values, but they can have fractional values.  For example, <code>-632.5</code>, <code>0.0002</code>, <code>636345.0</code>, and <code>885.6234234423</code> are all floating point numbers.  Floating points come in only two sizes: 32-bit (float) and 64-bit (double).</p>
+
+<p>Searching for floating points is considerably different than searching for integers.  For one thing, you have to use the correct size or you will not find the variable.  For example, a float with a value of <code>7.0</code> does NOT equal a double with the same value.  The only way to decide whether a floating point number is a float or a double is to look at the range of values the variable has.  A double can hold twice as much as a float can, which is probably why it's called "double."</p>
+
+<div class="tip">
+<span style="font-size: 14px; font-weight: bold;">Tip:</span> You do not need to be particularly accurate when searching for floats.  You only need to specify one extra digit after the decimal place.  This is why the results you get can vary sightly from the value you entered.</b>
+</div>
+
+<a name="5-2-3" />
+<p>The last variable type is a stream of bytes.  This is more commonly called an <b>ASCII string</b>.  ASCII just refers to the fact that the byte-stream is actually a string with special encoding.  In the case of an ASCII string, the encoded data consists of words and phrases.  It can also consist of numbers, but while the numbers are encoded as an ASCII string, the computer does not recognize it as a number.  To the computer, it's just a stream of bytes.  It is because of this that an integer with a value of <code>765</code> does NOT equal an ASCII string encoded with the same value.</p>
+
+<p>You will probably never use an ASCII string search when you are searching for number values.  The types of variables the ASCII string search finds are words, like perhaps the name of your character.</p>
+
+<hr />
+
+<a name="5-3" />
+<p>Let's revisit our made-up first-person shooter for the time being.  We now want to find the health variable so we can increase our health whenever we get low.  Our health is displayed along the bottom of the screen as a progress bar.  The bar shrinks when we get shot and grows when we pick up first aid kits.  The problem is that a progress bar doesn't give us anything we can directly search for.  In this case, we don't know the address or the value of the variable we are looking for.  We don't even know what type of variable it is!  How on earth are we supposed to find it!?</p>
+
+<p>In order to find such a beast, we may have to employ some wholesome guess-and-check techniques.  The first step is to figure out or guess which type of variable is running the progress bar.  It almost definitely is NOT an ASCII string; it is very likely a number of some sort.  It could be an integer with a built-in range (say, <code>0</code> means no health and <code>100</code> means full health).  It could also be a floating point number with a range from <code>0.0</code> to <code>1.0</code>.  There are many other possibilities as well.  The only way to find out the variable type is to try one and see if you can find the variable.  If you can't then try another type.  In this case, I would probably try an integer search first.</p>
+
+<a name="5-3-1" />
+<p>There is still a problem, though.  We still don't know what value to search for!  As it turns out, The Cheat has support for searching with different operators.  <b>Operators</b> take two values and tell you different things depending upon the operator.  There are four operators: equal, not equal, less than, and greater than.</p>
+
+<p>The <b>equal</b> operator records a hit if the value in memory is equal to the search value.  You would use this search operator if you knew the value of the variable you were looking for.  The same is true for the <b>not equal</b> operator.  As you would expect, a hit is recorded each time the value in memory does not equal the search value.</p>
+
+<p>The other two operators are most helpful in finding variable of which we don't know the value.  The <b>less than</b> operator records a hit for every value in memory that is numerically less than the search value.  I trust you can figure out what the <b>greater than</b> operator does.  It is important to note that these operators compare the numerical value of variables.  An ASCII string does not have a numerical value and can therefore not be used with these operators.  Integers and floating points are fair game, however.</p>
+
+<p>Let's put these operators to good use in our hypothetical first-person shooter.  We have a health bar which is about half full (or half empty if you prefer).  We don't know what the value is, but we do know that whatever it is, it's probably greater than zero.  So we do a greater than search with the value <code>0</code>, and we get a couple hundred thousand results.</p>
+
+<p>Recall that in order to find the variable, the value needs to change.  So we go back to the game and pick up a first aid kit, and the health bar grows like it's supposed to.  Notice that we are faced with another problem.  We only know two things.  The first thing we know is that the value is still greater than zero, but that doesn't help us because most of the variables that our first search found are probably still positive, too.  The other thing we know is that whatever the value is, it is now greater than what is was when we first searched.  This leads us to another handy tool.</p>
+
+<a name="5-3-2" />
+<p>The Cheat has the ability to perform searches based on previous values.  Instead of providing a search value to compare against, just use <i>Last Value</i>.  In the first-person shooter example, do a "greater than last value" search and The Cheat will return the variables from our previous results which have increased since our last search.</p>
+
+<p>Now get back to the game and blow yourself up so the health bar shrinks.  You will now want to do a "less than last value" search.  Repeat in this fashion to narrow down your results.  That's all there is to it!  If we were not able to find the variable this way, remember that we could still try a floating point search.</p>
+
+<p>That's all there is to searching.  You should be able to find almost any variable using the techniques described in this section.  Keep in mind that some variables are a lot trickier than others.  If you are an impatient person, it's alright to consider cheating something similar to therapy.  Some variables will take a long time to find, but the reward is usually justification enough.</p>
+
+<p align="right"><a href="#0">top</a></p>
+
+<a name="6" />
+<div class="header">6. Changing Variables</div>
+
+<p>Once you have successfully searched and found a variable, the worst part is far, far behind you.  Changing variables hardly needs its own section; there really isn't much to it.  Basically you just provide the new value to give to the variable, and apply the cheat.  There are a few things related to changing variables which should be discussed, however.</p>
+
+
+<a name="6-1" />
+<p>Variables which are added to the variable list are presented in a table which displays the type of variable it is, its address, and the value which is to be given to the variable when you apply the cheat.  Managing these variables is fairly simple.  You can enable and disable them.  Disabled variables are not changed when the cheat is applied.  You can also copy and paste variables between sessions.  There is a batch edit command which lets you edit multiple variables at the same time.  Of course, you can also delete variables.</p>
+
+<a name="6-2" />
+<p>You can also save "cheat" files if you want to save variables for use later.  Be careful, however.  Variables are NOT guaranteed to have the same address all of the time.  Some variables always have the same address and some do not.  It is impossible to tell which variables will have changing addresses, so you should do multiple searches for that variable at different times to see if it moves.  The variable you originally found will NOT work if it has moved and has a different address.  If it does move, the only way to use that variable is to search for it again.</p>
+
+<p>If you do save a "cheat" to file, information about the program being cheated is also saved.  You can also change the title of the window and give a short description about the cheat if you wish.</p>
+
+<div class="tip">
+<span style="font-size: 14px; font-weight: bold;">Tip:</span> The Cheat is an expert tool.  It exists to provide you with the tools to find and cheat variables, but it will not prevent you from doing something stupid with the tools.  For example, The Cheat lets you change the address of a variable to anything you want, and The Cheat will do its best to apply the cheat, even if you enter something stupid like <code>0x00000000</code>.  That is a the NULL pointer, and nothing exists at that address.  The Cheat may crash if you do something like this.  This is not dangerous to your system at all, but it does require you, the user, to know what you're doing.
+</div>
+
+<a name="6-3" />
+<p>Finally, The Cheat can also apply cheats at specified time intervals.  This is useful when you want to keep a variable constant.  For example, in my first-person shooter, I could tell The Cheat to set the health at maximum every second.  This has effectively provided me with a God-mode.  Since multiple variables can be changed for the same cheat, I could also do the same thing for my ammunition.  Now I can't be killed, and I can't run out of bullets.  Now all you need is to find a variable that allows you to walk through locked doors, and you're set!</p>
+
+<p align="right"><a href="#0">top</a></p>
+
+<a name="7" />
+<div class="header">7. Menu Commands</div>
+       
+<p>This section includes descriptions of all the non-obvious menu items you'll see in The Cheat.</p>
+
+<a name="7-1" />
+<p><i><b>Cheater -> Cheat Properties&#8230 &#8984I</b></i> activates a sheet which allows you to change the title of the session window and the cheat description.  This menu item is only available if a cheat session is active.</p>
+
+<a name="7-2" />
+<p><i><b>Cheater -> Pause Target &#8984P</b></i> uses the kill command to halt execution of the program being cheated.  In theory, this is a great way to pause your game without switching back and forth between the game and The Cheat.  In reality, it is sometimes better just to use the game's built-in pause feature.</p>
+
+<div class="tip">
+<span style="font-size: 14px; font-weight: bold;">Tip:</span> If you ever need to resume a game without The Cheat, you can use this command in Terminal.app:<br /><br >
+<div align="center">kill -s SIGCONT <i>pid</i></div><br />     
+Where <i>pid</i> is the process identifier of the process you want to resume.
+</div>
+
+<a name="7-3" />
+<p><i><b>Cheater -> Clear Search &#8984&#9003</b></i> is a shortcut way to clear the current search.  You can use this command in either Search or Cheat Modes.  It accomplishes the same thing as pushing the Clear Search button on the session window.</p>
+
+<a name="7-4" />
+<p><i><b>Cheater -> Add New Variable</b></i> is a submenu which contains menu items which will add certain types of blank variables.  You can then edit the address and values of these new variables.  Most of the time you will find variables by searching for them.</p>
+
+<a name="7-5" />
+<p><i><b>Cheater -> Dump Memory</b></i> activates the memory dump tool which allows you to "dump" a program's memory to a file.  Once in file form, you can use your preferred file comparison tools and whatnot for some advanced cheating.</p>
+
+<a name="7-6" />
+<p><i><b>Cheater -> Edit Variables &#8984&#8617</b></i> provides you with a way to edit a batch of variables instead of just one at a time.</p>
+
+<a name="7-7" />
+<p><i><b>Cheater -> Show [...] Mode &#8984T</b></i> toggles the mode of the session window between Search and Cheat Mode.  Refer to the section on the <a href="#4">user interface</a> to learn more about these two modes.</p>
+
+<a name="7-8" />
+<p><i><b>Other Server&#8230 &#8984K</b></i> appears inside the server popup menu on session windows.  It activates a sheet which allows you to enter the address and port of a cheat server to connect to.</p>
+
+<p align="right"><a href="#0">top</a></p>
+
+<a name="8" />
+<div class="header">8. Customizing The Cheat</div>
+
+<p>The Cheat does support a certain level of customizability.  This section describes what can be changed.  All of these settings can be changed by choosing the <i>Preferences</i> menu item, which is in the usual place.</p>
+
+<a name="8-1" />
+<p>The general settings effect mostly user interface and behavioral issues.  By default, The Cheat shows a very brief fade effect while switching between Search and Cheat Mode.  You can choose to disable this.  You can also choose to make The Cheat's session windows stay on top of other windows on the screen.  Unfortunately, full-screen games will cover the entire screen regardless of this setting.</p>
+
+<p>By default, The Cheat will automatically switch to Cheat Mode whenever you add variables to be cheated.  You can change this setting.  You can also tell The Cheat not to automatically start editing variables that are added to the Cheat Mode table of variables.  The Cheat is also set up to prompt you to save cheat files, and you can turn this off.</p>
+
+<p>The settings which effect the search results table allow you to turn off value-updating so you will not see current values.  The Cheat will only show you what the value was during the last search.  You can also specify how often the values are refreshed.  Lastly, you can specify how many results to show in the table.  The Cheat will display the first results it gets up to that limit.</p>
+
+<div class="tip">
+<span style="font-size: 14px; font-weight: bold;">Tip:</span> These settings do NOT effect the actual search results, they only effect how the results are displayed to you.  The reason there is a limit of the number of results displayed is because some searches can return so many results that there are too many for the table to draw without considerable glitching.
+</div>
+
+<a name="8-2" />
+<p>The Update feature of The Cheat helps you keep track of new versions of The Cheat when they are made available.  You can check the availability of new updates and you can also tell The Cheat to automatically check this for you every time it starts up.</p>
+
+<p>The rest of the settings relate to the remote cheating feature, which is discussed in the <a href="9">next section</a>.</p>
+
+<p align="right"><a href="#0">top</a></p>
+
+<a name="9" />
+<div class="header">9. Remote Cheating</div>
+
+<p>It's the classic cheater's horror story: you want to cheat a certain game, but you soon realize that the game only has a full-screen mode.  Bad luck, mate.  Or is it?</p>
+
+<p>Well, it <i>is</i> possible to cheat games which won't allow you to switch out of full-screen.  The good news is that it's just as easy as cheating a windowed game, but you knew there was a catch didn't you?  Of course there is!  You do have to have two networked computers capable of running The Cheat.</p>
+
+<p>The feature is affectionately known as <b>remote cheating</b>, and if you're a cheater with at least two computers with The Cheat, remote cheating is your new best friend.</p>
+
+<a name="9-1" />
+<p>In order for remote cheating to work, The Cheat comes with a built-in <b>cheat server</b>.  It's like a web server, only it serves... cheats!  Okay, bad analogy.  The point is that the cheat server needs to be running in order to allow other computers on your network to connect.  The server is off by default, so you will need to turn it on from the <i>Server</i> pane on the <i>Preferences</i> window.</p>
+
+<p>The cheat server is very simple to manage.  All it needs to start is an available TCP port.  You can also specify a broadcast name to broadcast your cheat server using Rendezvous, but this is optional.  Once the server has started, others can connect to it by selecting its broadcast name from the server popup menu on the session window or by using <i><a href="#7-8">Other Server&#8230  &#8984K</a></i>.  Alternatively, you can also use the URL given to you when the server is started.</p>
+
+<a name="9-2" />
+<p>Once the server is started, you can see the connections which are made in the connection table.  It will show you the IP address which the client is connected through as well as how much data the client is transferring.  You can disconnect clients by selecting them in the table and pressing the delete key on the keyboard.</p>
+
+<div class="tip">
+<span style="font-size: 14px; font-weight: bold;">Tip:</span> Once you are done using remote cheating, you should turn off the cheat server from the <i>Preferences</i> window.  It will only take up more of your system resources, and you don't want anyone else to be able to connect without you knowing, if you are on a public network.
+</div>
+
+<a name="9-3" />
+<p>If you can't get the cheat server to start, the most likely problem is that you are trying to bind to a port that is already in use on your computer.  Try a different port to see if that works.  If it does then just keep using that port.  Sometimes you might also get an informational dialog that tells you that the server was started, but it could not be broadcast.  This is because the name you are using to broadcast as is already being used.  You will have to choose another name if you want to use broadcasting.</p>
+
+<p>If you are have trouble connecting to a server that is running, you may be having firewall issues.  Make sure that the firewall software you are using allows TCP traffic in both ways through the port used by the cheat server.  If you want to make sure the server is actually working properly, you can try connecting locally using this URL: <a href="cheat://localhost">cheat://localhost</a>.  If your server is running on a non-standard port, you would use cheat://localhost:PORT.  Be sure to substitute PORT with the actual port number your server is using.</p>
+
+<p>That's all there is to remote cheating.  If you have any special problems, be sure to check out the <a href="#1">additional help resources</a> in the first section of this document.</p>
+
+<p align="right"><a href="#0">top</a></p>
+
+<div align="center" style="font-size: 10px;">
+<i>The contents of this document are licensed under the Creative Commons - Attribution / Share Alike license.<br />
+<a href="http://creativecommons.org/licenses/by-sa/2.0/">http://creativecommons.org/licenses/by-sa/2.0/</a></i>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/HelpController.h b/HelpController.h
new file mode 100644 (file)
index 0000000..2b034e1
--- /dev/null
@@ -0,0 +1,32 @@
+
+// **********************************************************************
+// 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 <Cocoa/Cocoa.h>
+#import <WebKit/WebKit.h>
+#import "ChazLog.h"
+
+
+@interface HelpController : NSWindowController
+{
+       IBOutlet NSWindow               *helpWindow;
+       IBOutlet WebView                *webView;
+}
+
+@end
diff --git a/HelpController.m b/HelpController.m
new file mode 100644 (file)
index 0000000..b55d03f
--- /dev/null
@@ -0,0 +1,63 @@
+
+// **********************************************************************
+// 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 "HelpController.h"
+
+
+@implementation HelpController
+
+
+- (id)init
+{
+       return [super initWithWindowNibName:@"Help"];
+}
+
+- (void)windowDidLoad
+{
+       NSString *filepath = [[NSBundle mainBundle] pathForResource:@"Help" ofType:@"html"];
+       NSURL *url;
+       NSURLRequest *request;
+       
+       if ( !filepath ) {
+               return;
+       }
+       
+       url = [NSURL fileURLWithPath:filepath];
+       request = [NSURLRequest requestWithURL:url];
+       
+       [[webView mainFrame] loadRequest:request];
+       [helpWindow center];
+}
+
+
+- (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id<WebPolicyDecisionListener>)listener
+{
+       NSURL *url = [request URL];
+       
+       // open "http" and "mailto" links in a real browser or email client
+       if ( [[url scheme] isEqualToString:@"http"] || [[url scheme] isEqualToString:@"mailto"] ) {
+               [[NSWorkspace sharedWorkspace] openURL:url];
+               [listener ignore];
+       }
+       [listener use];
+}
+
+
+@end
similarity index 70%
rename from Info-The_Cheat.plist
rename to Info.plist
index 4f0df19642170b651b9ba7c61821ea3140e98822..21da35c7e5b67d386b65d586ea55ebcfd9283193 100644 (file)
                        <string>Cheat Document</string>
                        <key>CFBundleTypeOSTypes</key>
                        <array>
-                               <string>ThCh</string>
+                               <string>????</string>
                        </array>
                        <key>CFBundleTypeRole</key>
                        <string>Editor</string>
+                       <key>LSTypeIsPackage</key>
+                       <false/>
+                       <key>NSDocumentClass</key>
+                       <string>CheatDocument</string>
                </dict>
        </array>
        <key>CFBundleExecutable</key>
        <string>The Cheat</string>
        <key>CFBundleGetInfoString</key>
-       <string>The Cheat 1.1.2</string>
+       <string>The Cheat 1.2</string>
        <key>CFBundleIconFile</key>
        <string>icon.icns</string>
        <key>CFBundleIdentifier</key>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.1.2</string>
+       <string>1.2</string>
        <key>CFBundleSignature</key>
-       <string>ThCh</string>
+       <string>chÅ“t</string>
+       <key>CFBundleURLTypes</key>
+       <array>
+               <dict>
+                       <key>CFBundleURLName</key>
+                       <string>The Cheat</string>
+                       <key>CFBundleURLSchemes</key>
+                       <array>
+                               <string>cheat</string>
+                       </array>
+               </dict>
+       </array>
+       <key>CFBundleVersion</key>
+       <string>1.2</string>
+       <key>NSAppleScriptEnabled</key>
+       <string>YES</string>
        <key>NSMainNibFile</key>
        <string>MainMenu</string>
        <key>NSPrincipalClass</key>
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..d60c31a
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,340 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/ListenerDelegate.h b/ListenerDelegate.h
deleted file mode 100644 (file)
index 2253e66..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      ListenerDelegate.h
-// Created:   Wed Sep 24 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#import <Cocoa/Cocoa.h>
-
-
-@protocol ListenerDelegate
-
-- (void)listenerListeningWithSocket:(int)sock;
-- (void)listenerDisconnected;
-- (void)listenerError:(NSString *)error message:(NSString *)message;
-
-- (void)listenerReceivedNewConnection:(int)sock;
-
-@end
\ No newline at end of file
diff --git a/LocalCheater.h b/LocalCheater.h
new file mode 100644 (file)
index 0000000..c24fe97
--- /dev/null
@@ -0,0 +1,68 @@
+
+// **********************************************************************
+// 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 <Cocoa/Cocoa.h>
+
+#import "Cheater.h"
+
+#import "VMRegion.h"
+#import "ThreadedTask.h"
+
+#import "SearchContext.h"
+#import "DumpContext.h"
+
+
+@interface LocalCheater : Cheater
+{
+       NSMutableArray *_processes;
+       Process *_target;
+       
+       BOOL _isTargetPaused;
+       
+       ThreadedTask *_searchTask;
+       ThreadedTask *_dumpTask;
+       
+       NSMutableArray *_searchResults;
+       NSMutableArray *_savedResults;
+       unsigned _returnLimit;
+       
+       NSTimer *_cheatTimer;
+       NSArray *_cheatVariables;
+       
+       NSTimer *_watchTimer;
+       NSArray *_watchVariables;
+       NSRange _watchRange;
+       
+       BOOL _shouldCopy;
+}
+
+
+// copying vs references
+// ultimately, the client will need a separate copy
+// of whatever is passed back to it, but we can use
+// references instead of the delegate will make its
+// own copies (or not use anything directly).
+- (BOOL)shouldCopy;
+- (void)setShouldCopy:(BOOL)flag;
+
+
+@end
+
+
diff --git a/LocalCheater.m b/LocalCheater.m
new file mode 100644 (file)
index 0000000..9403806
--- /dev/null
@@ -0,0 +1,753 @@
+
+// **********************************************************************
+// 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 "LocalCheater.h"
+
+#include "cheat_global.h"
+
+
+// memory dump function
+int _MemoryDumpTask( ThreadedTask *task, unsigned iteration );
+
+
+@interface LocalCheater ( Private )
+
+// internal methods so they can be used throughout the class
+- (void)_clearSearch;
+- (BOOL)_pauseTarget; // returns TRUE for success
+- (BOOL)_resumeTarget; // returns TRUE for success
+// handling app launching/quitting
+- (void)_applicationLaunched:(NSNotification *)note;
+- (void)_applicationTerminated:(NSNotification *)note;
+// cheating
+- (unsigned)_doChange:(NSArray *)variables;
+- (void)_changeTimer:(NSTimer *)timer;
+// watch variables
+- (void)_doWatch;
+- (void)_watchTimer:(NSTimer *)timer;
+// tasks
+- (int)_memoryDumpTask:(ThreadedTask *)task iteration:(unsigned)iteration;
+
+@end
+
+
+@implementation LocalCheater
+
+
+- (id)init
+{
+       if ( self = [super init] ) {
+               NSNotificationCenter *nc= [[NSWorkspace sharedWorkspace] notificationCenter];
+               
+               // register for app launch/quit notifications
+               [nc addObserver:self selector:@selector(_applicationLaunched:) name:NSWorkspaceDidLaunchApplicationNotification object:nil];
+               [nc addObserver:self selector:@selector(_applicationTerminated:) name:NSWorkspaceDidTerminateApplicationNotification object:nil];
+               
+               _searchResults = [[NSMutableArray alloc] init];
+               _savedResults = [[NSMutableArray alloc] init];
+               _returnLimit = -1;
+       }
+       return self;
+}
+
+- (void)dealloc
+{
+       [(NSNotificationCenter *)[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
+       
+       // make sure the process isn't left paused
+       [self _resumeTarget];
+       
+       // release local objects
+       [_target release];
+       [self _clearSearch];
+       
+       // make sure everything is cancelled.
+       [_searchTask cancelAndRemoveDelegate];
+       [_dumpTask cancelAndRemoveDelegate];
+       [self stopChangingVariables];
+       [self stopWatchingVariables];
+       
+       [_searchTask release];
+       [_dumpTask release];
+       
+       [_processes release];
+       
+       [super dealloc];        
+}
+
+
+- (BOOL)shouldCopy
+{
+       return _shouldCopy;
+}
+
+- (void)setShouldCopy:(BOOL)flag
+{
+       _shouldCopy = flag;
+}
+
+
+- (NSString *)hostAddress
+{
+       //return @"127.0.0.1";
+       return @"this computer";
+}
+
+
+// #############################################################################
+#pragma mark Cheater Override
+// #############################################################################
+
+- (void)connect
+{
+       if ( !_isConnected ) {
+               _isConnected = YES;
+               // return as connected
+               [_delegate cheaterDidConnect:self];
+       }
+}
+
+- (void)disconnect
+{
+       if ( _isConnected ) {
+               [_searchTask cancelAndRemoveDelegate];
+               [_dumpTask cancelAndRemoveDelegate];
+               [self stopChangingVariables];
+               [self stopWatchingVariables];
+
+               _isConnected = NO;
+               // return as disconnected
+               //[_delegate cheaterDidDisconnect:self];
+       }
+}
+
+- (void)authenticateWithPassword:(NSString *)password
+{
+       // being a local cheater, authentication really isn't required.
+       // return succes every time.
+       _isAuthenticated = YES;
+       [_delegate cheaterAcceptedPassword:self];
+}
+
+
+- (void)getProcessList
+{
+       NSWorkspace *workspace = [NSWorkspace sharedWorkspace];
+       NSArray *launchedApps = [workspace launchedApplications];
+       unsigned i, len = [launchedApps count];
+       
+       if ( !_processes ) {
+               _processes = [[NSMutableArray alloc] initWithCapacity:len];
+       }
+       
+       // compile process array
+       for ( i = 0; i < len; i++ ) {
+               NSDictionary *application = [launchedApps objectAtIndex:i];
+               
+               // don't allow The Cheat to be cheated
+               if ( [[application objectForKey:@"NSApplicationBundleIdentifier"] isEqualToString:[[NSBundle mainBundle] bundleIdentifier]] ) {
+                       continue;
+               }
+               
+               Process *process = [[Process alloc] initWithName:[application objectForKey:@"NSApplicationName"]
+                                                                                                version:ApplicationVersion( [application objectForKey:@"NSApplicationPath"] )
+                                                                                                       icon:[workspace iconForFile:[application objectForKey:@"NSApplicationPath"]]
+                                                                                                        pid:[[application objectForKey:@"NSApplicationProcessIdentifier"] intValue]];
+               [_processes addObject:process];
+               [process release];
+       }
+       
+       // return process list
+       [_delegate cheater:self didFindProcesses:[NSArray arrayWithArray:_processes]];
+}
+
+
+- (void)setTarget:(Process *)target
+{
+       // unpause the current target if needed
+       [self resumeTarget];
+       // clear the search
+       [self clearSearch];
+       // set the new target
+       [_target release];
+       
+       if ( _shouldCopy ) {
+               _target = [target copy];
+               [_delegate cheater:self didSetTarget:[_target copy]];
+       }
+       else {
+               _target = [target retain];
+               [_delegate cheater:self didSetTarget:_target];
+       }
+}
+
+- (void)pauseTarget
+{
+       // attempt to pause the current target
+       if ( !_isTargetPaused && [self _pauseTarget] ) {
+               [_delegate cheaterPausedTarget:self];
+       }
+       else {
+               [_delegate cheater:self echo:@"This process cannot be paused."];
+       }
+}
+
+- (void)resumeTarget
+{
+       // attempt to resume the current target
+       if ( _isTargetPaused && [self _resumeTarget] ) {
+               [_delegate cheaterResumedTarget:self];
+       }
+       else {
+               [_delegate cheater:self echo:@"This process cannot be resumed."];
+       }
+}
+
+
+- (void)limitReturnedResults:(unsigned)limit
+{
+       _returnLimit = limit;
+}
+
+- (void)searchForVariable:(Variable *)var comparison:(TCSearchOperator)op
+{
+       SearchContext *context;
+       void *function;
+       
+       if ( _searchTask ) {
+               ChazLog( @"there is already a search task" );
+               return;
+       }
+       
+       if ( [_searchResults count] > 0 ) {
+               SearchContext *lastContext = [_searchResults lastObject];
+               if ( ([var type] == TCString) && ([lastContext->value valueSize] < [var valueSize]) ) {
+                       // string size not good
+                       [_delegate cheater:self didFailLastRequest:@"String is too long."];
+                       return;
+               }
+               context = [[SearchContext alloc] initWithLastContext:[_searchResults lastObject]  searchOperator:op value:var];
+       }
+       else {
+               context = [[SearchContext alloc] initWithPID:[_target pid] searchOperator:op value:var];
+       }
+       
+       function = [context iterationFunction];
+       if ( function ) {
+               _searchTask = [[ThreadedTask alloc] initWithFunction:function
+                                                                                                        context:context
+                                                                                                       delegate:self];
+               
+               if ( ![_searchTask run] ) {
+                       // task didn't run
+                       [_searchTask release];
+                       _searchTask = nil;
+                       [_delegate cheater:self didFailLastRequest:@"Internal error."];
+               }
+       }
+       else {
+               [_delegate cheater:self didFailLastRequest:@"Invalid search parameters."];
+       }
+       
+       [context release];
+}
+
+
+- (void)searchLastValuesComparison:(TCSearchOperator)op
+{
+       SearchContext *context;
+       void *function;
+       
+       if ( _searchTask ) {
+               ChazLog( @"there is already a search task" );
+               return;
+       }
+       
+       if ( [_searchResults count] > 0 ) {
+               context = [[SearchContext alloc] initWithLastContext:[_searchResults lastObject]  searchOperator:op];
+       }
+       else {
+               ChazLog( @"doing a searchLastValues search without previous results..." );
+               [_delegate cheater:self didFailLastRequest:@"Invalid search."];
+               return;
+       }
+       
+       function = [context iterationFunction];
+       if ( function ) {
+               _searchTask = [[ThreadedTask alloc] initWithFunction:function
+                                                                                                        context:context
+                                                                                                       delegate:self];
+               
+               if ( ![_searchTask run] ) {
+                       // task didn't run
+                       [_searchTask release];
+                       _searchTask = nil;
+                       [_delegate cheater:self didFailLastRequest:@"Internal error."];
+               }
+       }
+       else {
+               [_delegate cheater:self didFailLastRequest:@"Invalid search parameters."];
+       }
+       
+       [context release];
+}
+
+- (void)cancelSearch
+{
+       [_searchTask cancelWithoutWaiting];
+}
+
+- (void)clearSearch
+{
+       [self _clearSearch];
+       [_delegate cheaterDidClearSearch:self];
+}
+
+
+- (void)getMemoryDump
+{
+       if ( _dumpTask ) {
+               ChazLog( @"there is already a dump task" );
+               return;
+       }
+       
+       _dumpTask = [[ThreadedTask alloc] initWithFunction:_MemoryDumpTask
+                                                                                        context:[[[DumpContext alloc] initWithPID:[_target pid]] autorelease]
+                                                                                       delegate:self];
+       
+       if ( ![_dumpTask run] ) {
+               [_dumpTask release];
+               _dumpTask = nil;
+               [_delegate cheater:self didFailLastRequest:@"Internal error."];
+       }
+}
+
+int _MemoryDumpTask( ThreadedTask *task, unsigned iteration )
+{
+       DumpContext *context = [task context];
+       VMRegion region = VMNextRegionWithAttributes( context->process, context->lastRegion, VMREGION_READABLE );
+       
+       if ( VMRegionIsNotNull( region ) ) {
+               [context->dump appendData:VMRegionData( region )];
+               
+               context->lastRegion = region;
+               
+               // continue looping
+               return 1;
+       }
+       else {
+               // no more regions, exit
+               return 0;
+       }
+}
+
+- (void)cancelMemoryDump
+{
+       [_dumpTask cancelWithoutWaiting];
+}
+
+
+- (void)makeVariableChanges:(NSArray *)variables repeat:(BOOL)doRepeat interval:(NSTimeInterval)repeatInterval
+{
+       unsigned changes;
+       
+       [self stopChangingVariables];
+       
+       // repeat the changes if necessary
+       if ( doRepeat ) {
+               if ( _shouldCopy ) {
+                       _cheatVariables = [variables copy];
+               }
+               else {
+                       _cheatVariables = [variables retain];
+               }
+               _cheatTimer = [[NSTimer scheduledTimerWithTimeInterval:repeatInterval
+                                                                                                               target:self
+                                                                                                         selector:@selector(_changeTimer:)
+                                                                                                         userInfo:nil
+                                                                                                          repeats:YES] retain];
+               [[NSRunLoop currentRunLoop] addTimer:_cheatTimer forMode:NSEventTrackingRunLoopMode];
+               [[NSRunLoop currentRunLoop] addTimer:_cheatTimer forMode:NSModalPanelRunLoopMode];
+       }
+       
+       // change variables
+       changes = [self _doChange:variables];
+       [_delegate cheater:self didChangeVariables:changes];
+}
+
+- (void)stopChangingVariables
+{
+       if ( _cheatVariables ) {
+               [_cheatTimer invalidate];
+               [_cheatTimer release];
+               _cheatTimer = nil;
+               [_cheatVariables release];
+               _cheatVariables = nil;
+               
+               // report back to delegate
+               [_delegate cheaterDidStopChangingVariables:self];
+       }
+}
+
+
+- (void)undo
+{
+       SearchContext *searchContext;
+       TCArray variables;
+       TCArray values;
+       
+       if ( searchContext = [_searchResults lastObject] ) {
+               [_savedResults addObject:searchContext];
+               [_searchResults removeLastObject];
+               
+               [self stopWatchingVariables];
+
+               if ( searchContext = [_searchResults lastObject] ) {
+                       if ( _shouldCopy ) {
+                               variables = TCArrayCopyElements( searchContext->addresses, _returnLimit );
+                               values = TCArrayCopyElements( searchContext->values, _returnLimit );
+                       }
+                       else {
+                               variables = TCArrayCopyContainer( searchContext->addresses, _returnLimit );
+                               values = TCArrayCopyContainer( searchContext->values, _returnLimit );
+                       }
+                       
+                       [_delegate cheater:self didRevertToVariables:variables actualAmount:TCArrayElementCount( searchContext->addresses )];
+                       [_delegate cheater:self didFindValues:values];
+               }
+               
+               [_delegate cheaterDidUndo:self];
+       }
+}
+
+- (void)redo
+{
+       SearchContext *searchContext;
+       TCArray variables;
+       TCArray values;
+       
+       [self stopWatchingVariables];
+       
+       if ( searchContext = [_savedResults lastObject] ) {
+               [_searchResults addObject:searchContext];
+               [_savedResults removeLastObject];
+               
+               if ( _shouldCopy ) {
+                       variables = TCArrayCopyElements( searchContext->addresses, _returnLimit );
+                       values = TCArrayCopyElements( searchContext->values, _returnLimit );
+               }
+               else {
+                       variables = TCArrayCopyContainer( searchContext->addresses, _returnLimit );
+                       values = TCArrayCopyContainer( searchContext->values, _returnLimit );
+               }
+               
+               [_delegate cheater:self didRevertToVariables:variables actualAmount:TCArrayElementCount( searchContext->addresses )];
+               [_delegate cheater:self didFindValues:values];
+               [_delegate cheaterDidRedo:self];
+       }
+}
+
+
+- (void)watchVariablesAtIndex:(unsigned)index count:(unsigned)count interval:(NSTimeInterval)checkInterval
+{
+       SearchContext *context;
+       unsigned i, top;
+       
+       ChazLog( @"watchVariablesAtIndex:.." );
+       
+       [self stopWatchingVariables];
+       
+       if ( count == 0 ) {
+               ChazLog( @"invalid watch parameters: 0 count" );
+               return;
+       }
+       
+       if ( context = [_searchResults lastObject] ) {
+               TCArray addresses = context->addresses;
+               TCArray values = context->values;
+               // check the index & count
+               if ( index + count <= TCArrayElementCount( addresses ) ) {
+                       // save current values
+                       NSMutableArray *vars = [[NSMutableArray alloc] initWithCapacity:count];
+                       top = index + count;
+                       for ( i = index; i < top; i++ ) {
+                               Variable *var = [[Variable alloc] initWithType:[context variableType] integerSign:[context integerSign]];
+                               [var setAddress:*(TCAddress *)TCArrayElementAtIndex( addresses, i )];
+                               [var setValue:TCArrayElementAtIndex( values, i ) size:TCArrayElementSize(values)];
+                               [vars addObject:var];
+                               [var release];
+                       }
+                       _watchVariables = [[NSArray arrayWithArray:vars] retain];
+                       [vars release];
+                       
+                       _watchRange = NSMakeRange( index, count );
+                       _watchTimer = [[NSTimer scheduledTimerWithTimeInterval:checkInterval
+                                                                                                                       target:self
+                                                                                                                 selector:@selector(_watchTimer:)
+                                                                                                                 userInfo:nil
+                                                                                                                  repeats:YES] retain];
+                       [[NSRunLoop currentRunLoop] addTimer:_watchTimer forMode:NSEventTrackingRunLoopMode];
+                       [[NSRunLoop currentRunLoop] addTimer:_watchTimer forMode:NSModalPanelRunLoopMode];
+                       
+                       // do a watch check right now
+                       [self _doWatch];
+               }
+               else {
+                       ChazLog( @"invalid watch parameters" );
+               }
+       }
+}
+
+- (void)stopWatchingVariables
+{
+       if ( _watchVariables ) {
+               [_watchTimer invalidate];
+               [_watchTimer release];
+               _watchTimer = nil;
+               [_watchVariables release];
+               _watchVariables = nil;
+       }
+}
+
+
+// #############################################################################
+#pragma mark ThreadedTaskDelegate
+// #############################################################################
+
+- (void)threadedTaskFinished:(ThreadedTask *)theTask
+{
+       id context = [theTask context];
+       
+       [self stopWatchingVariables];
+       
+       ChazLog( @"threaded task finished" );
+       
+       if ( [context isKindOfClass:[SearchContext class]] ) {
+               SearchContext *searchContext = context;
+               TCArray variables;
+               TCArray values;
+               
+               if ( _shouldCopy ) {
+                       variables = TCArrayCopyElements( searchContext->addresses, _returnLimit );
+                       values = TCArrayCopyElements( searchContext->values, _returnLimit );
+               }
+               else {
+                       variables = TCArrayCopyContainer( searchContext->addresses, _returnLimit );
+                       values = TCArrayCopyContainer( searchContext->values, _returnLimit );
+               }
+               
+               [_searchResults addObject:searchContext];
+               [_searchTask release];
+               _searchTask = nil;
+               
+               [_delegate cheater:self didFindVariables:variables actualAmount:TCArrayElementCount( searchContext->addresses )];
+               [_delegate cheater:self didFindValues:values];
+       }
+       else if ( [context isKindOfClass:[DumpContext class]] ) {
+               DumpContext *dumpContext = context;
+               [_delegate cheater:self didDumpMemory:dumpContext->dump];
+               [_dumpTask release];
+               _dumpTask = nil;
+       }
+}
+
+- (void)threadedTaskCancelled:(ThreadedTask *)theTask
+{
+       id context = [theTask context];
+       ChazLog( @"threaded task cancelled" );
+       
+       if ( [context isKindOfClass:[SearchContext class]] ) {
+               [_delegate cheaterDidCancelSearch:self];
+               [_searchTask release];
+               _searchTask = nil;
+       }
+       else if ( [context isKindOfClass:[DumpContext class]] ) {
+               [_delegate cheaterDidCancelMemoryDump:self];
+               [_dumpTask release];
+               _dumpTask = nil;
+       }
+}
+
+- (void)threadedTask:(ThreadedTask *)theTask failedWithErrorCode:(int)errorCode
+{
+       id context = [theTask context];
+       ChazLog( @"threaded task failed with code: %i", errorCode );
+       
+       if ( [context isKindOfClass:[SearchContext class]] ) {
+               [_delegate cheater:self didFailLastRequest:[NSString stringWithFormat:@"Search failed with error: %i", errorCode]];
+               [_searchTask release];
+               _searchTask = nil;
+       }
+       else if ( [context isKindOfClass:[DumpContext class]] ) {
+               [_delegate cheater:self didFailLastRequest:[NSString stringWithFormat:@"Dump failed with error: %i", errorCode]];
+               [_dumpTask release];
+               _dumpTask = nil;
+       }
+}
+
+- (void)threadedTask:(ThreadedTask *)theTask reportedProgress:(int)theProgress
+{
+       [_delegate cheater:self didReportProgress:theProgress];
+}
+
+
+// #############################################################################
+#pragma mark Private Methods
+// #############################################################################
+
+- (void)_clearSearch
+{
+       [self stopWatchingVariables];
+       [self cancelSearch];
+       
+       // empty the results array
+       [_searchResults removeAllObjects];
+       [_savedResults removeAllObjects];
+}
+
+- (BOOL)_pauseTarget
+{
+       // attempt to pause
+       if ( VMStopProcess( [_target pid] ) ) {
+               _isTargetPaused = YES;
+               return YES;
+       }
+       _isTargetPaused = NO;
+       return NO;
+}
+
+- (BOOL)_resumeTarget
+{
+       if ( VMContinueProcess( [_target pid] ) ) {
+               _isTargetPaused = NO;
+               return YES;
+       }
+       _isTargetPaused = YES;
+       return NO;
+}
+
+
+- (void)_applicationLaunched:(NSNotification *)note
+{
+       NSWorkspace *workspace = [NSWorkspace sharedWorkspace];
+       NSDictionary *application = [note userInfo];
+       NSString *bundleID;
+
+       // don't allow The Cheat to be cheated
+       bundleID = [application objectForKey:@"NSApplicationBundleIdentifier"];
+       if ( bundleID && [bundleID isEqualToString:[[NSBundle mainBundle] bundleIdentifier]] ) {
+               return;
+       }
+       
+       Process *process = [[Process alloc] initWithName:[application objectForKey:@"NSApplicationName"]
+                                                                                        version:ApplicationVersion( [application objectForKey:@"NSApplicationPath"] )
+                                                                                               icon:[workspace iconForFile:[application objectForKey:@"NSApplicationPath"]]
+                                                                                                pid:[[application objectForKey:@"NSApplicationProcessIdentifier"] intValue]];
+       if ( ![_processes containsObject:process] ) {
+               [_processes addObject:process];
+               // inform the delegate of the new process
+               [_delegate cheater:self didAddProcess:process];
+       }
+       // cleanup
+       [process release];
+}
+
+- (void)_applicationTerminated:(NSNotification *)note
+{
+       NSWorkspace *workspace = [NSWorkspace sharedWorkspace];
+       NSDictionary *application = [note userInfo];
+       
+       Process *process = [[Process alloc] initWithName:[application objectForKey:@"NSApplicationName"]
+                                                                                        version:ApplicationVersion( [application objectForKey:@"NSApplicationPath"] )
+                                                                                               icon:[workspace iconForFile:[application objectForKey:@"NSApplicationPath"]]
+                                                                                                pid:[[application objectForKey:@"NSApplicationProcessIdentifier"] intValue]];
+       
+       // if this is the current process, take appropriate actions
+       if ( [_target isEqual:process] ) {
+               [self cancelSearch];
+               [self clearSearch];
+               [self cancelMemoryDump];
+               [self stopChangingVariables];
+               [_delegate cheater:self didRemoveProcess:process];
+               [_delegate cheater:self didFailLastRequest:@"The target quit."];
+       }
+       else {
+               // inform the delegate of the removed process
+               [_delegate cheater:self didRemoveProcess:process];
+       }
+       [_processes removeObject:process];
+       
+       // cleanup
+       [process release];
+}
+
+
+- (unsigned)_doChange:(NSArray *)variables
+{
+       unsigned i, top;
+       unsigned successes = 0;
+       
+       top = [variables count];
+       for ( i = 0; i < top; i++ ) {
+               Variable *variable = [variables objectAtIndex:i];
+               
+               if ( VMWriteBytes( [_target pid], [variable address], [variable value], [variable valueSize] ) ) {
+                       successes++;
+               }
+       }
+       return successes;
+}
+
+- (void)_changeTimer:(NSTimer *)timer
+{
+       unsigned changes = [self _doChange:_cheatVariables];
+       [_delegate cheater:self didChangeVariables:changes];
+}
+
+
+- (void)_doWatch
+{
+       unsigned i, top;
+       char value[TC_MAX_VAR_SIZE];
+       vm_size_t size;
+       
+       top = [_watchVariables count];
+       for ( i = 0; i < top; i++ ) {
+               Variable *variable = [_watchVariables objectAtIndex:i];
+               
+               size = [variable valueSize];
+               if ( VMReadBytes( [_target pid], [variable address], value, &size ) ) {
+                       // check if memory changed
+                       if ( memcmp( value, [variable value], size ) != 0 ) {
+                               [variable setValue:value];
+                               // inform delegate of the change
+                               [_delegate cheater:self variableAtIndex:_watchRange.location+i didChangeTo:variable];
+                       }
+               }
+       }
+}
+
+- (void)_watchTimer:(NSTimer *)timer
+{
+       [self _doWatch];
+}
+
+
+@end
diff --git a/Lock.tif b/Lock.tif
new file mode 100644 (file)
index 0000000..f6a68f6
Binary files /dev/null and b/Lock.tif differ
index 4f9f3a140304c8f220a960121555f671901b1992..9e570b7ec97cbb7fdc9c6ed9fa3be85574eedd1d 100644 (file)
@@ -1,21 +1,32 @@
 
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      MenuExtras.h
-// Created:   Wed Sep 17 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 <Cocoa/Cocoa.h>
 
 
-@interface NSMenu (MenuExtras)
+@interface NSMenu ( MenuExtras )
 
 - (void)removeItemWithTitle:(NSString *)title;
 - (void)removeAllItemsWithTitle:(NSString *)title;
 - (void)removeItemWithTag:(int)tag;
+- (void)removeItemWithRepresentedObject:(id)object;
 
 - (void)removeAllItems;
 
index d8af851d09603d6ce0719eaf51dc36b61e23f9b4..5b7305a8a6bbe815955b397198a6e0de3ef9719f 100644 (file)
@@ -1,17 +1,28 @@
 
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      MenuExtras.m
-// Created:   Wed Sep 17 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 "MenuExtras.h"
 
 
-@implementation NSMenu (MenuExtras)
+@implementation NSMenu ( MenuExtras )
+
 
 - (void)removeItemWithTitle:(NSString *)title
 {
        }
 }
 
+- (void)removeItemWithRepresentedObject:(id)object
+{
+       int                     i, top = [self numberOfItems];
+       
+       for ( i = 0; i < top; i++ )
+       {
+               if ( [[[self itemAtIndex:i] representedObject] isEqual:object] )
+               {
+                       [self removeItemAtIndex:i];
+                       break;
+               }
+       }
+}
+
 
 - (void)removeAllItems
 {
        }
 }
 
+
 @end
\ No newline at end of file
diff --git a/MySocket.h b/MySocket.h
new file mode 100644 (file)
index 0000000..20df4f1
--- /dev/null
@@ -0,0 +1,127 @@
+//
+//  MySocket.h
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 2/1/05.
+//  Copyright 2005 Chaz McGarvey. All rights reserved.
+//
+
+/*
+ * MySocket is my 24 hour hackjob.  There are other classes which would have
+ * done a better job, but I found them to be too slow.  This class wraps
+ * around BSD sockets directly.  It uses two threads for both asynchronous
+ * reads and writes.  Performance still isn't spectacular... I measure about
+ * 58 MB/s average when transfering to localhost.
+ * The way the old The Cheat did networking was by spawning a new thread for
+ * each connection (for both serving and receiving).  I thought that this way
+ * would be more efficient, but the old way is noticeably faster.  I may go
+ * back to that way eventually, after all it isn't that many threads.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import "ChazLog.h"
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h> 
+#include <netdb.h>
+#include <fcntl.h>
+
+#include <string.h>
+
+
+/*
+ * This class has a few limitations which may not be obvious.  First, it will
+ * only send back delegate methods on the Main thread, not necessarily the
+ * same thread used to create the socket.  There is no way to time out a read
+ * or write action.  There is no way to just read "all" data possible; you
+ * must specify how much data to receive.
+ */
+
+
+@interface MySocket : NSObject
+{
+       int _sockfd;
+       
+       NSMutableArray *_readQueue;
+       NSMutableArray *_writeQueue;
+       NSMutableData *_unclaimedData;
+       NSRecursiveLock *_readLock;
+       NSRecursiveLock *_writeLock;
+       
+       unsigned _flags;
+       unsigned _bytesRead;
+       unsigned _bytesWritten;
+       NSTimeInterval _startTime;
+       
+       unsigned _lastBytesRead;
+       unsigned _lastBytesWritten;
+       NSTimeInterval _lastBytesReadTime;
+       NSTimeInterval _lastBytesWrittenTime;
+       
+       id _delegate;
+}
+
+/* INITIALIZATION */
+- (id)initWithDelegate:(id)delegate;
+
+/* CONNECTING/ACCEPTING */
+- (BOOL)connectToHost:(NSString *)host port:(int)port;
+- (BOOL)connectToAddress:(const struct sockaddr *)addr length:(unsigned)addrLen;
+- (BOOL)connectToAddressWithData:(NSData *)addr;
+- (BOOL)listenOnPort:(int)port;
+// returns YES on success
+
+/* OBVIOUS */
+- (void)disconnect;
+// the disconnect delegate method will NOT be called.
+// it is only called when the socket is disconnect by remote or by error.
+// absolutely NO delegate methods are sent after this (until reconnecting).
+
+/* READING & WRITING */
+- (void)readDataToLength:(unsigned)len tag:(int)tag;
+- (void)writeData:(NSData *)data tag:(int)tag;
+- (void)writeBytes:(void const *)bytes length:(unsigned)len tag:(int)tag;
+/* Nope, there is no way to time out a request. */
+
+/* STATISTICS */
+- (unsigned)bytesRead;
+- (unsigned)bytesWritten;
+/* the above accessors can be accessed after the socket is disconnected to get
+   the grand total amount of traffic passed through the socket. */
+- (NSTimeInterval)timeConnected;
+- (double)readSpeed; // bytes/sec
+- (double)writeSpeed; // bytes/sec
+/* These speeds are averaged out using the last time these methods were called.
+   The more often you call these methods the more accurate they will be. */
+
+- (NSString *)localHost;
+- (int)localPort;
+- (NSString *)remoteHost;
+- (int)remotePort;
+
+- (BOOL)isConnected;
+- (BOOL)isListener;
+
+/* CONVENIENCE */
++ (NSData *)addressWithHost:(NSString *)host port:(int)port;
+
+/* DELEGATION */
+- (id)delegate;
+- (void)setDelegate:(id)delegate;
+
+@end
+
+
+@interface NSObject ( MySocketDelegate )
+
+/* DELEGATE METHODS */
+- (void)socketDidDisconnect:(MySocket *)mySocket;
+- (void)socket:(MySocket *)mySocket didAcceptSocket:(MySocket *)newSocket;
+- (void)socket:(MySocket *)mySocket didReadData:(NSData *)theData tag:(int)tag;
+- (void)socket:(MySocket *)mySocket didWriteDataWithTag:(int)tag;
+
+@end
\ No newline at end of file
diff --git a/MySocket.m b/MySocket.m
new file mode 100644 (file)
index 0000000..d040af6
--- /dev/null
@@ -0,0 +1,1106 @@
+//
+//  MySocket.m
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 2/1/05.
+//  Copyright 2005 Chaz McGarvey. All rights reserved.
+//
+
+#import "MySocket.h"
+
+
+// CONSTANTS
+
+// this is used to read in unclaimed data
+#define MYSOCKET_PACKETLEN (1024)
+
+enum {
+       kMySocketAddedToManager = 1,
+       kMySocketConnected = 2,
+       kMySocketIsListener = 4
+};
+
+
+struct _mySocketGlobals {
+       BOOL isManagerRunning;
+       NSMutableArray *sockets;
+       NSRecursiveLock *readLock;
+       NSRecursiveLock *writeLock;
+       int readPipe[2];
+       int writePipe[2];
+       int maxreadfd;
+       int maxwritefd;
+       fd_set readfds;
+       fd_set writefds;
+} _mySocketGlobals = { NO, nil, nil, nil, { -1, -1 }, { -1, -1 }, 0, 0 };
+
+
+// HELPER CLASSES
+
+@interface _MySocketPacket : NSObject
+{
+       NSData *_buffer;
+       unsigned _bytesHandled;
+       unsigned _bytesRequired;
+       int _tag;
+}
+
+- (id)initWithData:(NSData *)data tag:(int)tag;
+
+- (void *)bytes; // pointer to the current bytes; changes are bytes are handled
+- (unsigned)bytesRemaining;
+
+- (void)handledBytes:(unsigned)count;
+
+- (unsigned)bytesRequired;
+
+- (NSData *)data;
+- (int)tag;
+- (BOOL)isComplete;
+
+@end
+
+
+// PRIVATE STUFF
+
+@interface MySocket ( PrivateAPI )
+
+- (id)_initWithFileDescriptor:(int)sockfd;
+- (void)_connect;
+
+- (void)_addToManager;
+- (void)_removeFromManager;
+
++ (void)_readWithSockFD:(int)fd;
++ (void)_refreshReadThread;
++ (void)_writeWithSockFD:(int)fd;
++ (void)_refreshWriteThread;
+
++ (void)_lockRead;
++ (void)_unlockRead;
++ (void)_lockWrite;
++ (void)_unlockWrite;
++ (void)_lockReadAndWrite;
++ (void)_unlockReadAndWrite;
+
+/* #### MANAGER METHODS #### */
++ (void)_startManager;
++ (void)_readThread:(id)object;
++ (void)_writeThread:(id)object;
+
+- (int)_accept;
+- (int)_read;
+- (int)_write;
+
+- (void)_fillReadPacketsWithUnclaimedBytes;
+
+- (void)_handleReadQueue;
+- (void)_handleWriteQueue;
+
+- (void)_eventDidAcceptSocket:(MySocket *)newSocket;
+- (void)_eventDidDisconnect:(id)dummy;
+- (void)_eventDidReadData:(_MySocketPacket *)packet;
+- (void)_eventDidWriteData:(_MySocketPacket *)packet;
+
+// utility
+- (NSMutableData *)_readBufferWithLength:(unsigned *)len;
+
+// accessors
+- (int)_sockfd;
+
+@end
+
+
+
+@implementation MySocket
+
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark Initialization
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+- (id)initWithDelegate:(id)delegate
+{
+       if ( self = [super init] ) {
+               ChazLog( @"SOCKET CREATED" );
+               [self setDelegate:delegate];
+       }
+       return self;
+}
+
+- (void)dealloc
+{
+       ChazLog( @"SOCKET DESTROYED" );
+       [self disconnect];
+       [super dealloc];
+}
+
+
+- (void)release
+{
+       if ( [self retainCount] == 1 ) {
+               [self _removeFromManager];
+       }
+       
+       [super release];
+}
+
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark Connecting/Disconnecting
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+- (BOOL)connectToHost:(NSString *)host port:(int)port
+{
+       return [self connectToAddressWithData:[MySocket addressWithHost:host port:port]];
+}
+
+- (BOOL)connectToAddress:(const struct sockaddr *)addr length:(unsigned)addrLen
+{
+       int err = 0;
+       
+       if ( [self isConnected] ) {
+               return NO;
+       }
+       
+       _sockfd = socket( addr->sa_family, SOCK_STREAM, 0 );
+       if ( _sockfd == -1 ) {
+               // can't get file descriptor
+               return NO;
+       }
+       // make the socket NOT block
+       /*err = fcntl( _sockfd, F_SETFL, O_NONBLOCK );
+       if ( err == -1 ) {
+               // can't not block
+               close( _sockfd );
+               return NO;
+       }*/
+       err = connect( _sockfd, addr, addrLen );
+       if ( err == -1 ) {
+               // can't connect
+               close( _sockfd );
+               return NO;
+       }
+       
+       [self _connect];
+       return YES;
+}
+
+- (BOOL)connectToAddressWithData:(NSData *)addr
+{
+       return [self connectToAddress:[addr bytes] length:[addr length]];
+}
+
+- (BOOL)listenOnPort:(int)port
+{
+       struct sockaddr_in addr;
+       
+       int err = 0;
+       int yes = 1;
+       
+       if ( [self isConnected] ) {
+               return NO;
+       }
+       
+       _sockfd = socket( AF_INET, SOCK_STREAM, 0 );
+       if ( _sockfd == -1 ) {
+               // can't get file descriptor
+               return NO;
+       }
+       err = setsockopt( _sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes) );
+       if ( err == -1 ) {
+               // can't reuse address
+               close( _sockfd );
+               return NO;
+       }
+       
+       // pack the socket address structure
+       addr.sin_family = AF_INET;
+       addr.sin_port = htons( (short)port );
+       addr.sin_addr.s_addr = INADDR_ANY;
+       memset( &(addr.sin_zero), NULL, 8 );
+       
+       err = bind( _sockfd, (struct sockaddr *)(&addr), sizeof(addr) );
+       if ( err == -1 ) {
+               // can't bind to this address
+               close( _sockfd );
+               return NO;
+       }
+       
+       err = listen( _sockfd, 10 );
+       if ( err == -1 ) {
+               // can't listen on this address
+               close( _sockfd );
+               return NO;
+       }
+       
+       _flags |= kMySocketIsListener;
+       [self _connect];
+       return YES;
+}
+
+
+- (void)disconnect
+{
+       if ( !(_flags & kMySocketConnected) ) {
+               // not connected
+               return;
+       }
+       
+       [self _removeFromManager];
+       
+       close( _sockfd );
+       _sockfd = -1;
+       
+       [_readQueue release];
+       _readQueue = nil;
+       [_writeQueue release];
+       _writeQueue = nil;
+       [_readLock release];
+       _readLock = nil;
+       [_writeLock release];
+       _writeLock = nil;
+       
+       _startTime = 0.0;
+       
+       _flags = 0;
+}
+
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark Reading/Writing
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+- (void)readDataToLength:(unsigned)len tag:(int)tag
+{
+       _MySocketPacket *packet;
+       
+       if ( ![self isConnected] || [self isListener] || len == 0 ) {
+               // must be connected and have a valid length
+               return;
+       }
+       
+       // create a "read" packet
+       packet = [[_MySocketPacket alloc] initWithData:[NSMutableData dataWithLength:len] tag:tag];
+       //[packet handledBytes:0];
+       
+       // add the packet to the queue
+       [_readLock lock];
+       [_readQueue addObject:packet];
+       [packet release];
+       [_readLock unlock];
+       
+       // make sure the thread picks up the change
+       [MySocket _refreshReadThread];
+}
+
+
+- (void)writeData:(NSData *)data tag:(int)tag
+{
+       _MySocketPacket *packet;
+       BOOL alreadyWriting;
+       
+       if ( ![self isConnected] || [self isListener] ) {
+               // must be connected
+               return;
+       }
+       
+       // create a "write" packet
+       packet = [[_MySocketPacket alloc] initWithData:data tag:tag];
+       
+       [_writeLock lock];
+       alreadyWriting = [_writeQueue count] > 0;
+       [_writeQueue addObject:packet];
+       [packet release];
+       [_writeLock unlock];
+       
+       if ( !alreadyWriting ) {
+               // make the helper aware the socket has data to write
+               [MySocket _writeWithSockFD:_sockfd];
+       }
+}
+
+- (void)writeBytes:(void const *)bytes length:(unsigned)len tag:(int)tag
+{
+       [self writeData:[NSData dataWithBytes:bytes length:len] tag:tag];
+}
+
+
+// AsyncSocket compatibility
+- (void)readDataToLength:(CFIndex)length withTimeout:(NSTimeInterval)timeout tag:(long)tag
+{
+       [self readDataToLength:length tag:tag];
+}
+
+- (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag
+{
+       [self writeData:data tag:tag];
+}
+
+- (void)writeBytes:(void *)bytes length:(unsigned)len withTimeout:(NSTimeInterval)timeout tag:(long)tag
+{
+       [self writeBytes:bytes length:len tag:tag];
+}
+
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark Accesors
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+- (unsigned)bytesRead
+{
+       return _bytesRead;
+}
+
+- (unsigned)bytesWritten
+{
+       return _bytesWritten;
+}
+
+- (NSTimeInterval)timeConnected
+{
+       return CFAbsoluteTimeGetCurrent() - _startTime;
+}
+
+- (double)readSpeed
+{
+       double currentTime = CFAbsoluteTimeGetCurrent();
+       double speed = (double)( _bytesRead - _lastBytesRead ) / ( currentTime - _lastBytesReadTime );
+       _lastBytesRead = _bytesRead;
+       _lastBytesReadTime = currentTime;
+       return speed;
+}
+
+- (double)writeSpeed
+{
+       double currentTime = CFAbsoluteTimeGetCurrent();
+       double speed = (double)( _bytesWritten - _lastBytesWritten ) / ( currentTime - _lastBytesWrittenTime );
+       _lastBytesWritten = _bytesWritten;
+       _lastBytesWrittenTime = currentTime;
+       return speed;
+}
+
+
+- (NSString *)localHost
+{
+       char host[128];
+       int err;
+       
+       err = gethostname( host, sizeof(host) );
+       if ( err == -1 ) {
+               return @"";
+       }
+       return [NSString stringWithCString:host];
+}
+
+- (int)localPort
+{
+       return 0;
+}
+
+- (NSString *)remoteHost
+{
+       int err;
+       struct sockaddr_in addr;
+       int len = sizeof(addr);
+       
+       err = getpeername( _sockfd, (struct sockaddr *)(&addr), &len );
+       if ( err == -1 ) {
+               return @"Unknown";
+       }
+       return [NSString stringWithCString:inet_ntoa(addr.sin_addr)];
+}
+
+- (int)remotePort
+{
+       int err;
+       struct sockaddr_in addr;
+       int len = sizeof(addr);
+       
+       err = getpeername( _sockfd, (struct sockaddr *)(&addr), &len );
+       if ( err == -1 ) {
+               return -1;
+       }
+       return addr.sin_port;
+}
+
+
+- (BOOL)isConnected
+{
+       return _flags & kMySocketConnected;
+}
+
+- (BOOL)isListener
+{
+       return _flags & kMySocketIsListener;
+}
+
+
++ (NSData *)addressWithHost:(NSString *)host port:(int)port
+{
+       struct hostent *h;
+       struct sockaddr_in addr;
+       
+       // resolve the host
+       h = gethostbyname( [host lossyCString] );
+       if ( h == NULL ) {
+               // host not found
+               return nil;
+       }
+       
+       // pack the socket address structure
+       addr.sin_family = AF_INET;
+       addr.sin_port = htons( (short)port );
+       memcpy( &(addr.sin_addr), h->h_addr, sizeof(struct in_addr) );
+       memset( &(addr.sin_zero), NULL, 8 );
+       
+       return [NSData dataWithBytes:&addr length:sizeof(addr)];
+}
+
+
+- (id)delegate
+{
+       return _delegate;
+}
+
+- (void)setDelegate:(id)delegate
+{
+       _delegate = delegate;
+}
+
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark PrivateAPI
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+- (id)_initWithFileDescriptor:(int)sockfd
+{
+       if ( self = [super init] ) {
+               _sockfd = sockfd;
+               [self _connect];
+       }
+       return self;
+}
+
+- (void)_connect
+{
+       if ( ![self isListener] ) {
+               _readQueue = [[NSMutableArray alloc] init];
+               _writeQueue = [[NSMutableArray alloc] init];
+       }
+       
+       // create the locks
+       _readLock = [[NSRecursiveLock alloc] init];
+       _writeLock = [[NSRecursiveLock alloc] init];
+       
+       _startTime = _lastBytesReadTime = _lastBytesWrittenTime = CFAbsoluteTimeGetCurrent();
+       _bytesRead = _lastBytesRead = _bytesWritten = _lastBytesWritten = 0;
+       
+       _flags |= kMySocketConnected;
+       
+       [self _addToManager];
+}
+
+
+- (void)_addToManager
+{
+       if ( _flags & kMySocketAddedToManager ) {
+               // only add this socket once
+               return;
+       }
+       
+       // start the manager if it is not already started
+       [MySocket _startManager];
+       
+       [MySocket _lockReadAndWrite];
+       // add to global array of sockets
+       [_mySocketGlobals.sockets addObject:self];
+       [self release];
+       [MySocket _readWithSockFD:_sockfd];
+       [MySocket _unlockReadAndWrite];
+
+       // mark as added to manager
+       _flags |= kMySocketAddedToManager;
+}
+
+- (void)_removeFromManager
+{
+       if ( !(_flags & kMySocketAddedToManager) ) {
+               // only remove if it is added
+               return;
+       }
+       
+       [MySocket _lockReadAndWrite];
+       // remove from global array
+       [self retain];
+       ChazLog( @"REMOVING SOCKET AT INDEX %i", [_mySocketGlobals.sockets indexOfObject:self] );
+       [_mySocketGlobals.sockets removeObject:self];
+       FD_CLR( _sockfd, &_mySocketGlobals.readfds );
+       FD_CLR( _sockfd, &_mySocketGlobals.writefds );
+       [MySocket _unlockReadAndWrite];
+       
+       _flags ^= kMySocketAddedToManager;
+}
+
+
++ (void)_readWithSockFD:(int)fd
+{
+       [MySocket _lockRead];
+       FD_SET( fd, &_mySocketGlobals.readfds );
+       _mySocketGlobals.maxreadfd = MAX( _mySocketGlobals.maxreadfd, fd );
+       [MySocket _unlockRead];
+       // make sure the thread picks up the change
+       [MySocket _refreshReadThread];
+}
+
++ (void)_refreshReadThread
+{
+       char b = 'R';
+       write( _mySocketGlobals.readPipe[1], &b, sizeof(b) );
+}
+
++ (void)_writeWithSockFD:(int)fd
+{
+       [MySocket _lockWrite];
+       FD_SET( fd, &_mySocketGlobals.writefds );
+       _mySocketGlobals.maxwritefd = MAX( _mySocketGlobals.maxwritefd, fd );
+       [MySocket _unlockWrite];
+       [MySocket _refreshWriteThread];
+}
+
++ (void)_refreshWriteThread
+{
+       char b = 'R';
+       write( _mySocketGlobals.writePipe[1], &b, sizeof(b) );
+}
+
+
++ (void)_lockRead
+{
+       [_mySocketGlobals.readLock lock];
+}
+
++ (void)_unlockRead
+{
+       [_mySocketGlobals.readLock unlock];
+}
+
++ (void)_lockWrite
+{
+       [_mySocketGlobals.writeLock lock];
+}
+
++ (void)_unlockWrite
+{
+       [_mySocketGlobals.writeLock unlock];
+}
+
++ (void)_lockReadAndWrite
+{
+       [MySocket _lockRead];
+       [MySocket _lockWrite];
+}
+
++ (void)_unlockReadAndWrite
+{
+       [MySocket _unlockRead];
+       [MySocket _unlockWrite];
+}
+
+
++ (void)_startManager
+{
+       int err;
+       
+       if ( _mySocketGlobals.isManagerRunning ) {
+               return;
+       }
+       
+       ChazLog( @"MySocketHelper STARTING" );
+       
+       // zero the descriptor sets
+       FD_ZERO( &_mySocketGlobals.readfds );
+       FD_ZERO( &_mySocketGlobals.writefds );
+       
+       // create the read pipe
+       err = pipe( _mySocketGlobals.readPipe );
+       if ( err == -1 ) {
+               return;
+       }
+       FD_SET( _mySocketGlobals.readPipe[0], &_mySocketGlobals.readfds );
+       _mySocketGlobals.maxreadfd = _mySocketGlobals.readPipe[0];
+       // create the write pipe
+       err = pipe( _mySocketGlobals.writePipe );
+       if ( err == -1 ) {
+               close( _mySocketGlobals.readPipe[0] );
+               close( _mySocketGlobals.readPipe[1] );
+               return;
+       }
+       _mySocketGlobals.maxwritefd = _mySocketGlobals.writePipe[0];
+       
+       // create other global objects
+       _mySocketGlobals.sockets = [[NSMutableArray alloc] init];
+       _mySocketGlobals.readLock = [[NSRecursiveLock alloc] init];
+       _mySocketGlobals.writeLock = [[NSRecursiveLock alloc] init];
+       
+       // start the threads
+       [NSThread detachNewThreadSelector:@selector(_readThread:) toTarget:[MySocket class] withObject:nil];
+       [NSThread detachNewThreadSelector:@selector(_writeThread:) toTarget:[MySocket class] withObject:nil];
+       _mySocketGlobals.isManagerRunning = YES;
+}
+
++ (void)_readThread:(id)object
+{
+       BOOL breakLoop = NO;
+       fd_set readfds;
+       
+       do {
+               int err;
+               int i, top;
+               
+               // create the ever-so-important pool
+               NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+               
+               [MySocket _lockRead];
+               //FD_COPY( &_mySocketGlobals.readfds, &readfds );
+               readfds = _mySocketGlobals.readfds;
+               [MySocket _unlockRead];
+               
+               // find the sockets which need processing
+               err = select( _mySocketGlobals.maxreadfd+1, &readfds, NULL, NULL, NULL );
+               if ( err == -1 ) {
+                       // trouble, select() is having problems
+                       ChazLog( @"select() failed!, error: %s", strerror(errno) );
+                       goto DONE;
+               }
+               
+               // check the pipe
+               if ( FD_ISSET( _mySocketGlobals.readPipe[0], &readfds ) ) {
+                       char b;
+                       err = read( _mySocketGlobals.readPipe[0], &b, sizeof(b) );
+                       if ( err <= 0 ) {
+                               // our connection to the main thread was severed...
+                               // SELF DESTRUCT
+                               ChazLog( @"readPipe severed, exiting READ thread..." );
+                               breakLoop = YES;
+                               goto DONE;
+                       }
+               }
+               
+               // process the sockets
+               [MySocket _lockRead];
+               top = [_mySocketGlobals.sockets count];
+               for ( i = 0; i < top; i++ ) {
+                       MySocket *sock = [_mySocketGlobals.sockets objectAtIndex:i];
+                       int sockfd = [sock _sockfd];
+                       
+                       [sock _fillReadPacketsWithUnclaimedBytes];
+                       [sock _handleReadQueue];
+                       
+                       if ( FD_ISSET( sockfd, &readfds ) ) {
+                               if ( [sock isListener] ) {
+                                       // socket ready for accepting
+                                       err = [sock _accept];
+                               }
+                               else {
+                                       // socket ready for reading
+                                       err = [sock _read];
+                               }
+                               if ( err == -1 ) {
+                                       // action returne error, disconnect socket
+                                       [sock disconnect];
+                                       [sock performSelectorOnMainThread:@selector(_eventDidDisconnect:)
+                                                                                  withObject:nil waitUntilDone:NO];
+                                       top--;
+                               }
+                       }
+               }
+               [MySocket _unlockRead];
+               
+DONE:;
+               [pool release];
+       }
+       while ( !breakLoop );
+}
+
++ (void)_writeThread:(id)object
+{
+       BOOL breakLoop = NO;
+       fd_set pipefds;
+       fd_set readfds, writefds;
+       
+       FD_ZERO( &pipefds );
+       FD_SET( _mySocketGlobals.writePipe[0], &pipefds );
+       
+       do {
+               int err;
+               int i, top;
+               
+               // create the ever-so-important pool
+               NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+               
+               readfds = pipefds;
+               [MySocket _lockWrite];
+               //FD_COPY( &_mySocketGlobals.writefds, &writefds );
+               writefds = _mySocketGlobals.writefds;
+               [MySocket _unlockWrite];
+               
+               // find the sockets which need processing
+               err = select( _mySocketGlobals.maxwritefd+1, &readfds, &writefds, NULL, NULL );
+               if ( err == -1 ) {
+                       // trouble, select() is having problems
+                       ChazLog( @"select() failed!, error: %s", strerror(errno) );
+                       goto DONE;
+               }
+               
+               // check the pipe
+               if ( FD_ISSET( _mySocketGlobals.writePipe[0], &readfds ) ) {
+                       char b;
+                       err = read( _mySocketGlobals.writePipe[0], &b, sizeof(b) );
+                       if ( err <= 0 ) {
+                               // our connection to the main thread was severed...
+                               // SELF DESTRUCT
+                               ChazLog( @"writePipe severed" );
+                               breakLoop = YES;
+                               goto DONE;
+                       }
+               }
+               
+               // process the sockets
+               [MySocket _lockWrite];
+               top = [_mySocketGlobals.sockets count];
+               for ( i = 0; i < top; i++ ) {
+                       MySocket *sock = [_mySocketGlobals.sockets objectAtIndex:i];
+                       int sockfd = [sock _sockfd];
+                       
+                       if ( FD_ISSET( sockfd, &writefds ) ) {
+                               // socket ready for accepting
+                               err = [sock _write];
+                               if ( err == -1 ) {
+                                       // action returne error, disconnect socket
+                                       [sock disconnect];
+                                       [sock performSelectorOnMainThread:@selector(_eventDidDisconnect:)
+                                                                                  withObject:nil waitUntilDone:NO];
+                                       top--;
+                               }
+                       }
+               }
+               [MySocket _unlockWrite];
+               
+DONE:;
+               [pool release];
+       }
+       while ( !breakLoop );
+}
+
+
+- (int)_accept
+{
+       MySocket *newSocket;
+       int newsockfd;
+       struct sockaddr addr;
+       int addrlen = sizeof(addr);
+       
+       newsockfd = accept( _sockfd, &addr, &addrlen );
+       if ( newsockfd >= 0 ) {
+               // create a new MySocket
+               newSocket = [[MySocket alloc] _initWithFileDescriptor:newsockfd];
+               [newSocket setDelegate:_delegate];
+               
+               [self performSelectorOnMainThread:@selector(_eventDidAcceptSocket:)
+                                                          withObject:newSocket waitUntilDone:NO];
+       }
+       else {
+               return -1;
+       }
+       return 0;
+}
+
+- (int)_read
+{
+       _MySocketPacket *packet = nil;
+       int bytesRead;
+       
+       [_readLock lock];
+       if ( [_readQueue count] == 0 ) {
+               // no packets claiming anything, so just
+               // read into the unclaimed bytes buffer.
+               if ( !_unclaimedData ) {
+                       _unclaimedData = [[NSMutableData alloc] init];
+               }
+               int len = [_unclaimedData length];
+               [_unclaimedData increaseLengthBy:MYSOCKET_PACKETLEN];
+               bytesRead = recv( _sockfd, [_unclaimedData mutableBytes] + len, MYSOCKET_PACKETLEN, 0 );
+               [_unclaimedData setLength:len+bytesRead];
+       }
+       else {
+               packet = [_readQueue objectAtIndex:0];
+               bytesRead = recv( _sockfd, [packet bytes], [packet bytesRemaining], 0 );
+               [packet handledBytes:bytesRead];
+       }
+       [_readLock unlock];
+       
+       if ( bytesRead > 0 ) {
+               // update total bytes read
+               _bytesRead += bytesRead;
+               
+               [self _handleReadQueue];
+       }
+       else {
+               // remove this socket
+               ChazLog( @"MySocket disconnecting: %i", bytesRead );
+               return -1;
+       }
+       return 0;
+}
+
+- (int)_write
+{
+       _MySocketPacket *packet = nil;
+       int bytesWritten = 0;
+       
+       [_writeLock lock];
+       if ( [_writeQueue count] > 0 ) {
+               int buflen = 0;
+               int len = sizeof(buflen);
+               int err;
+               err = getsockopt( _sockfd, SOL_SOCKET, SO_SNDBUF, &buflen, &len );
+               // write data
+               packet = [_writeQueue objectAtIndex:0];
+               bytesWritten = send( _sockfd, [packet bytes], MIN([packet bytesRemaining],buflen/2), 0 ); //MIN(4096,[packet bytesRemaining]), 0 );
+               [packet handledBytes:bytesWritten];
+       }
+       [_writeLock unlock];
+       
+       if ( bytesWritten >= 0 ) {
+               // update total bytes read
+               _bytesWritten += bytesWritten;
+               
+               [self _handleWriteQueue];
+       }
+       else {
+               return -1;
+       }
+       return 0;
+}
+
+
+- (void)_fillReadPacketsWithUnclaimedBytes
+{
+       int i, top;
+       void *bytes;
+       int total;
+       
+       total = [_unclaimedData length];
+       if ( total == 0 ) {
+               return;
+       }
+       bytes = [_unclaimedData mutableBytes];
+       
+       [_readLock lock];
+       top = [_readQueue count];
+       for ( i = 0; i < top; i++ ) {
+               _MySocketPacket *packet = [_readQueue objectAtIndex:i];
+               int len = MIN( total, [packet bytesRemaining] );
+               
+               if ( len > 0 ) {
+                       memcpy( [packet bytes], bytes, len );
+                       [packet handledBytes:len];
+                       bytes += len;
+                       total -= len;
+               }
+               if ( total == 0 ) {
+                       break;
+               }
+       }
+       [_unclaimedData replaceBytesInRange:NSMakeRange(0,[_unclaimedData length]-total) withBytes:NULL length:0];
+       [_readLock unlock];
+}
+
+
+- (void)_handleReadQueue
+{
+       int i, top;
+       
+       [_readLock lock];
+       top = [_readQueue count];
+       for ( i = 0; i < top; ) {
+               _MySocketPacket *packet = [_readQueue objectAtIndex:0];
+               if ( [packet isComplete] ) {
+                       [self performSelectorOnMainThread:@selector(_eventDidReadData:)
+                                                                  withObject:[packet retain] waitUntilDone:NO];
+                       [_readQueue removeObjectAtIndex:i];
+                       top--;
+               }
+               else {
+                       i++;
+               }
+       }
+       [_readLock unlock];
+}
+
+- (void)_handleWriteQueue
+{
+       int i, top;
+       
+       [_writeLock lock];
+       top = [_writeQueue count];
+       for ( i = 0; i < top; ) {
+               _MySocketPacket *packet = [_writeQueue objectAtIndex:0];
+               if ( [packet isComplete] ) {
+                       [self performSelectorOnMainThread:@selector(_eventDidWriteData:)
+                                                                  withObject:[packet retain] waitUntilDone:NO];
+                       [_writeQueue removeObjectAtIndex:i];
+                       top--;
+               }
+               else {
+                       i++;
+               }
+       }
+       if ( [_writeQueue count] == 0 ) {
+               // no more pending writes
+               FD_CLR( _sockfd, &_mySocketGlobals.writefds );
+       }
+       [_writeLock unlock];
+}
+
+
+- (void)_eventDidAcceptSocket:(MySocket *)newSocket
+{
+       // just report the event back to the delegate
+       if ( [_delegate respondsToSelector:@selector(socket:didAcceptSocket:)] ) {
+               [_delegate socket:self didAcceptSocket:newSocket];
+       }
+       
+       // release the parameter(s)
+       // they were not released by the caller because the caller is in another thread.
+       [newSocket release];
+}
+
+- (void)_eventDidDisconnect:(id)dummy
+{
+       [self disconnect];
+       if ( [_delegate respondsToSelector:@selector(socketDidDisconnect:)] ) {
+               [_delegate socketDidDisconnect:self];
+       }
+}
+
+- (void)_eventDidReadData:(_MySocketPacket *)packet
+{
+       if ( [_delegate respondsToSelector:@selector(socket:didReadData:tag:)] ) {
+               [_delegate socket:self didReadData:[packet data] tag:[packet tag]];
+       }
+       
+       [packet release];
+}
+
+- (void)_eventDidWriteData:(_MySocketPacket *)packet
+{
+       if ( [_delegate respondsToSelector:@selector(socket:didWriteDataWithTag:)] ) {
+               [_delegate socket:self didWriteDataWithTag:[packet tag]];
+       }
+       
+       [packet release];
+}
+
+
+- (NSMutableData *)_readBufferWithLength:(unsigned *)len
+{
+       NSMutableData *buffer;
+       unsigned packetLen = *len;
+       
+       if ( buffer = _unclaimedData ) {
+               // claim the bytes
+               int unclaimedLen = [_unclaimedData length];
+               if ( unclaimedLen > packetLen ) {
+                       *len = packetLen;
+                       _unclaimedData = [[NSMutableData alloc] initWithBytes:[buffer bytes]+packetLen length:unclaimedLen-packetLen];
+                               //[[buffer subdataWithRange:NSMakeRange(packetLen,unclaimedLen-packetLen)] retain];
+               }
+               else {
+                       *len = unclaimedLen;
+                       _unclaimedData = nil;
+               }
+               [buffer setLength:packetLen];
+       }
+       else {
+               buffer = [[NSMutableData alloc] initWithLength:packetLen];
+               *len = 0;
+       }
+       return [buffer autorelease];
+}
+
+
+- (int)_sockfd
+{
+       return _sockfd;
+}
+
+
+@end
+
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark _MySocketPacket
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+@implementation _MySocketPacket
+
+
+- (id)initWithData:(NSData *)data tag:(int)tag
+{
+       if ( self = [super init] ) {
+               _buffer = [data retain];
+               _bytesRequired = [data length];
+               _tag = tag;
+       }
+       return self;
+}
+
+- (void)dealloc
+{
+       [_buffer release];
+       [super dealloc];
+}
+
+
+- (void *)bytes
+{
+       return (void *)[_buffer bytes] + _bytesHandled;
+}
+
+- (unsigned)bytesRemaining
+{
+       return _bytesRequired - _bytesHandled;
+}
+
+
+- (void)handledBytes:(unsigned)count
+{
+       _bytesHandled += count;
+}
+
+- (unsigned)bytesRequired
+{
+       return _bytesRequired;
+}
+
+
+- (NSData *)data
+{
+       return _buffer;
+}
+
+- (int)tag
+{
+       return _tag;
+}
+
+- (BOOL)isComplete
+{
+       return [self bytesRemaining] == 0;
+}
+
+
+
+@end
diff --git a/NOTICE b/NOTICE
new file mode 100644 (file)
index 0000000..7e0f2c4
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,39 @@
+
+
+The Cheat Notice File
+Chaz McGarvey
+October 4, 2004
+
+
+The state of the source code--
+
+The source code for The Cheat has been worked on by one person (me) for a long
+time.  I'm making this project open source now, but it needs a lot of work
+still.  My style of programming is such that I jump around a lot and work on a
+lot of different parts of the code at any given time.  Therefore, the vast
+majority of the source files are incomplete.  In short, the code is basically a
+disaster at first glance.  As I get free time I will continue to work on this
+project.  When the code is ready for a new release, it will be more useful. 
+Nevertheless, if there's something useful to you help yourself as long as your
+intentions are compatible with the GPL license (provided; see file LICENSE).  If
+you'd like to help with this project, go right ahead.  You certainly don't need
+my permission.
+
+The code should be in a compilable state unedited, but the resulting binary
+would only be useful in showing the interface I had in mind for the next
+release.  It's mostly non-functional.
+
+The complete Xcode project is included.  That's what I use.  I really don't know
+if The Cheat will compile under CodeWarrior or not.  My intentions are to keep
+The Cheat Mac OS X 10.2 (Jaguar) compatible.  I have thus far resisted the
+temptation to use any new methods or bindings (I hope).
+
+Included with this project are also a few personal classes I've written
+(StatusTextField, DeleteTableView, CMVersionCheck, etc) and also CMLog (a simple
+NSLog wrapper that allows logging to be toggled on/off).  While not really part
+of The Cheat project, I have used them in The Cheat so I went ahead and GPL'd
+those classes, too.  Some of the classes included in this project were released
+under a BSD-like license (ThreadedTask, MemoryAccessor, MemoryRegion).  Just
+FYI.
+
+Well that's basically it.  I hope something useful can become of this.
diff --git a/NetTrafficController.h b/NetTrafficController.h
deleted file mode 100644 (file)
index d356904..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      NetTrafficController.h
-// Created:   Wed Sep 24 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#import <Cocoa/Cocoa.h>
-#import <Chaz/Chaz.h>
-
-#import "NetTrafficControlling.h"
-
-#include "cheat_globals.h"
-
-
-@interface NetTrafficController : NSWindowController
-{
-       id                              delegate;
-       
-       IBOutlet id             netTrafficWindow;
-       IBOutlet id             broadcastNameText;
-       IBOutlet id             listenPortText;
-       IBOutlet id             serverListTable;
-       IBOutlet id             connectionCountText;
-       IBOutlet id             killConnectionButton;
-}
-
-- (id)initWithDelegate:(id)del;
-
-- (void)initialInterfaceSetup;
-- (void)interfaceUpdate;
-
-- (void)serverSetAllowRemote:(BOOL)allow listenPort:(int)port broadcastName:(NSString *)name;
-
-/*
-- (void)allowRemoteChanged:(BOOL)allow;
-- (void)listenPortChanged:(int)port;
-- (void)broadcastNameChanged:(NSString *)name;
-*/
-
-- (void)connectionListChanged;
-
-- (void)setConnectionCount:(int)count;
-
-- (IBAction)killConnectionButton:(id)sender;
-
-@end
\ No newline at end of file
diff --git a/NetTrafficController.m b/NetTrafficController.m
deleted file mode 100644 (file)
index f57e02e..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      NetTrafficController.m
-// Created:   Wed Sep 24 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#import "NetTrafficController.h"
-
-#import "CheatServer.h"
-
-#import "ServerHolder.h"
-
-
-@implementation NetTrafficController
-
-
-- (id)initWithDelegate:(id)del
-{
-       if ( self = [super initWithWindowNibName:@"NetTraffic"] )
-       {
-               [self setWindowFrameAutosaveName:@"TCNetTrafficWindowPosition"];
-               
-               delegate = del;
-       }
-
-       return self;
-}
-
-- (void)windowDidLoad
-{
-       [self initialInterfaceSetup];
-       [self interfaceUpdate];
-}
-
-
-- (void)initialInterfaceSetup
-{
-       //[netTrafficWindow setResizeIncrements:NSMakeSize( 1.0, 17.0 )];
-       
-       [self serverSetAllowRemote:TCGlobalAllowRemote listenPort:TCGlobalListenPort broadcastName:TCGlobalBroadcastName];
-       //[self allowRemoteChanged:TCGlobalAllowRemote];
-       //[self listenPortChanged:TCGlobalListenPort];
-       [self setConnectionCount:[delegate netTrafficConnectionCount]];
-       [serverListTable reloadData];
-}
-
-- (void)interfaceUpdate
-{
-       NSArray                         *array = [[serverListTable selectedRowEnumerator] allObjects];
-       
-       if ( [array count] == 0 )
-       {
-               [killConnectionButton setEnabled:NO];
-       }
-       else
-       {
-               [killConnectionButton setEnabled:YES];
-               
-               if ( [array count] > 1 )
-               {
-                       [killConnectionButton setTitle:@"Kill Connections"];
-               }
-               else
-               {
-                       [killConnectionButton setTitle:@"Kill Connection"];
-               }
-       }
-}
-
-
-- (void)serverSetAllowRemote:(BOOL)allow listenPort:(int)port broadcastName:(NSString *)name
-{
-       if ( allow )
-       {
-               [listenPortText setStringValue:[NSString stringWithFormat:@"Listening on port %i.", port]];
-               [broadcastNameText setStringValue:[NSString stringWithFormat:@"Broadcasting service as \"%@.\"", name]];
-       }
-       else
-       {
-               [broadcastNameText setStringValue:@"Not accepting new connections from remote clients."];
-               [listenPortText setStringValue:@"Listening for local connections only."];
-       }
-}
-
-
-/*
-- (void)allowRemoteChanged:(BOOL)allow
-{
-       if ( allow )
-       {
-               [self broadcastNameChanged:TCGlobalBroadcastName];
-               [self listenPortChanged:TCGlobalListenPort];
-       }
-       else
-       {
-               [broadcastNameText setStringValue:@"Not accepting new connections from remote clients."];
-               [listenPortText setStringValue:@"Listening for local connections only."];
-       }
-}
-
-- (void)listenPortChanged:(int)port
-{
-       if ( TCGlobalAllowRemote )
-       {
-               [listenPortText setStringValue:[NSString stringWithFormat:@"Listening on port %i.", port]];
-       }
-}
-
-- (void)broadcastNameChanged:(NSString *)name
-{
-       if ( TCGlobalAllowRemote )
-       {
-               [broadcastNameText setStringValue:[NSString stringWithFormat:@"Broadcasting service as \"%@.\"", name]];
-       }
-}
-*/
-
-
-- (void)connectionListChanged
-{
-       [self setConnectionCount:[delegate netTrafficConnectionCount]];
-       [serverListTable reloadData];
-}
-
-
-- (void)setConnectionCount:(int)count
-{
-       [connectionCountText setStringValue:[NSString stringWithFormat:@"Now serving %i clients.", count]];
-}
-
-
-- (IBAction)killConnectionButton:(id)sender
-{
-       NSArray                         *array = [[serverListTable selectedRowEnumerator] allObjects];
-       int                                     i;
-       
-       for ( i = [array count] - 1; i >= 0; i-- )
-       {
-               [delegate netTrafficKillConnection:[(NSNumber *)[array objectAtIndex:i] intValue]];
-       }
-}
-
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%   NSTableView Data Source/Delegate
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-- (int)numberOfRowsInTableView:(NSTableView *)table
-{
-       return [delegate netTrafficConnectionCount];
-}
-
-- (id)tableView:(NSTableView *)table objectValueForTableColumn:(NSTableColumn *)column row:(int)row
-{
-       ServerHolder            *holder = [[delegate netTrafficConnectionList] objectAtIndex:row];
-       
-       if ( [[column identifier] isEqualToString:@"IP Address"] )
-       {
-               return [holder address];
-       }
-       else if ( [[column identifier] isEqualToString:@"Current Action"] )
-       {
-               return [holder action];
-       }
-
-       return @"Unknown";
-}
-
-- (void)tableView:(NSTableView *) setObjectValue:(id)object forTableColumn:(NSTableColumn *)column row:(int)row
-{
-       return;
-}
-
-- (void)tableViewSelectionDidChange:(NSNotification *)note
-{
-       [self interfaceUpdate];
-}
-
-
-@end
\ No newline at end of file
diff --git a/NetTrafficControlling.h b/NetTrafficControlling.h
deleted file mode 100644 (file)
index 2cd3d9c..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      NetTrafficControlling.h
-// Created:   Wed Sep 24 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#import <Cocoa/Cocoa.h>
-
-
-@protocol NetTrafficControlling
-
-- (int)netTrafficConnectionCount;
-- (NSArray *)netTrafficConnectionList;
-
-- (void)netTrafficKillConnection:(int)index;
-
-@end
\ No newline at end of file
index 6b42051cadca7506771065c58247a392809ca67c..44675aa855732beac037e1b81773edddffd45a54 100644 (file)
@@ -1,46 +1,44 @@
 
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      PreferenceController.h
-// Created:   Wed Sep 24 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 <Cocoa/Cocoa.h>
-#import <Chaz/Chaz.h>
+#import "ChazLog.h"
 
-#import "PreferenceControlling.h"
-
-#include "cheat_globals.h"
+#include "cheat_global.h"
 
 
 @interface PreferenceController : NSWindowController
 {
-       id                              delegate;
+       NSToolbar               *_toolbar;
        
-       IBOutlet id             prefsWindow;
-       IBOutlet id             playSoundsButton;
-       IBOutlet id             windowsOnTopButton;
-       IBOutlet id             updateAutomaticallyButton;
-       IBOutlet id             allowRemoteButton;
-       IBOutlet id             broadcastNameTextField;
-       IBOutlet id             listenPortTextField;
-       IBOutlet id             hitsDisplayedTextField;
+       NSView                  *_contentView;
+       IBOutlet NSView *ibGeneralView;
+       IBOutlet NSView *ibServerView;
+       IBOutlet NSView *ibUpdateCheckView;
 }
 
-- (id)initWithDelegate:(id)del;
+- (void)chooseGeneral:(id)object;
+- (void)chooseServer:(id)object;
+- (void)chooseUpdate:(id)object;
+- (void)switchToView:(NSView *)view;
 
 - (void)initialInterfaceSetup;
-- (void)interfaceUpdate;
-
-- (IBAction)change:(id)sender;
-
-- (IBAction)revert:(id)sender;
-- (IBAction)apply:(id)sender;
-
-- (IBAction)cancel:(id)sender;
-- (IBAction)save:(id)sender;
 
 @end
\ No newline at end of file
index 7c0ec13ad805aa28f2954f3466a092004a60f43d..f8f2cbadc1ca9f5a5618411df79c377d6f195551 100644 (file)
@@ -1,12 +1,22 @@
 
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      PreferenceController.m
-// Created:   Wed Sep 24 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 "PreferenceController.h"
 
 @implementation PreferenceController
 
 
-- (id)initWithDelegate:(id)del
+- (id)init
 {
        if ( self = [super initWithWindowNibName:@"Preferences"] )
        {
                [self setWindowFrameAutosaveName:@"TCPreferencWindowPosition"];
-               
-               delegate = del;
        }
-
        return self;
 }
 
+- (void)dealloc
+{
+       [_toolbar release];
+       [_contentView release];
+       [super dealloc];
+}
+
+
 - (void)windowDidLoad
 {
+       _toolbar = [[NSToolbar alloc] initWithIdentifier:@"TCPreferencesToolbar"];
+       [_toolbar setDelegate:self];
+       [_toolbar setVisible:YES];
+       [[self window] setToolbar:_toolbar];
+       
+       _contentView = [[[self window] contentView] retain];
+       
        [self initialInterfaceSetup];
 }
 
 
 - (void)initialInterfaceSetup
 {
-       [playSoundsButton setState:(TCGlobalPlaySounds)? NSOnState:NSOffState];
-       [windowsOnTopButton setState:(TCGlobalWindowsOnTop)? NSOnState:NSOffState];
-       [updateAutomaticallyButton setState:(TCGlobalUpdateCheck)? NSOnState:NSOffState];
-       [allowRemoteButton setState:(TCGlobalAllowRemote)? NSOnState:NSOffState];
-       [listenPortTextField setIntValue:TCGlobalListenPort];
-       [broadcastNameTextField setStringValue:[[NSUserDefaults standardUserDefaults] objectForKey:TCBroadcastNamePref]];
-       [hitsDisplayedTextField setIntValue:TCGlobalHitsDisplayed];
-       
-       [self interfaceUpdate];
+       [self chooseGeneral:self];
 }
 
-- (void)interfaceUpdate
+
+- (void)chooseGeneral:(id)object
 {
-       if ( [allowRemoteButton state] )
-       {
-               [listenPortTextField setEnabled:YES];
-               [broadcastNameTextField setEnabled:YES];
-       }
-       else
-       {
-               [listenPortTextField setEnabled:NO];
-               [broadcastNameTextField setEnabled:NO];
+       NSWindow *window = [self window];
+       [self switchToView:ibGeneralView];
+       [window setTitle:@"General"];
+       if ( MacOSXVersion() >= 0x1030 ) {
+               [_toolbar setSelectedItemIdentifier:@"General"];
        }
 }
 
-
-- (IBAction)change:(id)sender
+- (void)chooseServer:(id)object
 {
-       [self interfaceUpdate];
+       NSWindow *window = [self window];
+       [self switchToView:ibServerView];
+       [window setTitle:@"Server"];
+       if ( MacOSXVersion() >= 0x1030 ) {
+               [_toolbar setSelectedItemIdentifier:@"Server"];
+       }
 }
 
-
-- (IBAction)revert:(id)sender
+- (void)chooseUpdate:(id)object
 {
-       [self initialInterfaceSetup];
+       NSWindow *window = [self window];
+       [self switchToView:ibUpdateCheckView];
+       [window setTitle:@"Update Check"];
+       if ( MacOSXVersion() >= 0x1030 ) {
+               [_toolbar setSelectedItemIdentifier:@"Update Check"];
+       }
 }
 
-- (IBAction)apply:(id)sender
+- (void)switchToView:(NSView *)view
 {
-       TCGlobalPlaySounds = [playSoundsButton state];
-       [[NSUserDefaults standardUserDefaults] setBool:TCGlobalPlaySounds forKey:TCPlaySoundsPref];
-       
-       // send window information to the delegate so the necessary adjustments can be made
-       [delegate preferenceSetWindowsOnTop:[windowsOnTopButton state]];
+       NSWindow *window = [self window];
+       NSRect frame = [window frame];
+       float xdif, ydif;
        
-       TCGlobalWindowsOnTop = [windowsOnTopButton state];
-       [[NSUserDefaults standardUserDefaults] setBool:TCGlobalWindowsOnTop forKey:TCWindowsOnTopPref];
-       
-       TCGlobalUpdateCheck = [updateAutomaticallyButton state];
-       [[NSUserDefaults standardUserDefaults] setBool:TCGlobalUpdateCheck forKey:TCUpdateCheckPref];
+       if ( view == [window contentView] ) {
+               return;
+       }
        
-       // send server information to the delegate so the server can be updated accordingly
-       [delegate preferenceSetAllowRemote:[allowRemoteButton state] listenPort:[listenPortTextField intValue] broadcastName:[broadcastNameTextField stringValue]];
+       xdif = [view frame].size.width - [[window contentView] frame].size.width;
+       ydif = [view frame].size.height - [[window contentView] frame].size.height;
        
-       TCGlobalAllowRemote = [allowRemoteButton state];
-       [[NSUserDefaults standardUserDefaults] setBool:TCGlobalAllowRemote forKey:TCAllowRemotePref];
+       frame.size.width += xdif;
+       frame.size.height += ydif;
+       frame.origin.y -= ydif;
        
-       TCGlobalListenPort = [listenPortTextField intValue];
-       [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:TCGlobalListenPort] forKey:TCListenPortPref];
+       // switch to the new view
+       [window setContentView:_contentView];
+       [window setFrame:frame display:YES animate:YES];
+       [window setContentView:view];
+       [window makeFirstResponder:view];
+}
+
+
+- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag
+{
+       NSToolbarItem           *item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
        
-       [[NSUserDefaults standardUserDefaults] setObject:[broadcastNameTextField stringValue] forKey:TCBroadcastNamePref];
+       [item setLabel:itemIdentifier];
+       [item setPaletteLabel:itemIdentifier];
+       [item setImage:[NSImage imageNamed:itemIdentifier]];
+       [item setTarget:self];
+       [item setAction:NSSelectorFromString( [NSString stringWithFormat:@"choose%@:", itemIdentifier] )];
        
-       TCGlobalHitsDisplayed = [hitsDisplayedTextField intValue];
-       [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:TCGlobalHitsDisplayed] forKey:TCHitsDisplayedPref];
+    return [item autorelease];
 }
 
+- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar
+{
+       return [NSArray arrayWithObjects:@"General", @"Update", @"Server", nil];
+}
 
-- (IBAction)cancel:(id)sender
+- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar
 {
-       [self initialInterfaceSetup];
-       [self close];
+       return [NSArray arrayWithObjects:@"General", @"Update", @"Server", nil];
 }
 
-- (IBAction)save:(id)sender
+- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar
 {
-       [self apply:self];
-       [self close];
+       return [NSArray arrayWithObjects:@"General", @"Update", @"Server", nil];
 }
 
 
diff --git a/PreferenceControlling.h b/PreferenceControlling.h
deleted file mode 100644 (file)
index dd31d18..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      PreferenceControlling.h
-// Created:   Wed Sep 24 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#import <Cocoa/Cocoa.h>
-
-
-@protocol PreferenceControlling
-
-- (void)preferenceSetWindowsOnTop:(BOOL)windowsOnTop;
-- (void)preferenceSetAllowRemote:(BOOL)allow listenPort:(int)port broadcastName:(NSString *)name;
-
-/*
-- (void)preferenceAllowRemoteChanged:(BOOL)allow;
-- (void)preferenceListenPortChanged:(int)port;
-- (void)preferenceBroadcastNameChanged:(NSString *)name;
-*/
-
-@end
\ No newline at end of file
diff --git a/Process.h b/Process.h
new file mode 100644 (file)
index 0000000..47f73e9
--- /dev/null
+++ b/Process.h
@@ -0,0 +1,46 @@
+
+// **********************************************************************
+// 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 <Cocoa/Cocoa.h>
+
+
+@interface Process : NSObject < NSCopying, NSCoding >
+{
+       NSString *_name;
+       NSString *_version;
+       NSImage *_icon;
+       pid_t _pid;
+}
+
+// initialization
+- (id)initWithName:(NSString *)name version:(NSString *)version icon:(NSImage *)icon pid:(pid_t)pid;
+- (id)initWithName:(NSString *)name version:(NSString *)version icon:(NSImage *)icon;
+- (id)initWithName:(NSString *)name version:(NSString *)version;
+
+// comparison
+- (BOOL)sameApplicationAs:(id)anObject;
+
+// accessors
+- (NSString *)name;
+- (NSString *)version;
+- (NSImage *)icon;
+- (pid_t)pid;
+
+@end
diff --git a/Process.m b/Process.m
new file mode 100644 (file)
index 0000000..3fe3a69
--- /dev/null
+++ b/Process.m
@@ -0,0 +1,194 @@
+
+// **********************************************************************
+// 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 "Process.h"
+
+
+@interface Process ( PrivateAPI )
+
+- (void)_setName:(NSString *)name;
+- (void)_setVersion:(NSString *)version;
+- (void)_setIcon:(NSImage *)icon;
+- (void)_setPID:(pid_t)pid;
+
+@end
+
+
+@implementation Process
+
+
+- (id)initWithName:(NSString *)name version:(NSString *)version icon:(NSImage *)icon pid:(pid_t)pid
+{
+       if ( self = [super init] ) {
+               [self _setName:name];
+               [self _setVersion:version];
+               [self _setIcon:icon];
+               [self _setPID:pid];
+       }
+       return self;
+}
+
+- (id)initWithName:(NSString *)name version:(NSString *)version icon:(NSImage *)icon
+{
+       return [self initWithName:name version:version icon:icon pid:0];
+}
+
+- (id)initWithName:(NSString *)name version:(NSString *)version
+{
+       return [self initWithName:name version:version icon:nil pid:0];
+}
+
+- (void)dealloc
+{
+       // release local objects
+       [_name release];
+       [_version release];
+       [_icon release];
+       
+       [super dealloc];
+}
+
+
+// #############################################################################
+#pragma mark NSCoding
+// #############################################################################
+
+- (id)copyWithZone:(NSZone *)zone
+{
+       return [[Process allocWithZone:zone] initWithName:_name version:_version icon:_icon pid:_pid];
+}
+
+
+// #############################################################################
+#pragma mark NSCoding
+// #############################################################################
+
+- (id)initWithCoder:(NSCoder *)coder
+{
+       if ( self = [super init] )
+       {
+               [self _setName:[coder decodeObject]];
+               [self _setVersion:[coder decodeObject]];
+               //[self setIcon:[coder decodeObject]];
+               [coder decodeValueOfObjCType:@encode(pid_t) at:&_pid];
+       }
+       return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)coder
+{
+       [coder encodeObject:_name];
+       [coder encodeObject:_version];
+       //[coder encodeObject:_icon];
+       [coder encodeValueOfObjCType:@encode(pid_t) at:&_pid];
+}
+
+
+#pragma mark NSObject Override
+
+- (BOOL)isEqual:(id)anObject
+{
+       if ( [_name isEqualToString:[(Process *)anObject name]] &&
+                [_version isEqualToString:[(Process *)anObject version]] &&
+                _pid == [(Process *)anObject pid] ) {
+               // they are the same process
+               return YES;
+       }
+       return NO;
+}
+
+- (unsigned)hash
+{
+       return [[NSString stringWithFormat:@"%@%@%u", _name, _version, _pid] hash];
+}
+
+
+- (BOOL)sameApplicationAs:(id)anObject
+{
+       if ( [_name isEqualToString:[(Process *)anObject name]] &&
+                [_version isEqualToString:[(Process *)anObject version]] ) {
+               // they are the same application
+               return YES;
+       }
+       return NO;
+}
+
+
+#pragma mark Accessors
+
+- (NSString *)name
+{
+       return _name;
+}
+
+- (NSString *)version
+{
+       return _version;
+}
+
+- (NSImage *)icon
+{
+       return _icon;
+}
+
+- (pid_t)pid
+{
+       return _pid;
+}
+
+
+- (void)_setName:(NSString *)name
+{
+       if ( !name ) {
+               name = [NSString stringWithString:@"Unknown Process"];
+       }
+       [name retain];
+       [_name release];
+       _name = name;
+}
+
+- (void)_setVersion:(NSString *)version
+{
+       if ( !version ) {
+               version = [NSString stringWithString:@"Unknown Version"];
+       }
+       [version retain];
+       [_version release];
+       _version = version;
+}
+
+- (void)_setIcon:(NSImage *)icon
+{
+       [icon retain];
+       [_icon release];
+       _icon = icon;
+       
+       // resize new image
+       [_icon setScalesWhenResized:YES];
+       [_icon setSize:NSMakeSize(16,16)];
+}
+
+- (void)_setPID:(pid_t)pid
+{
+       _pid = pid;
+}
+
+
+@end
diff --git a/Read Me.rtf b/Read Me.rtf
deleted file mode 100644 (file)
index 9377d54..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-{\rtf1\mac\ansicpg10000\cocoartf102
-{\fonttbl\f0\fswiss\fcharset77 Arial-BoldMT;\f1\fswiss\fcharset77 ArialMT;\f2\fswiss\fcharset77 Arial-ItalicMT;
-\f3\fswiss\fcharset77 Helvetica;\f4\fnil\fcharset77 Monaco;}
-{\colortbl;\red255\green255\blue255;}
-\margl1440\margr1440\vieww11440\viewh16000\viewkind0
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
-
-\f0\b\fs42 \cf0 The Cheat
-\fs24  v1.1.2
-\fs42 \
-
-\fs24 Chaz McGarvey\
-
-\f1\b0\fs32 March 19, 2004
-\f0\b\fs24 \
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qj
-
-\fs42 \cf0 \
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qj
-
-\fs28 \cf0 What is The Cheat?
-\f1\b0 \
-\
-The Cheat is an application referred to as a 
-\f2\i universal game trainer
-\f1\i0 .  It allows you to alter many different aspects of computer games.  For example, you can change things like the amount of lives your character has, the amount of ammo, the level you're on, the abilities you have, your location in the game, and whatever else you want to change in your games.  This all occurs in real-time while the game is running, and the process will work for almost any game.  The Cheat contains the following features:\
-\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\qj
-
-\f3 \cf0 - Includes support for finding strings, integers, and floats.\
-- Ability to pause the target application without switching programs.\
-- Browse and change possible variables from a list.\
-- Remote cheating lets you cheat games which won't give up full-screen.\
-- Ability to change variables continually, keeping a variable constant.\
-- Undo/redo works to revert to previous search results.
-\f1 \
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qj
-\cf0 \
-
-\f0\b How does it work?
-\f1\b0 \
-\
-Although the process has been used to cheat games for many years, it is relatively new to Mac OS X.  Similar programs have been written for many platforms including Windows and many different game consoles.  To do what it does, The Cheat accesses the memory of other applications.  It first reads through the entire address space, searching for variables based on input you provide.  Search results are then narrowed down by scanning the memory again after the value of the variable you are searching for has changed.  After a few searches, there should only be one variable remaining (ideally).  The Cheat will then allow you to change this variable to whatever you want.  To learn more about using the program, refer to the tutorial which you should have received with the application.\
-\
-
-\f0\b Is this safe?
-\f1\b0 \
-\
-Mac OS X includes support for protected memory which disables running processes from accessing the address spaces of other processes and of the operating system.  This causes a more stable system because faulty applications won't be able to trash the memory of other applications which could cause certain applications to crash or the entire operating system to crash.  So since The Cheat is able to get around this protection, might this be bad for stability?  Well, potentially yes.  However, The Cheat only changes the memory of other programs where you tell it to.  Thus, if you follow the process correctly, your games should never crash.  Furthermore, assuming you don't run The Cheat as root (which would not be a good idea), The Cheat will not be able to alter any system-critical processes so it would actually be very difficult if not impossible to crash your system using The Cheat.\
-\
-That said, The Cheat does support a feature called remote cheating.  This allows you to cheat programs running on one computer from another computer on the same network.  This feature exists to allow programs which won't give up full-screen to be cheated.  However, if there happens to be any malicious Mac OS X users on your network who also have The Cheat, they could potentially access the memory of your applications whenever remote cheating is enabled.  This feature is off by default.  It is recommended that you leave it off whenever you don't need its functionality.\
-\
-
-\f0\b So who writes this software?
-\f1\b0 \
-\
-I do.  If you need to contact me, my hours are 12 a.m. to 11:59:59 p.m. (yes, I need at least a second off) Monday through Saturday (and a day).  Get ahold of me if you have questions about the software or if you have bugs to report.  There are also resources on my web site (including discussion forums and source code for developers).\
-\
-Web:   http://www.brokenzipper.com\
-Email: chaz@brokenzipper.com\
-\
-Be sure to have a nice disposition if you decide to contact me, and keep in mind that that this software is free.\
-\
-
-\f0\b Do you keep track of version history?
-\f1\b0 \
-\
-Against my better judgment, yes.  Here it is:\
-\
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qj
-
-\f4\fs24 \cf0 1.1.2    (03/19/04, public)\
-Bug Fixes:\
-- Crash when trying to display more results than there are.\
-Other Changes:\
-- Internal improvements to the status displayer.\
-- Internal modifications to the document system.\
-- Quitting the target is now reported through status, not by sheets.\
-\
-1.1.1  (03/08/04, public)\
-Bug Fixes:\
-- String searches can now be narrowed down (sorry about that).\
-\
-1.1            (03/08/04, public)\
-New Features:\
-- Update Check (query a server to determine current version).\
-- Ability to specify how many hits you want The Cheat to show you.\
-Bug Fixes:\
-- String changing now changes the correct number of bytes.\
-- Other minor bugs.\
-Other Changes:\
-- String searching is now optimized.\
-- Default port changed from 5007 to 51835.\
-- New icon.\
-\
-1.0            (12/19/03, public)\
-Bug Fixes:\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\qj
-\cf0 - User interface glitch disallowing continuous changes to be stopped.\
-- Other minor bugs.\
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qj
-\cf0 \
-1.0b4  (12/11/03, internal)\
-Bug Fixes:\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\qj
-\cf0 - The address table selection can now be changed during a continuous change.\
-- Stability issues relating to the network browser.\
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qj
-\cf0 - Server finder no longer displays servers on the local machine.\
-- Some crashes resolved.\
-Other Changes:\
-- Progress bar changed to the round variety.\
-- Information about searches is now provided for new users.\
-- Minor user interface improvements.\
-\
-1.0b3  (11/26/03, internal)\
-New Features:\
-- Change values on a time interval to make variables seem constant.\
-- Informative about box added.\
-Bug Fixes:\
-- Searching implemented for all supported types.\
-- Changing values now works.\
-- Searching/changing decimal numbers is no longer broken.\
-- Targets can now be paused before the first search.\
-- Other minor bugs.\
-\
-1.0b2  (11/12/03, internal)\
-New Features:\
-- Remote cheating (cheat games over a network).\
-- Pause target (pause without switching applications).\
-Bug Fixes:\
-- Some user interface glitches fixed.\
-Other Changes:\
-- New icon.\
-\
-1.0b1  (09/04/03, public)\
-Features:\
-- Searching and changing integers, strings, and floats.\
-- Changing variables from a list.
-\f1\fs28 \
-\
-Remember, different versions of The Cheat are not guaranteed to be able to communicate with each other using the remote cheating feature.  It is highly recommended that you upgrade every copy on you network if you use remote cheating.\
-\
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qj
-
-\f0\b \cf0 My computer died.  Can I sue you?
-\f1\b0 \
-\
-Uh, no...  Here are the complete terms of use:\
-\
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qj
-
-\f4\fs24 \cf0 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\f1\fs28 \
-\
-Fortunately, The Cheat hasn't yet caused any dead computers to my knowledge.  Let's cross our fingers and hope the luck continues.\
-\
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qj
-
-\f0\b \cf0 So what else is there?
-\f1\b0 \
-\
-Well that's pretty much it.  If you are new to universal game trainers, I highly recommend that you go through the included tutorial before you try to figure it out yourself and ultimately become frustrated.  The tutorial doesn't include everything, though, so visit the forums or email me if you need additional help.  I'm really quite willing to help provided I have time.  Other than that, just have fun with The Cheat.  Or don't.  Whatever.\
-}
\ No newline at end of file
diff --git a/RemoteCheater.h b/RemoteCheater.h
new file mode 100644 (file)
index 0000000..07db68b
--- /dev/null
@@ -0,0 +1,41 @@
+
+// **********************************************************************
+// 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 <Cocoa/Cocoa.h>
+#import "ChazUpdate.h"
+
+#import "Cheater.h"
+
+#import "MySocket.h"
+
+
+@interface RemoteCheater : Cheater
+{
+       MySocket *_socket;
+       
+       /* the current packet being read. */
+       TCPacketHeader _header;
+       NSData *_parameters;
+}
+
+- (BOOL)connectToHostWithData:(NSData *)data;
+// disconnects automatically upon dealloc
+
+@end
diff --git a/RemoteCheater.m b/RemoteCheater.m
new file mode 100644 (file)
index 0000000..f0bd8b9
--- /dev/null
@@ -0,0 +1,376 @@
+
+// **********************************************************************
+// 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 "RemoteCheater.h"
+
+
+@interface RemoteCheater ( PrivateAPI )
+
+- (void)_handlePacket;
+
+@end
+
+
+
+@implementation RemoteCheater
+
+
+- (void)dealloc
+{
+       [self disconnect];
+       [super dealloc];
+}
+
+
+- (BOOL)connectToHostWithData:(NSData *)data
+{
+       if ( _socket ) {
+               [self disconnect];
+       }
+       _socket = [[MySocket alloc] initWithDelegate:self];
+       if ( ![_socket connectToAddressWithData:data] ) {
+               return NO;
+       }
+       
+       // start reading from the socket
+       [_socket readDataToLength:sizeof(TCPacketHeader) tag:0];
+       
+       return YES;
+}
+
+- (NSString *)hostAddress
+{
+       return [_socket remoteHost];
+}
+
+
+// #############################################################################
+#pragma mark Cheater Override
+// #############################################################################
+
+- (void)connect
+{
+       NSData *params = [NSArchiver archivedDataWithRootObject:[NSString stringWithFormat:@"%@ %@", ChazAppName(), ChazAppVersion()]];
+       TCPacketHeader header = { TC_NIFTY, [params length], "connect" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeData:params tag:0];
+}
+
+- (void)disconnect
+{
+       [_socket setDelegate:nil];
+       [_socket release];
+       _socket = nil;
+       //[_delegate cheaterDidDisconnect:self];
+}
+
+- (void)authenticateWithPassword:(NSString *)password
+{
+       NSData *params = [NSArchiver archivedDataWithRootObject:password];
+       TCPacketHeader header = { TC_NIFTY, [params length], "authenticate" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeData:params tag:0];
+}
+
+
+- (void)getProcessList
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "getproclist" };
+       ChazLog( @"SENT getproclist" );
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+
+- (void)setTarget:(Process *)target
+{
+       NSData *params = [NSArchiver archivedDataWithRootObject:target];
+       TCPacketHeader header = { TC_NIFTY, [params length], "settarget" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeData:params tag:0];
+}
+
+- (void)pauseTarget
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "pausetarget" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+- (void)resumeTarget
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "resumetarget" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+
+- (void)limitReturnedResults:(unsigned)limit
+{
+       NSData *params = [NSArchiver archivedDataWithRootObject:[NSNumber numberWithUnsignedInt:limit]];
+       TCPacketHeader header = { TC_NIFTY, [params length], "limitresults" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeData:params tag:0];
+}
+
+- (void)searchForVariable:(Variable *)data comparison:(TCSearchOperator)op
+{
+       NSData *params = [NSArchiver archivedDataWithRootObject:[NSArray arrayWithObjects:data, [NSNumber numberWithUnsignedChar:op], nil]];
+       TCPacketHeader header = { TC_NIFTY, [params length], "search" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeData:params tag:0];
+}
+
+- (void)searchLastValuesComparison:(TCSearchOperator)op
+{
+       NSData *params = [NSArchiver archivedDataWithRootObject:[NSNumber numberWithUnsignedChar:op]];
+       TCPacketHeader header = { TC_NIFTY, [params length], "lastsearch" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeData:params tag:0];
+}
+
+- (void)cancelSearch
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "cancelsearch" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+- (void)clearSearch
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "clearsearch" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+- (void)getMemoryDump
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "dump" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+- (void)cancelMemoryDump
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "canceldump" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+
+- (void)makeVariableChanges:(NSArray *)variables repeat:(BOOL)doRepeat interval:(NSTimeInterval)repeatInterval
+{
+       NSData *params = [NSArchiver archivedDataWithRootObject:[NSArray arrayWithObjects:variables,
+               [NSNumber numberWithBool:doRepeat], [NSNumber numberWithDouble:repeatInterval], nil]];
+       TCPacketHeader header = { TC_NIFTY, [params length], "changevars" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeData:params tag:0];
+}
+
+- (void)stopChangingVariables
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "stopchange" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+
+- (void)undo
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "undo" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+- (void)redo
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "redo" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+
+- (void)watchVariablesAtIndex:(unsigned)index count:(unsigned)count interval:(NSTimeInterval)checkInterval
+{
+       NSData *params = [NSArchiver archivedDataWithRootObject:[NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:index],
+               [NSNumber numberWithUnsignedInt:count], [NSNumber numberWithDouble:checkInterval], nil]];
+       TCPacketHeader header = { TC_NIFTY, [params length], "watchvars" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeData:params tag:0];
+}
+
+- (void)stopWatchingVariables
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "stopwatching" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark MySocketDelegate
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+- (void)socket:(MySocket *)mySocket didReadData:(NSData *)theData tag:(int)tag
+{
+       if ( tag == 0 && [theData length] == sizeof(TCPacketHeader) ) {
+               // got a packet header
+               memcpy( &_header, [theData bytes], sizeof(TCPacketHeader) );
+               if ( _header.size > 0 ) {
+                       // request the rest of the packet
+                       [mySocket readDataToLength:_header.size tag:1];
+               }
+               else {
+                       [self _handlePacket];
+                       // start reading the next packet
+                       [mySocket readDataToLength:sizeof(TCPacketHeader) tag:0];
+               }
+       }
+       else if ( tag == 1 && [theData length] == _header.size ) {
+               // got packet parameter data
+               _parameters = [theData retain];
+               [self _handlePacket];
+               // start reading the next packet
+               [mySocket readDataToLength:sizeof(TCPacketHeader) tag:0];
+       }
+       else {
+               ChazLog( @"RemoteCheater - read expected data, disconnecting..." );
+               [self disconnect];
+       }
+}
+
+- (void)socketDidDisconnect:(MySocket *)mySocket
+{
+       [_socket release];
+       _socket = nil;
+       
+       [_delegate cheaterDidDisconnect:self];
+}
+
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark PrivateAPI
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+- (void)_handlePacket
+{
+       if ( strncmp( "connected", _header.name, sizeof(_header.name) ) == 0 ) {
+               ChazLog( @"RemoteCheater - connected" );
+               [_delegate cheaterDidConnect:self];
+       }
+       else if ( strncmp( "requireauth", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_delegate cheaterRequiresAuthentication:self];
+       }
+       else if ( strncmp( "rejectedauth", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_delegate cheaterRejectedPassword:self];
+       }
+       else if ( strncmp( "authenticated", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_delegate cheaterAcceptedPassword:self];
+       }
+       else if ( strncmp( "proclist", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_delegate cheater:self didFindProcesses:[NSUnarchiver unarchiveObjectWithData:_parameters]];
+       }
+       else if ( strncmp( "addprocess", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_delegate cheater:self didAddProcess:[NSUnarchiver unarchiveObjectWithData:_parameters]];
+       }
+       else if ( strncmp( "removeprocess", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_delegate cheater:self didRemoveProcess:[NSUnarchiver unarchiveObjectWithData:_parameters]];
+       }
+       else if ( strncmp( "didsettarget", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_delegate cheater:self didSetTarget:[NSUnarchiver unarchiveObjectWithData:_parameters]];
+       }
+       else if ( strncmp( "didpausetarget", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_delegate cheaterPausedTarget:self];
+       }
+       else if ( strncmp( "didresumetarget", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_delegate cheaterResumedTarget:self];
+       }
+       else if ( strncmp( "vars", _header.name, sizeof(_header.name) ) == 0 ) {
+               struct varInfo {
+                       unsigned count;
+                       unsigned varCount;
+                       unsigned varSize;
+               } *varInfo;
+               void *bytes;
+               TCArray variables;
+               varInfo = (struct varInfo *)[_parameters bytes];
+               bytes = (void *)[_parameters bytes] + sizeof(*varInfo);
+               variables = TCMakeArrayWithBytes( varInfo->varCount, varInfo->varSize, bytes );
+               [_delegate cheater:self didFindVariables:variables actualAmount:varInfo->count];
+       }
+       else if ( strncmp( "values", _header.name, sizeof(_header.name) ) == 0 ) {
+               struct varInfo {
+                       unsigned varCount;
+                       unsigned varSize;
+               } *varInfo;
+               void *bytes;
+               TCArray values;
+               varInfo = (struct varInfo *)[_parameters bytes];
+               bytes = (void *)[_parameters bytes] + sizeof(*varInfo);
+               values = TCMakeArrayWithBytes( varInfo->varCount, varInfo->varSize, bytes );
+               [_delegate cheater:self didFindValues:values];
+       }
+       else if ( strncmp( "didcancelsearch", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_delegate cheaterDidCancelSearch:self];
+       }
+       else if ( strncmp( "didclearsearch", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_delegate cheaterDidClearSearch:self];
+       }
+       else if ( strncmp( "memdump", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_delegate cheater:self didDumpMemory:_parameters];
+       }
+       else if ( strncmp( "didcanceldump", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_delegate cheaterDidCancelMemoryDump:self];
+       }
+       else if ( strncmp( "changedvars", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_delegate cheater:self didChangeVariables:[[NSUnarchiver unarchiveObjectWithData:_parameters] unsignedIntValue]];
+       }
+       else if ( strncmp( "didstopchanging", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_delegate cheaterDidStopChangingVariables:self];
+       }
+       else if ( strncmp( "progress", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_delegate cheater:self didReportProgress:[[NSUnarchiver unarchiveObjectWithData:_parameters] intValue]];
+       }
+       else if ( strncmp( "revertedto", _header.name, sizeof(_header.name) ) == 0 ) {
+               struct varInfo {
+                       unsigned count;
+                       unsigned varCount;
+                       unsigned varSize;
+               } *varInfo;
+               void *bytes;
+               TCArray variables;
+               varInfo = (struct varInfo *)[_parameters bytes];
+               bytes = (void *)[_parameters bytes] + sizeof(*varInfo);
+               variables = TCMakeArrayWithBytes( varInfo->varCount, varInfo->varSize, bytes );
+               [_delegate cheater:self didRevertToVariables:variables actualAmount:varInfo->count];
+       }
+       else if ( strncmp( "didundo", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_delegate cheaterDidUndo:self];
+       }
+       else if ( strncmp( "didredo", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_delegate cheaterDidRedo:self];
+       }
+       else if ( strncmp( "varchanged", _header.name, sizeof(_header.name) ) == 0 ) {
+               NSArray *params = [NSUnarchiver unarchiveObjectWithData:_parameters];
+               [_delegate cheater:self variableAtIndex:[[params objectAtIndex:0] unsignedIntValue] didChangeTo:[params objectAtIndex:1]];
+       }
+       else if ( strncmp( "failed", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_delegate cheater:self didFailLastRequest:[NSUnarchiver unarchiveObjectWithData:_parameters]];
+       }
+       else if ( strncmp( "echo", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_delegate cheater:self echo:[NSUnarchiver unarchiveObjectWithData:_parameters]];
+       }
+       
+       [_parameters release];
+       _parameters = nil;
+}
+
+
+
+@end
diff --git a/SearchContext.h b/SearchContext.h
new file mode 100644 (file)
index 0000000..26bd2c7
--- /dev/null
@@ -0,0 +1,89 @@
+//
+//  SearchContext.h
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 12/4/04.
+//  Copyright 2004 Chaz McGarvey. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+#include "ChazLog.h"
+
+#import "CheaterTypes.h"
+#import "Searching.h"
+#import "VMRegion.h"
+#import "Variable.h"
+
+
+#define TC_BUFFER_SIZE (8192)
+// used when buffers are expanded; use a multiple for 4096 because
+// the virtual memory system uses those sizes for optimization.
+
+#define TC_EPSILON (0.1)
+// defines the accuracy for floating point comparisons
+
+
+@interface SearchContext : NSObject
+{
+       /*
+        * So here's the big, bad, rather ugly search context class.
+        * There is quite a bit to keep track of, as you can see.
+        */
+       
+       TCVariableType _variableType;
+       TCIntegerSign _integerSign;
+       TCSearchOperator _operator;
+       TCSearchType _searchType;
+       
+       // for fast access while iterating through the task loop.
+       @public;
+       
+       pid_t process; // the pid of the process being searched
+       unsigned regionCount; // estimation of the # of regions used for progress reporting
+       VMRegion lastRegion; // used to find the next region to search
+       
+       Variable *value; // the value to compare against (TCGivenValue searches)
+       BOOL (*compareFunc)(void const *, void const*); // comparison function
+       
+       TCArray addresses; // array to store hit addresses
+       TCArray values; // parallel array to store hit values
+       TCArray regions; // array of addresses, one for each region which contains a hit
+       TCArray perRegion; // number of variables found for each region
+       unsigned numberOfResults; // actual number of hits so far
+       
+       TCArray lastAddresses; // the addresses of variables to check
+       TCArray lastValues; // the values to compare against (TCLastValue searches)
+       TCArray lastRegions; // optimizes "again" searches
+       TCArray lastPerRegion; // parallels lastRegions
+       
+       void *buffer; // the working buffer for reading in memory from the other app
+       unsigned bufferSize; // size of the working buffer
+       
+       // pointers
+       void *valuePtr, *lastValuePtr;
+       TCAddress *addressPtr, *lastAddressPtr;
+       TCAddress *lastRegionPtr;
+       unsigned *lastPerRegionPtr;
+       
+       int progress; // 0-100
+}
+
+// Initialization
+
+// this initializer must be used to create a context for a first-time search
+- (id)initWithPID:(pid_t)pid searchOperator:(TCSearchOperator)op value:(Variable *)val;
+// these initializers take data from the last search that was performed
+- (id)initWithLastContext:(SearchContext *)context searchOperator:(TCSearchOperator)op;
+- (id)initWithLastContext:(SearchContext *)context searchOperator:(TCSearchOperator)op value:(Variable *)val;
+
+// Accessors
+
+- (TCVariableType)variableType;
+- (TCIntegerSign)integerSign;
+- (TCSearchOperator)searchOperator;
+
+- (BOOL (*)(void const *, void const *))compareFunction;
+- (int (*)(id, unsigned))iterationFunction;
+
+
+@end
diff --git a/SearchContext.m b/SearchContext.m
new file mode 100644 (file)
index 0000000..704e267
--- /dev/null
@@ -0,0 +1,295 @@
+//
+//  SearchContext.m
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 12/4/04.
+//  Copyright 2004 Chaz McGarvey. All rights reserved.
+//
+
+#import "SearchContext.h"
+
+
+@implementation SearchContext
+
+
+#pragma mark Initialization
+
+/*
+ * There isn't really a designated initializer because the initialization of the types
+ * of searches vary way too much.
+ */
+
+- (id)initWithPID:(pid_t)pid searchOperator:(TCSearchOperator)op value:(Variable *)val
+{
+       unsigned valueSize;
+       
+       if ( [super init] ) {
+               value = [val retain];
+               if ( !value ) {
+                       [self release];
+                       return nil;
+               }
+               valueSize = [value valueSize];
+               process = pid;
+               _variableType = [value type];
+               _integerSign = [value integerSign];
+               _operator = op;
+               _searchType = TCGivenValue;
+               compareFunc = [self compareFunction];
+               
+               // allocate the memory objects which will be used during the search
+               regionCount = VMCountRegionsWithAttributes( process, VMREGION_READABLE | VMREGION_WRITABLE );
+               addresses = TCMakeArray( TC_BUFFER_SIZE / sizeof(TCAddress), sizeof(TCAddress) );
+               values = TCMakeArray( TC_BUFFER_SIZE / valueSize, valueSize );
+               regions = TCMakeArray( 0, sizeof(TCAddress) );
+               perRegion = TCMakeArray( 0, sizeof(unsigned) );
+               addressPtr = TCArrayBytes( addresses );
+               valuePtr = TCArrayBytes( values );
+               
+               ChazLog( @"SearchContext: varType=%i, intSign=%i, op=%i, value=%@", _variableType, _integerSign, _operator, [value stringValue] );
+       }
+       return self;
+}
+
+- (id)initWithLastContext:(SearchContext *)context searchOperator:(TCSearchOperator)op
+{
+       unsigned valueSize;
+       
+       if ( [super init] ) {
+               if ( !context ) {
+                       [self release];
+                       return nil;
+               }
+               valueSize = TCArrayElementSize(context->values);
+               process = context->process;
+               _variableType = [context variableType];
+               _integerSign = [context integerSign];
+               _operator = op;
+               _searchType = TCLastValue;
+               compareFunc = [self compareFunction];
+               
+               regionCount = TCArrayElementCount( context->regions );
+               addresses = TCMakeArray( TC_BUFFER_SIZE / sizeof(TCAddress), sizeof(TCAddress) );
+               values = TCMakeArray( TC_BUFFER_SIZE / valueSize, valueSize );
+               regions = TCMakeArray( 0, sizeof(TCAddress) );
+               perRegion = TCMakeArray( 0, sizeof(unsigned) );
+               lastAddresses = context->addresses;
+               lastValues = context->values;
+               lastRegions = context->regions;
+               lastPerRegion = context->perRegion;
+               addressPtr = TCArrayBytes( addresses );
+               valuePtr = TCArrayBytes( values );
+               lastAddressPtr = TCArrayBytes( lastAddresses );
+               lastValuePtr = TCArrayBytes( lastValues );
+               lastRegionPtr = TCArrayBytes( lastRegions );
+               lastPerRegionPtr = TCArrayBytes( lastPerRegion );
+               
+               ChazLog( @"SearchContext: varType=%i, intSign=%i, op=%i", _variableType, _integerSign, _operator );
+       }
+       return self;
+}
+
+- (id)initWithLastContext:(SearchContext *)context searchOperator:(TCSearchOperator)op value:(Variable *)val
+{
+       unsigned valueSize;
+       
+       if ( [super init] ) {
+               if ( !context || !val || ([val type] != [context variableType]) // and search values can't be bigger than the last time.
+                        || (([context variableType] == TCString) && ([val valueSize] > TCArrayElementSize(context->values))) ) {
+                       [self release];
+                       return nil;
+               }
+               value = [val retain];
+               valueSize = [value valueSize];
+               process = context->process;
+               _variableType = [context variableType];
+               _integerSign = [context integerSign];
+               _operator = op;
+               _searchType = TCGivenValue;
+               compareFunc = [self compareFunction];
+               
+               regionCount = TCArrayElementCount( context->regions );
+               addresses = TCMakeArray( TC_BUFFER_SIZE / sizeof(TCAddress), sizeof(TCAddress) );
+               values = TCMakeArray( TC_BUFFER_SIZE / valueSize, valueSize );
+               regions = TCMakeArray( 0, sizeof(TCAddress) );
+               perRegion = TCMakeArray( 0, sizeof(unsigned) );
+               lastAddresses = context->addresses;
+               lastValues = context->values;
+               lastRegions = context->regions;
+               lastPerRegion = context->perRegion;
+               addressPtr = TCArrayBytes( addresses );
+               valuePtr = TCArrayBytes( values );
+               lastAddressPtr = TCArrayBytes( lastAddresses );
+               lastValuePtr = TCArrayBytes( lastValues );
+               lastRegionPtr = TCArrayBytes( lastRegions );
+               lastPerRegionPtr = TCArrayBytes( lastPerRegion );
+               
+               ChazLog( @"SearchContext: varType=%i, intSign=%i, op=%i, value=%@", _variableType, _integerSign, _operator, [value stringValue] );
+       }
+       return self;
+}
+
+- (void)dealloc
+{
+       ChazLog( @"SearchContext %p dealloc", self );
+       TCReleaseArray( addresses );
+       TCReleaseArray( values );
+       TCReleaseArray( regions );
+       TCReleaseArray( perRegion );
+       
+       if ( buffer ) {
+               free( buffer );
+       }
+       [value release];
+       
+       [super dealloc];
+}
+
+
+#pragma mark Accessors
+
+- (TCVariableType)variableType
+{
+       return _variableType;
+}
+
+- (TCIntegerSign)integerSign
+{
+       return _integerSign;
+}
+
+- (TCSearchOperator)searchOperator
+{
+       return _operator;
+}
+
+
+- (BOOL (*)(void const *, void const *))compareFunction
+{
+       // here begins a very pretty collection of switch and if statements. enjoy!
+       switch ( _operator ) {
+               case TCEqual:
+                       switch ( _variableType ) {
+                               case TCFloat: return EqualFloat;
+                               case TCDouble: return EqualDouble;
+                       }
+                       if ( _integerSign == TCSigned ) {
+                               switch ( _variableType ) {
+                                       case TCInt64: return EqualInt64;
+                                       case TCInt32: return EqualInt32;
+                                       case TCInt16: return EqualInt16;
+                                       case TCInt8: return EqualInt8;
+                               }
+                       }
+                       else {
+                               switch ( _variableType ) {
+                                       case TCInt64: return EqualUInt64;
+                                       case TCInt32: return EqualUInt32;
+                                       case TCInt16: return EqualUInt16;
+                                       case TCInt8: return EqualUInt8;
+                               }
+                       }
+                       break;
+               case TCNotEqual:
+                       switch ( _variableType ) {
+                               case TCFloat: return NotEqualFloat;
+                               case TCDouble: return NotEqualDouble;
+                       }
+                       if ( _integerSign == TCSigned ) {
+                               switch ( _variableType ) {
+                                       case TCInt64: return NotEqualInt64;
+                                       case TCInt32: return NotEqualInt32;
+                                       case TCInt16: return NotEqualInt16;
+                                       case TCInt8: return NotEqualInt8;
+                               }
+                       }
+                       else {
+                               switch ( _variableType ) {
+                                       case TCInt64: return NotEqualUInt64;
+                                       case TCInt32: return NotEqualUInt32;
+                                       case TCInt16: return NotEqualUInt16;
+                                       case TCInt8: return NotEqualUInt8;
+                               }
+                       }
+                       break;
+               case TCLessThan:
+                       switch ( _variableType ) {
+                               case TCFloat: return LessThanFloat;
+                               case TCDouble: return LessThanDouble;
+                       }
+                       if ( _integerSign == TCSigned ) {
+                               switch ( _variableType ) {
+                                       case TCInt64: return LessThanInt64;
+                                       case TCInt32: return LessThanInt32;
+                                       case TCInt16: return LessThanInt16;
+                                       case TCInt8: return LessThanInt8;
+                               }
+                       }
+                       else {
+                               switch ( _variableType ) {
+                                       case TCInt64: return LessThanUInt64;
+                                       case TCInt32: return LessThanUInt32;
+                                       case TCInt16: return LessThanUInt16;
+                                       case TCInt8: return LessThanUInt8;
+                               }
+                       }
+                       break;
+               case TCGreaterThan:
+                       switch ( _variableType ) {
+                               case TCFloat: return GreaterThanFloat;
+                               case TCDouble: return GreaterThanDouble;
+                       }
+                       if ( _integerSign == TCSigned ) {
+                               switch ( _variableType ) {
+                                       case TCInt64: return GreaterThanInt64;
+                                       case TCInt32: return GreaterThanInt32;
+                                       case TCInt16: return GreaterThanInt16;
+                                       case TCInt8: return GreaterThanInt8;
+                               }
+                       }
+                       else {
+                               switch ( _variableType ) {
+                                       case TCInt64: return GreaterThanUInt64;
+                                       case TCInt32: return GreaterThanUInt32;
+                                       case TCInt16: return GreaterThanUInt16;
+                                       case TCInt8: return GreaterThanUInt8;
+                               }
+                       }
+                       break;
+       }
+       return NULL;
+}
+
+- (int (*)(id, unsigned))iterationFunction
+{
+       if ( _searchType == TCGivenValue ) {
+               if ( !lastAddresses ) {
+                       if ( _variableType == TCString ) {
+                               return SearchStringIteration;
+                       }
+                       else {
+                               return SearchIteration;
+                       }
+               }
+               else {
+                       if ( _variableType == TCString ) {
+                               return SearchStringIterationAgain;
+                       }
+                       else {
+                               return SearchIterationAgain;
+                       }
+               }
+       }
+       else if ( _searchType == TCLastValue ) {
+               if ( _variableType == TCString ) {
+                       return SearchStringIterationLastValue;
+               }
+               else {
+                       return SearchIterationLastValue;
+               }
+       }
+       return NULL;
+}
+
+
+@end
diff --git a/SearchData.h b/SearchData.h
new file mode 100644 (file)
index 0000000..bdcfeda
--- /dev/null
@@ -0,0 +1,76 @@
+//
+//  SearchData.h
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 12/13/04.
+//  Copyright 2004 Chaz McGarvey. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+
+#import "CheaterTypes.h"
+
+#import "Cheater.h"
+#import "Variable.h"
+
+
+@interface SearchData : NSObject
+{
+       TCVariableType _variableType;
+       TCIntegerSign _integerSign;
+       TCSearchOperator _operator;
+       TCSearchType _value;
+       
+       Variable *_variableValue;
+       
+       TCArray _addresses;
+       TCArray _values;
+       
+       Process *_process;
+       
+       int _undoes;
+       int _redoes;
+}
+
+// ACCESSORS
+- (TCVariableType)variableType;
+- (void)setVariableType:(TCVariableType)varType;
+
+- (TCIntegerSign)integerSign;
+- (void)setIntegerSign:(TCIntegerSign)sign;
+
+- (TCSearchOperator)searchOperator;
+- (void)setSearchOperator:(TCSearchOperator)op;
+
+- (TCSearchType)valueUsed;
+- (void)setValueUsed:(TCSearchType)value;
+
+- (Variable *)searchValue;
+- (void)setSearchValue:(Variable *)value;
+
+- (unsigned)numberOfResults;
+- (TCArray)addresses;
+- (void)setAddresses:(TCArray)addresses;
+- (TCArray)values;
+- (void)setValues:(TCArray)values;
+- (void)setValue:(Variable *)value atIndex:(unsigned)index;
+- (BOOL)valuesLoaded;
+- (Variable *)variableAtIndex:(unsigned)index;
+- (NSString *)stringForRow:(unsigned)rowIndex;
+
+- (BOOL)hasSearchedOnce;
+
+- (int)undoesLeft;
+- (int)redoesLeft;
+- (void)didAddResults;
+- (void)didUndo;
+- (void)didRedo;
+
+// this is convenient
+- (BOOL)isTypeInteger;
+
+// ACTIONS
+- (void)clearResults;
+
+
+@end
diff --git a/SearchData.m b/SearchData.m
new file mode 100644 (file)
index 0000000..6170bac
--- /dev/null
@@ -0,0 +1,243 @@
+//
+//  SearchData.m
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 12/13/04.
+//  Copyright 2004 Chaz McGarvey. All rights reserved.
+//
+
+#import "SearchData.h"
+
+
+@implementation SearchData
+
+
+- (id)init
+{
+       if ( self = [super init] ) {
+               [self setVariableType:TCInt32];
+               [self setIntegerSign:TCSigned];
+               [self setSearchOperator:TCEqual];
+               [self setValueUsed:TCGivenValue];
+               
+               _undoes = -1;
+               _redoes = 0;
+       }
+       return self;
+}
+
+- (void)dealloc
+{
+       [_variableValue release];
+       TCReleaseArray( _addresses );
+       TCReleaseArray( _values );
+       [super dealloc];
+}
+
+
+- (TCVariableType)variableType
+{
+       return _variableType;
+}
+
+- (void)setVariableType:(TCVariableType)varType
+{
+       // can't change the variable type when there has been a search
+       if ( ![self hasSearchedOnce] ) {
+               _variableType = varType;
+       }
+}
+
+
+- (TCIntegerSign)integerSign
+{
+       return _integerSign;
+}
+
+- (void)setIntegerSign:(TCIntegerSign)sign
+{
+       // can't change the integer sign when there has been a search
+       if ( ![self hasSearchedOnce] ) {
+               _integerSign = sign;
+       }
+}
+
+
+- (TCSearchOperator)searchOperator
+{
+       return _operator;
+}
+
+- (void)setSearchOperator:(TCSearchOperator)op
+{
+       _operator = op;
+}
+
+
+- (TCSearchType)valueUsed
+{
+       if ( ![self hasSearchedOnce] ) {
+               // if there is no search, then use search value no matter what
+               _value = TCGivenValue;
+       }
+       return _value;
+}
+
+- (void)setValueUsed:(TCSearchType)value
+{
+       _value = value;
+}
+
+
+- (Variable *)searchValue
+{
+       if ( !_variableValue ) {
+               // create a zero value if there is none
+               _variableValue = [[Variable alloc] init];
+       }
+       return _variableValue;
+}
+
+- (void)setSearchValue:(Variable *)value
+{
+       [value retain];
+       [_variableValue release];
+       _variableValue = value;
+}
+
+
+- (unsigned)numberOfResults
+{
+       if ( _addresses ) {
+               return TCArrayElementCount( _addresses );
+       }
+       return 0;
+}
+
+- (TCArray)addresses
+{
+       return _addresses;
+}
+
+- (void)setAddresses:(TCArray)addresses
+{
+       TCReleaseArray( _addresses );
+       _addresses = addresses;
+       
+       if ( !_addresses ) {
+               // clear the undoes and redoes if the search is cleared
+               _undoes = -1;
+               _redoes = 0;
+       }
+       
+       // clear the stored values
+       [self setValues:NULL];
+}
+
+- (TCArray)values
+{
+       return _values;
+}
+
+- (void)setValues:(TCArray)values
+{
+       TCReleaseArray( _values );
+       _values = values;
+}
+
+- (void)setValue:(Variable *)value atIndex:(unsigned)index
+{
+       if ( _values ) {
+               if ( index < TCArrayElementCount( _values ) ) {
+                       TCArraySetElementAtIndex( _values, index, [value value] );
+               }
+       }
+}
+
+- (BOOL)valuesLoaded
+{
+       return ( _values != NULL );
+}
+
+- (Variable *)variableAtIndex:(unsigned)index
+{
+       if ( [self hasSearchedOnce] ) {
+               Variable *var = [[Variable alloc] initWithType:[self variableType] integerSign:[self integerSign]];
+               [var setAddress:*(TCAddress *)TCArrayElementAtIndex( [self addresses], index )];
+               if ( [self valuesLoaded] ) {
+                       [var setValue:TCArrayElementAtIndex( [self values], index ) size:TCArrayElementSize([self values])];
+               }
+               return [var autorelease];
+       }
+       return nil;
+}
+
+- (NSString *)stringForRow:(unsigned)rowIndex
+{
+       Variable *var = [self variableAtIndex:rowIndex];
+       
+       if ( var ) {
+               if ( [self valuesLoaded] ) {
+                       if ( [var type] == TCString ) {
+                               return [NSString stringWithFormat:@"%@ = \"%@\"", [var addressString], [var stringValue]];
+                       }
+                       else {
+                               return [NSString stringWithFormat:@"%@ = %@", [var addressString], [var stringValue]];
+                       }
+               }
+               else {
+                       return [var addressString];
+               }
+       }
+       return @"";
+}
+
+
+- (BOOL)hasSearchedOnce
+{
+       return ( _addresses != NULL );
+}
+
+
+- (int)undoesLeft
+{
+       return _undoes;
+}
+
+- (int)redoesLeft
+{
+       return _redoes;
+}
+
+- (void)didAddResults
+{
+       _undoes++;
+       _redoes = 0;
+}
+
+- (void)didUndo
+{
+       _undoes--;
+       _redoes++;
+}
+
+- (void)didRedo
+{
+       _undoes++;
+       _redoes--;
+}
+
+
+- (BOOL)isTypeInteger
+{
+       return _variableType <= TCInt8;
+}
+
+
+- (void)clearResults
+{
+       [self setAddresses:NULL];
+}
+
+
+@end
diff --git a/SearchResults.h b/SearchResults.h
deleted file mode 100644 (file)
index 364470a..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      SearchResults.h
-// Created:   Sat Oct 04 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#import <Cocoa/Cocoa.h>
-
-#include "cheat_types.h"
-
-
-@interface SearchResults : NSObject
-{
-       TCtype                  myType;
-       TCsize                  mySize;
-       
-       TCaddress               *myData;
-       int                             myAmount;
-}
-
-+ (id)resultsWithType:(TCtype)type size:(TCsize)size data:(TCaddress const *)data amount:(int)amount;
-- (id)initWithType:(TCtype)type size:(TCsize)size data:(TCaddress const *)data amount:(int)amount;
-
-- (TCtype)type;
-- (TCsize)size;
-- (TCaddress *)data;
-- (int)amount;
-
-@end
\ No newline at end of file
diff --git a/SearchResults.m b/SearchResults.m
deleted file mode 100644 (file)
index 8e15180..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      SearchResults.m
-// Created:   Sat Oct 04 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#import "SearchResults.h"
-
-
-@implementation SearchResults
-
-
-+ (id)resultsWithType:(TCtype)type size:(TCsize)size data:(TCaddress const *)data amount:(int)amount
-{
-       return [[[SearchResults alloc] initWithType:type size:size data:data amount:amount] autorelease];
-}
-
-- (id)initWithType:(TCtype)type size:(TCsize)size data:(TCaddress const *)data amount:(int)amount
-{
-       if ( self = [self init] )
-       {
-               myType = type;
-               mySize = size;
-               myData = (TCaddress *)data;
-               myAmount = amount;
-       }
-
-       return self;
-}
-
-
-- (TCtype)type
-{
-       return myType;
-}
-
-- (TCsize)size
-{
-       return mySize;
-}
-
-- (TCaddress *)data
-{
-       return myData;
-}
-
-- (int)amount
-{
-       return myAmount;
-}
-
-
-- (void)dealloc
-{
-       if ( myData )
-       {
-               free( myData );
-       }
-       
-       [super dealloc];
-}
-
-
-@end
\ No newline at end of file
diff --git a/Searching.h b/Searching.h
new file mode 100644 (file)
index 0000000..bed1220
--- /dev/null
@@ -0,0 +1,86 @@
+//
+//  Searching.h
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 12/28/04.
+//  Copyright 2004 Chaz McGarvey. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+
+#import "ThreadedTask.h"
+#import "SearchContext.h"
+
+#import "VMRegion.h"
+
+
+extern __inline__ void ReportSearchProgress( ThreadedTask *task, unsigned iteration, unsigned regions, int *progress );
+
+
+
+/*
+ * Search iteration functions:
+ * The first set is the generic one, the other is for strings.
+ */
+
+int SearchIteration( ThreadedTask *task, unsigned iteration );
+int SearchIterationAgain( ThreadedTask *task, unsigned iteration );
+int SearchIterationLastValue( ThreadedTask *task, unsigned iteration );
+
+int SearchStringIteration( ThreadedTask *task, unsigned iteration );
+int SearchStringIterationAgain( ThreadedTask *task, unsigned iteration );
+int SearchStringIterationLastValue( ThreadedTask *task, unsigned iteration );
+
+
+/*
+ * Compare functions...
+ * "Function( first, second)" -> "first [operator] second"
+ */
+BOOL EqualInt64( void const *first, void const *second );
+BOOL EqualInt32( void const *first, void const *second );
+BOOL EqualInt16( void const *first, void const *second );
+BOOL EqualInt8( void const *first, void const *second );
+BOOL EqualUInt64( void const *first, void const *second );
+BOOL EqualUInt32( void const *first, void const *second );
+BOOL EqualUInt16( void const *first, void const *second );
+BOOL EqualUInt8( void const *first, void const *second );
+BOOL EqualFloat( void const *first, void const *second );
+BOOL EqualDouble( void const *first, void const *second );
+
+BOOL NotEqualInt64( void const *first, void const *second );
+BOOL NotEqualInt32( void const *first, void const *second );
+BOOL NotEqualInt16( void const *first, void const *second );
+BOOL NotEqualInt8( void const *first, void const *second );
+BOOL NotEqualUInt64( void const *first, void const *second );
+BOOL NotEqualUInt32( void const *first, void const *second );
+BOOL NotEqualUInt16( void const *first, void const *second );
+BOOL NotEqualUInt8( void const *first, void const *second );
+BOOL NotEqualFloat( void const *first, void const *second );
+BOOL NotEqualDouble( void const *first, void const *second );
+
+BOOL LessThanInt64( void const *first, void const *second );
+BOOL LessThanInt32( void const *first, void const *second );
+BOOL LessThanInt16( void const *first, void const *second );
+BOOL LessThanInt8( void const *first, void const *second );
+BOOL LessThanUInt64( void const *first, void const *second );
+BOOL LessThanUInt32( void const *first, void const *second );
+BOOL LessThanUInt16( void const *first, void const *second );
+BOOL LessThanUInt8( void const *first, void const *second );
+BOOL LessThanFloat( void const *first, void const *second );
+BOOL LessThanDouble( void const *first, void const *second );
+
+BOOL GreaterThanInt64( void const *first, void const *second );
+BOOL GreaterThanInt32( void const *first, void const *second );
+BOOL GreaterThanInt16( void const *first, void const *second );
+BOOL GreaterThanInt8( void const *first, void const *second );
+BOOL GreaterThanUInt64( void const *first, void const *second );
+BOOL GreaterThanUInt32( void const *first, void const *second );
+BOOL GreaterThanUInt16( void const *first, void const *second );
+BOOL GreaterThanUInt8( void const *first, void const *second );
+BOOL GreaterThanFloat( void const *first, void const *second );
+BOOL GreaterThanDouble( void const *first, void const *second );
+
+/* Strings are handled by special iteration functions. */
+
+
+
diff --git a/Searching.m b/Searching.m
new file mode 100644 (file)
index 0000000..2d1ddb5
--- /dev/null
@@ -0,0 +1,720 @@
+//
+//  Searching.m
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 12/28/04.
+//  Copyright 2004 Chaz McGarvey. All rights reserved.
+//
+
+#import "Searching.h"
+
+
+/*
+ * WARNING! BEWARE! WATCH OUT!
+ *
+ * This source code file makes use of goto jump statements.  If goto statements
+ * are disagreeable to you, you may want to skip over this file or you face the
+ * possibility that you will be changed in a very deep and personal way.
+ *
+ * You have been warned.
+ */
+
+
+/* Here are some handy functions used in this file. */
+
+void ReportSearchProgress( ThreadedTask *task, unsigned iteration, unsigned regions, int *progress )
+{
+       int newProgress = (iteration * 100) / regions;
+       if ( newProgress > *progress ) {
+               *progress = newProgress;
+               [task reportProgress:newProgress];
+       }
+}
+
+
+/*
+ * This is a real gem. I have no idea where I got this, but it is a wicked
+ * fast string searching algorithm.  Hope it's not patented...
+ */
+#define ASIZE 256
+void *bmsearch( char *pat, int m, char *text, int n ) {
+       int i,j,k,skip[ASIZE];if(m==0)return 0;
+       for(k=0;k<ASIZE;k++)skip[k]=m;
+       for(k=0;k<m-1;k++)skip[(int)pat[k]]=m-k-1;
+       for(k=m-1;k<n;k+=skip[(int)text[k]&(ASIZE-1)]){
+       for(j=m-1,i=k;j>=0&&text[i]==pat[j];j--)i--;
+       if(j==-1)return(text+i+1);}
+       return NULL;
+}
+
+
+#pragma mark -
+#pragma mark Search Functions
+
+
+int SearchIteration( ThreadedTask *task, unsigned iteration )
+{
+       SearchContext *context = [task context];
+       VMRegion region;
+       unsigned hitsPerRegion = 0;
+       vm_size_t size;
+       
+       void *ptr, *top;
+       TCAddress offset;
+       
+       region = VMNextRegionWithAttributes( context->process, context->lastRegion, VMREGION_READABLE | VMREGION_WRITABLE );
+       if ( VMRegionIsNotNull( region ) ) {
+               
+               if ( context->bufferSize < VMRegionSize( region ) ) {
+                       char *buf = realloc( context->buffer, VMRegionSize( region ) );
+                       if ( buf ) {
+                               context->buffer = buf;
+                               context->bufferSize = VMRegionSize( region );
+                       }
+                       else {
+                               goto FAILURE;
+                       }
+               }
+               
+               if ( !VMRegionBytes( region, context->buffer, &size ) ) {
+                       goto FAILURE;
+               }
+               
+               ptr = context->buffer;
+               top = context->buffer + VMRegionSize( region );
+               offset = VMRegionAddress( region ) - (TCAddress)context->buffer;
+               
+               while ( ptr < top ) {
+                       if ( context->compareFunc(ptr,context->value->_value) ) {
+                               if ( context->numberOfResults >= TCArrayElementCount(context->addresses) ) {
+                                       TCArrayResize( context->addresses, TCArrayElementCount(context->addresses) + TC_BUFFER_SIZE / sizeof(TCAddress) );
+                                       context->addressPtr = (TCAddress *)TCArrayBytes(context->addresses) + context->numberOfResults;
+                               }
+                               if ( context->numberOfResults >= TCArrayElementCount(context->values) ) {
+                                       TCArrayResize( context->values, TCArrayElementCount(context->values) + TC_BUFFER_SIZE / TCArrayElementSize(context->values) );
+                                       context->valuePtr = TCArrayBytes(context->values) + context->numberOfResults * TCArrayElementSize(context->values);
+                               }
+                               
+                               *context->addressPtr = (TCAddress)ptr + offset;
+                               memcpy( context->valuePtr, ptr, TCArrayElementSize( context->values ) );
+                               
+                               context->numberOfResults++;
+                               hitsPerRegion++;
+                               
+                               context->addressPtr++;
+                               context->valuePtr += TCArrayElementSize( context->values );
+                       }
+                       
+                       ptr += TCArrayElementSize( context->values );
+               }
+               
+FAILURE:;
+               if ( hitsPerRegion > 0 ) {
+                       TCAddress addr = VMRegionAddress( region );
+                       unsigned index = TCArrayElementCount( context->regions );
+                       unsigned newsize = index + 1;
+                       
+                       TCArrayResize( context->regions, newsize );
+                       TCArrayResize( context->perRegion, newsize );
+                       
+                       TCArraySetElementAtIndex( context->regions, index, &addr );
+                       TCArraySetElementAtIndex( context->perRegion, index, &hitsPerRegion );
+               }
+               
+               ReportSearchProgress( task, iteration, context->regionCount, &context->progress );
+               
+               context->lastRegion = region;
+               return 1;
+       }
+       else {
+               free( context->buffer );
+               context->buffer = NULL;
+               TCArrayResize( context->addresses, context->numberOfResults );
+               TCArrayResize( context->values, context->numberOfResults );
+               return 0;
+       }
+}
+
+
+int SearchIterationAgain( ThreadedTask *task, unsigned iteration )
+{
+       SearchContext *context = [task context];
+       VMRegion region;
+       unsigned hitsPerRegion = 0;
+       vm_size_t size;
+       
+       void *ptr;
+       unsigned i, top;
+       
+       if ( iteration < TCArrayElementCount( context->lastRegions ) ) {
+               
+               context->lastRegion = VMMakeRegion( context->process, *(context->lastRegionPtr), 0 );
+               region = VMNextRegionWithAttributes( context->process, context->lastRegion, VMREGION_READABLE | VMREGION_WRITABLE );
+               if ( VMRegionIsNotNull( region ) ) {
+                       
+                       if ( context->bufferSize < VMRegionSize( region ) ) {
+                               char *buf = realloc( context->buffer, VMRegionSize( region ) );
+                               if ( buf ) {
+                                       context->buffer = buf;
+                                       context->bufferSize = VMRegionSize( region );
+                               }
+                               else {
+                                       goto FAILURE;
+                               }
+                       }
+                       
+                       if ( !VMRegionBytes( region, context->buffer, &size ) ) {
+                               goto FAILURE;
+                       }
+                       
+                       top = *context->lastPerRegionPtr;
+                       
+                       for ( i = 0; i < top; i++ ) {
+                               
+                               ptr = context->buffer + *context->lastAddressPtr - VMRegionAddress(region);
+                               if ( context->compareFunc(ptr,context->value->_value) ) {
+                                       if ( context->numberOfResults >= TCArrayElementCount(context->addresses) ) {
+                                               TCArrayResize( context->addresses, TCArrayElementCount(context->addresses) + TC_BUFFER_SIZE / sizeof(TCAddress) );
+                                               context->addressPtr = (TCAddress *)TCArrayBytes(context->addresses) + context->numberOfResults;
+                                       }
+                                       if ( context->numberOfResults >= TCArrayElementCount(context->values) ) {
+                                               TCArrayResize( context->values, TCArrayElementCount(context->values) + TC_BUFFER_SIZE / TCArrayElementSize(context->values) );
+                                               context->valuePtr = TCArrayBytes(context->values) + context->numberOfResults * TCArrayElementSize(context->values);
+                                       }
+                                       
+                                       *context->addressPtr = *context->lastAddressPtr;
+                                       memcpy( context->valuePtr, ptr, TCArrayElementSize( context->values ) );
+                                       
+                                       context->numberOfResults++;
+                                       hitsPerRegion++;
+                                       
+                                       context->addressPtr++;
+                                       context->valuePtr += TCArrayElementSize( context->values );
+                               }
+                               
+                               context->lastAddressPtr++;
+                       }
+               }
+               
+FAILURE:;
+               context->lastRegionPtr++;
+               context->lastPerRegionPtr++;
+               
+               if ( hitsPerRegion > 0 ) {
+                       TCAddress addr = VMRegionAddress( region );
+                       unsigned index = TCArrayElementCount( context->regions );
+                       unsigned newsize = index + 1;
+                       
+                       TCArrayResize( context->regions, newsize );
+                       TCArrayResize( context->perRegion, newsize );
+                       
+                       TCArraySetElementAtIndex( context->regions, index, &addr );
+                       TCArraySetElementAtIndex( context->perRegion, index, &hitsPerRegion );
+               }
+               
+               ReportSearchProgress( task, iteration, context->regionCount, &context->progress );
+               
+               context->lastRegion = region;
+               return 1;
+       }
+       else {
+               free( context->buffer );
+               context->buffer = NULL;
+               TCArrayResize( context->addresses, context->numberOfResults );
+               TCArrayResize( context->values, context->numberOfResults );
+               return 0;
+       }
+}
+
+
+int SearchIterationLastValue( ThreadedTask *task, unsigned iteration )
+{
+       SearchContext *context = [task context];
+       VMRegion region;
+       unsigned hitsPerRegion = 0;
+       vm_size_t size;
+       
+       void *ptr;
+       unsigned i, top;
+       
+       if ( iteration < TCArrayElementCount( context->lastRegions ) ) {
+               
+               context->lastRegion = VMMakeRegion( context->process, *(context->lastRegionPtr), 0 );
+               region = VMNextRegionWithAttributes( context->process, context->lastRegion, VMREGION_READABLE | VMREGION_WRITABLE );
+               if ( VMRegionIsNotNull( region ) ) {
+                       
+                       if ( context->bufferSize < VMRegionSize( region ) ) {
+                               char *buf = realloc( context->buffer, VMRegionSize( region ) );
+                               if ( buf ) {
+                                       context->buffer = buf;
+                                       context->bufferSize = VMRegionSize( region );
+                               }
+                               else {
+                                       goto FAILURE;
+                               }
+                       }
+                       
+                       if ( !VMRegionBytes( region, context->buffer, &size ) ) {
+                               goto FAILURE;
+                       }
+                       
+                       top = *context->lastPerRegionPtr;
+                       
+                       for ( i = 0; i < top; i++ ) {
+                               
+                               ptr = context->buffer + *context->lastAddressPtr - VMRegionAddress(region);
+                               if ( context->compareFunc(ptr,context->lastValuePtr) ) {
+                                       if ( context->numberOfResults >= TCArrayElementCount(context->addresses) ) {
+                                               TCArrayResize( context->addresses, TCArrayElementCount(context->addresses) + TC_BUFFER_SIZE / sizeof(TCAddress) );
+                                               context->addressPtr = (TCAddress *)TCArrayBytes(context->addresses) + context->numberOfResults;
+                                       }
+                                       if ( context->numberOfResults >= TCArrayElementCount(context->values) ) {
+                                               TCArrayResize( context->values, TCArrayElementCount(context->values) + TC_BUFFER_SIZE / TCArrayElementSize(context->values) );
+                                               context->valuePtr = TCArrayBytes(context->values) + context->numberOfResults * TCArrayElementSize(context->values);
+                                       }
+                                       
+                                       *context->addressPtr = *context->lastAddressPtr;
+                                       memcpy( context->valuePtr, ptr, TCArrayElementSize(context->values) );
+                                       
+                                       context->numberOfResults++;
+                                       hitsPerRegion++;
+                                       
+                                       context->addressPtr++;
+                                       context->valuePtr += TCArrayElementSize(context->values);
+                               }
+                               
+                               context->lastAddressPtr++;
+                               context->lastValuePtr += TCArrayElementSize(context->values);
+                       }
+               }
+               
+FAILURE:;
+               context->lastRegionPtr++;
+               context->lastPerRegionPtr++;
+               
+               if ( hitsPerRegion > 0 ) {
+                       TCAddress addr = VMRegionAddress( region );
+                       unsigned index = TCArrayElementCount( context->regions );
+                       unsigned newsize = index + 1;
+                       
+                       TCArrayResize( context->regions, newsize );
+                       TCArrayResize( context->perRegion, newsize );
+                       
+                       TCArraySetElementAtIndex( context->regions, index, &addr );
+                       TCArraySetElementAtIndex( context->perRegion, index, &hitsPerRegion );
+               }
+               
+               ReportSearchProgress( task, iteration, context->regionCount, &context->progress );
+               
+               context->lastRegion = region;
+               return 1;
+       }
+       else {
+               free( context->buffer );
+               context->buffer = NULL;
+               TCArrayResize( context->addresses, context->numberOfResults );
+               TCArrayResize( context->values, context->numberOfResults );
+               return 0;
+       }
+}
+
+
+
+int SearchStringIteration( ThreadedTask *task, unsigned iteration )
+{
+       SearchContext *context = [task context];
+       VMRegion region;
+       unsigned hitsPerRegion = 0;
+       vm_size_t size;
+       
+       void *ptr, *top, *hit;
+       TCAddress offset;
+       
+       region = VMNextRegionWithAttributes( context->process, context->lastRegion, VMREGION_READABLE | VMREGION_WRITABLE );
+       if ( VMRegionIsNotNull( region ) ) {
+               
+               if ( context->bufferSize < VMRegionSize(region) ) {
+                       char *buf = realloc( context->buffer, VMRegionSize( region ) );
+                       if ( buf ) {
+                               context->buffer = buf;
+                               context->bufferSize = VMRegionSize(region);
+                       }
+                       else {
+                               goto FAILURE;
+                       }
+               }
+               
+               if ( !VMRegionBytes( region, context->buffer, &size ) ) {
+                       goto FAILURE;
+               }
+               
+               ptr = context->buffer;
+               top = context->buffer + VMRegionSize( region );
+               offset = VMRegionAddress( region ) - (TCAddress)context->buffer;
+               
+               do {
+                       hit = bmsearch( context->value->_value, context->value->_size, ptr, top - ptr );
+                       if ( hit ) {
+                               if ( context->numberOfResults >= TCArrayElementCount(context->addresses) ) {
+                                       TCArrayResize( context->addresses, TCArrayElementCount(context->addresses) + TC_BUFFER_SIZE / sizeof(TCAddress) );
+                                       context->addressPtr = (TCAddress *)TCArrayBytes(context->addresses) + context->numberOfResults;
+                               }
+                               if ( context->numberOfResults >= TCArrayElementCount(context->values) ) {
+                                       TCArrayResize( context->values, TCArrayElementCount(context->values) + TC_BUFFER_SIZE / TCArrayElementSize(context->values) );
+                                       context->valuePtr = TCArrayBytes(context->values) + context->numberOfResults * TCArrayElementSize(context->values);
+                               }
+                               
+                               *context->addressPtr = (TCAddress)hit + offset;
+                               memcpy( context->valuePtr, hit, context->value->_size );
+                               context->addressPtr++;
+                               context->valuePtr += context->value->_size;
+                               
+                               context->numberOfResults++;
+                               hitsPerRegion++;
+                       }
+                       
+                       ptr = hit + 1;
+               }
+               while ( hit );
+               
+FAILURE:;
+               if ( hitsPerRegion > 0 ) {
+                       TCAddress addr = VMRegionAddress( region );
+                       unsigned index = TCArrayElementCount( context->regions );
+                       unsigned newsize = index + 1;
+                       
+                       TCArrayResize( context->regions, newsize );
+                       TCArrayResize( context->perRegion, newsize );
+                       
+                       TCArraySetElementAtIndex( context->regions, index, &addr );
+                       TCArraySetElementAtIndex( context->perRegion, index, &hitsPerRegion );
+               }
+               
+               ReportSearchProgress( task, iteration, context->regionCount, &context->progress );
+               
+               context->lastRegion = region;
+               return 1;
+       }
+       else {
+               free( context->buffer );
+               context->buffer = NULL;
+               TCArrayResize( context->addresses, context->numberOfResults );
+               TCArrayResize( context->values, context->numberOfResults );
+               return 0;
+       }
+}
+
+int SearchStringIterationAgain( ThreadedTask *task, unsigned iteration )
+{
+       SearchContext *context = [task context];
+       VMRegion region;
+       unsigned hitsPerRegion = 0;
+       vm_size_t size;
+       
+       void *ptr;
+       unsigned i, top;
+       
+       if ( iteration < TCArrayElementCount( context->lastRegions ) ) {
+               
+               context->lastRegion = VMMakeRegion( context->process, *(context->lastRegionPtr), 0 );
+               region = VMNextRegionWithAttributes( context->process, context->lastRegion, VMREGION_READABLE | VMREGION_WRITABLE );
+               if ( VMRegionIsNotNull( region ) ) {
+                       
+                       if ( context->bufferSize < VMRegionSize( region ) ) {
+                               char *buf = realloc( context->buffer, VMRegionSize( region ) );
+                               if ( buf ) {
+                                       context->buffer = buf;
+                                       context->bufferSize = VMRegionSize( region );
+                               }
+                               else {
+                                       goto FAILURE;
+                               }
+                       }
+                       
+                       if ( !VMRegionBytes( region, context->buffer, &size ) ) {
+                               goto FAILURE;
+                       }
+                       
+                       top = *context->lastPerRegionPtr;
+                       
+                       for ( i = 0; i < top; i++ ) {
+                               
+                               ptr = context->buffer + *context->lastAddressPtr - VMRegionAddress(region);
+                               if ( memcmp( ptr, context->value->_value, MIN(TCArrayElementSize(context->values),context->buffer+VMRegionAddress(region)-ptr) ) == 0 ) {
+                                       if ( context->numberOfResults >= TCArrayElementCount(context->addresses) ) {
+                                               TCArrayResize( context->addresses, TCArrayElementCount(context->addresses) + TC_BUFFER_SIZE / sizeof(TCAddress) );
+                                               context->addressPtr = (TCAddress *)TCArrayBytes(context->addresses) + context->numberOfResults;
+                                       }
+                                       if ( context->numberOfResults >= TCArrayElementCount(context->values) ) {
+                                               TCArrayResize( context->values, TCArrayElementCount(context->values) + TC_BUFFER_SIZE / TCArrayElementSize(context->values) );
+                                               context->valuePtr = TCArrayBytes(context->values) + context->numberOfResults * TCArrayElementSize(context->values);
+                                       }
+                                       
+                                       *context->addressPtr = *context->lastAddressPtr;
+                                       memcpy( context->valuePtr, ptr, TCArrayElementSize( context->values ) );
+                                       context->addressPtr++;
+                                       context->valuePtr += TCArrayElementSize( context->values );
+                                       
+                                       context->numberOfResults++;
+                                       hitsPerRegion++;
+                               }
+                               
+                               context->lastAddressPtr++;
+                       }
+               }
+               
+FAILURE:;
+               context->lastRegionPtr++;
+               context->lastPerRegionPtr++;
+               
+               if ( hitsPerRegion > 0 ) {
+                       TCAddress addr = VMRegionAddress( region );
+                       unsigned index = TCArrayElementCount( context->regions );
+                       unsigned newsize = index + 1;
+                       
+                       TCArrayResize( context->regions, newsize );
+                       TCArrayResize( context->perRegion, newsize );
+                       
+                       TCArraySetElementAtIndex( context->regions, index, &addr );
+                       TCArraySetElementAtIndex( context->perRegion, index, &hitsPerRegion );
+               }
+               
+               ReportSearchProgress( task, iteration, context->regionCount, &context->progress );
+               
+               context->lastRegion = region;
+               return 1;
+       }
+       else {
+               free( context->buffer );
+               context->buffer = NULL;
+               TCArrayResize( context->addresses, context->numberOfResults );
+               TCArrayResize( context->values, context->numberOfResults );
+               return 0;
+       }
+}
+
+int SearchStringIterationLastValue( ThreadedTask *task, unsigned iteration )
+{
+       SearchContext *context = [task context];
+       VMRegion region;
+       unsigned hitsPerRegion = 0;
+       vm_size_t size;
+       
+       void *ptr;
+       unsigned i, top;
+       
+       if ( iteration < TCArrayElementCount( context->lastRegions ) ) {
+               
+               context->lastRegion = VMMakeRegion( context->process, *(context->lastRegionPtr), 0 );
+               region = VMNextRegionWithAttributes( context->process, context->lastRegion, VMREGION_READABLE | VMREGION_WRITABLE );
+               if ( VMRegionIsNotNull( region ) ) {
+                       
+                       if ( context->bufferSize < VMRegionSize( region ) ) {
+                               char *buf = realloc( context->buffer, VMRegionSize( region ) );
+                               if ( buf ) {
+                                       context->buffer = buf;
+                                       context->bufferSize = VMRegionSize( region );
+                               }
+                               else {
+                                       goto FAILURE;
+                               }
+                       }
+                       
+                       if ( !VMRegionBytes( region, context->buffer, &size ) ) {
+                               goto FAILURE;
+                       }
+                       
+                       top = *context->lastPerRegionPtr;
+                       
+                       for ( i = 0; i < top; i++ ) {
+                               
+                               ptr = context->buffer + *context->lastAddressPtr - VMRegionAddress(region);
+                               if ( memcmp( ptr, context->lastValuePtr, MIN(TCArrayElementSize(context->values),context->buffer+VMRegionAddress(region)-ptr) ) == 0 ) {
+                                       if ( context->numberOfResults >= TCArrayElementCount(context->addresses) ) {
+                                               TCArrayResize( context->addresses, TCArrayElementCount(context->addresses) + TC_BUFFER_SIZE / sizeof(TCAddress) );
+                                               context->addressPtr = (TCAddress *)TCArrayBytes(context->addresses) + context->numberOfResults;
+                                       }
+                                       if ( context->numberOfResults >= TCArrayElementCount(context->values) ) {
+                                               TCArrayResize( context->values, TCArrayElementCount(context->values) + TC_BUFFER_SIZE / TCArrayElementSize(context->values) );
+                                               context->valuePtr = TCArrayBytes(context->values) + context->numberOfResults * TCArrayElementSize(context->values);
+                                       }
+                                       
+                                       *context->addressPtr = *context->lastAddressPtr;
+                                       memcpy( context->valuePtr, ptr, TCArrayElementSize(context->values) );
+                                       context->addressPtr++;
+                                       context->valuePtr += TCArrayElementSize(context->values);
+                                       
+                                       context->numberOfResults++;
+                                       hitsPerRegion++;
+                               }
+                               
+                               context->lastAddressPtr++;
+                               context->lastValuePtr += TCArrayElementSize(context->lastValues);
+                       }
+               }
+               
+FAILURE:;
+               context->lastRegionPtr++;
+               context->lastPerRegionPtr++;
+               
+               if ( hitsPerRegion > 0 ) {
+                       TCAddress addr = VMRegionAddress( region );
+                       unsigned index = TCArrayElementCount( context->regions );
+                       unsigned newsize = index + 1;
+                       
+                       TCArrayResize( context->regions, newsize );
+                       TCArrayResize( context->perRegion, newsize );
+                       
+                       TCArraySetElementAtIndex( context->regions, index, &addr );
+                       TCArraySetElementAtIndex( context->perRegion, index, &hitsPerRegion );
+               }
+               
+               ReportSearchProgress( task, iteration, context->regionCount, &context->progress );
+               
+               context->lastRegion = region;
+               return 1;
+       }
+       else {
+               free( context->buffer );
+               context->buffer = NULL;
+               TCArrayResize( context->addresses, context->numberOfResults );
+               TCArrayResize( context->values, context->numberOfResults );
+               return 0;
+       }
+}
+
+
+
+#pragma mark -
+#pragma mark Comparison Functions
+
+
+
+BOOL EqualInt64( void const *first, void const *second ) {
+       return *(SInt64 *)first == *(SInt64 *)second;
+}
+BOOL EqualInt32( void const *first, void const *second ) {
+       return *(SInt32 *)first == *(SInt32 *)second;
+}
+BOOL EqualInt16( void const *first, void const *second ) {
+       return *(SInt16 *)first == *(SInt16 *)second;
+}
+BOOL EqualInt8( void const *first, void const *second ) {
+       return *(SInt8 *)first == *(SInt8 *)second;
+}
+BOOL EqualUInt64( void const *first, void const *second ) {
+       return *(UInt64 *)first == *(UInt64 *)second;
+}
+BOOL EqualUInt32( void const *first, void const *second ) {
+       return *(UInt32 *)first == *(UInt32 *)second;
+}
+BOOL EqualUInt16( void const *first, void const *second ) {
+       return *(UInt16 *)first == *(UInt16 *)second;
+}
+BOOL EqualUInt8( void const *first, void const *second ) {
+       return *(UInt8 *)first == *(UInt8 *)second;
+}
+BOOL EqualFloat( void const *first, void const *second ) {
+       return TC_EPSILON > ABS( *(float *)first - *(float *)second );
+}
+BOOL EqualDouble( void const *first, void const *second ) {
+       return TC_EPSILON > ABS( *(double *)first - *(double *)second );
+}
+
+BOOL NotEqualInt64( void const *first, void const *second ) {
+       return *(SInt64 *)first != *(SInt64 *)second;
+}
+BOOL NotEqualInt32( void const *first, void const *second ) {
+       return *(SInt32 *)first != *(SInt32 *)second;
+}
+BOOL NotEqualInt16( void const *first, void const *second ) {
+       return *(SInt16 *)first != *(SInt16 *)second;
+}
+BOOL NotEqualInt8( void const *first, void const *second ) {
+       return *(SInt8 *)first != *(SInt8 *)second;
+}
+BOOL NotEqualUInt64( void const *first, void const *second ) {
+       return *(UInt64 *)first != *(UInt64 *)second;
+}
+BOOL NotEqualUInt32( void const *first, void const *second ) {
+       return *(UInt32 *)first != *(UInt32 *)second;
+}
+BOOL NotEqualUInt16( void const *first, void const *second ) {
+       return *(UInt16 *)first != *(UInt16 *)second;
+}
+BOOL NotEqualUInt8( void const *first, void const *second ) {
+       return *(UInt8 *)first != *(UInt8 *)second;
+}
+BOOL NotEqualFloat( void const *first, void const *second ) {
+       return TC_EPSILON <= ABS( *(float *)first - *(float *)second );
+}
+BOOL NotEqualDouble( void const *first, void const *second ) {
+       return TC_EPSILON <= ABS( *(double *)first - *(double *)second );
+}
+
+BOOL LessThanInt64( void const *first, void const *second ) {
+       return *(SInt64 *)first < *(SInt64 *)second;
+}
+BOOL LessThanInt32( void const *first, void const *second ) {
+       return *(SInt32 *)first < *(SInt32 *)second;
+}
+BOOL LessThanInt16( void const *first, void const *second ) {
+       return *(SInt16 *)first < *(SInt16 *)second;
+}
+BOOL LessThanInt8( void const *first, void const *second ) {
+       return *(SInt8 *)first < *(SInt8 *)second;
+}
+BOOL LessThanUInt64( void const *first, void const *second ) {
+       return *(UInt64 *)first < *(UInt64 *)second;
+}
+BOOL LessThanUInt32( void const *first, void const *second ) {
+       return *(UInt32 *)first < *(UInt32 *)second;
+}
+BOOL LessThanUInt16( void const *first, void const *second ) {
+       return *(UInt16 *)first < *(UInt16 *)second;
+}
+BOOL LessThanUInt8( void const *first, void const *second ) {
+       return *(UInt8 *)first < *(UInt8 *)second;
+}
+BOOL LessThanFloat( void const *first, void const *second ) {
+       return *(float *)first < *(float *)second;
+}
+BOOL LessThanDouble( void const *first, void const *second ) {
+       return *(double *)first < *(double *)second;
+}
+
+BOOL GreaterThanInt64( void const *first, void const *second ) {
+       return *(SInt64 *)first > *(SInt64 *)second;
+}
+BOOL GreaterThanInt32( void const *first, void const *second ) {
+       return *(SInt32 *)first > *(SInt32 *)second;
+}
+BOOL GreaterThanInt16( void const *first, void const *second ) {
+       return *(SInt16 *)first > *(SInt16 *)second;
+}
+BOOL GreaterThanInt8( void const *first, void const *second ) {
+       return *(SInt8 *)first > *(SInt8 *)second;
+}
+BOOL GreaterThanUInt64( void const *first, void const *second ) {
+       return *(UInt64 *)first > *(UInt64 *)second;
+}
+BOOL GreaterThanUInt32( void const *first, void const *second ) {
+       return *(UInt32 *)first > *(UInt32 *)second;
+}
+BOOL GreaterThanUInt16( void const *first, void const *second ) {
+       return *(UInt16 *)first > *(UInt16 *)second;
+}
+BOOL GreaterThanUInt8( void const *first, void const *second ) {
+       return *(UInt8 *)first > *(UInt8 *)second;
+}
+BOOL GreaterThanFloat( void const *first, void const *second ) {
+       return *(float *)first > *(float *)second;
+}
+BOOL GreaterThanDouble( void const *first, void const *second ) {
+       return *(double *)first > *(double *)second;
+}
+
+
+
+
+
diff --git a/Server.png b/Server.png
new file mode 100644 (file)
index 0000000..2828d3e
Binary files /dev/null and b/Server.png differ
diff --git a/ServerChild.h b/ServerChild.h
new file mode 100644 (file)
index 0000000..66d65a3
--- /dev/null
@@ -0,0 +1,67 @@
+
+// **********************************************************************
+// 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 <Cocoa/Cocoa.h>
+#import "ChazLog.h"
+
+#import "MySocket.h"
+
+#import "LocalCheater.h"
+#import "Cheater.h"
+
+#include <string.h>
+
+
+@interface ServerChild : NSObject < CheaterDelegate >
+{
+       MySocket *_socket;
+       NSString *_client;
+       
+       LocalCheater *_cheater;
+       
+       /* the current packet being read. */
+       TCPacketHeader _header;
+       NSData *_parameters;
+       
+       id _delegate;
+}
+
+- (id)initWithSocket:(MySocket *)sock;
+- (id)initWithSocket:(MySocket *)sock delegate:(id)delegate;
+
+- (NSString *)host;
+- (NSString *)transfer;
+
+- (id)delegate;
+- (void)setDelegate:(id)delegate;
+
+@end
+
+
+@interface NSObject ( ServerChildDelegate )
+
+// informs the cheat server of connection status
+- (void)serverChildConnected:(ServerChild *)theChild;
+- (void)serverChildDisconnected:(ServerChild *)theChild;
+
+// inform the cheat server something about the child changed.
+- (void)serverChildChanged:(ServerChild *)theChild;
+
+@end
\ No newline at end of file
diff --git a/ServerChild.m b/ServerChild.m
new file mode 100644 (file)
index 0000000..501b380
--- /dev/null
@@ -0,0 +1,471 @@
+
+// **********************************************************************
+// 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 "ServerChild.h"
+
+
+@interface ServerChild ( PrivateAPI )
+
+- (void)_handlePacket;
+
+- (void)_setClient:(NSString *)status;
+
+@end
+
+
+@implementation ServerChild
+
+
+- (id)initWithSocket:(MySocket *)sock
+{
+       return [self initWithSocket:sock delegate:nil];
+}
+
+- (id)initWithSocket:(MySocket *)sock delegate:(id)delegate
+{
+       if ( self = [super init] ) {
+               _socket = [sock retain];
+               [_socket setDelegate:self];
+               _delegate = delegate;
+               
+               // create the cheater object
+               _cheater = [[LocalCheater alloc] initWithDelegate:self];
+               [_cheater setShouldCopy:NO];
+               
+               // start reading from the socket
+               [_socket readDataToLength:sizeof(TCPacketHeader) tag:0];
+               
+               if ( [_delegate respondsToSelector:@selector(serverChildConnected:)] ) {
+                       [_delegate serverChildConnected:self];
+               }
+       }
+       return self;
+}
+
+- (void)dealloc
+{
+       //[_socket setDelegate:[self class]];
+       //[_socket disconnect];
+       [_socket setDelegate:nil];
+       [_socket release];
+       
+       [_client release];
+       [_parameters release];
+       [_cheater release];
+       [super dealloc];
+}
+
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark MySocketDelegate
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+- (void)socket:(MySocket *)mySocket didReadData:(NSData *)theData tag:(int)tag
+{
+       if ( tag == 0 && [theData length] == sizeof(TCPacketHeader) ) {
+               // got a packet header
+               memcpy( &_header, [theData bytes], sizeof(TCPacketHeader) );
+               if ( _header.size > 0 ) {
+                       // request the rest of the packet
+                       [mySocket readDataToLength:_header.size tag:1];
+               }
+               else {
+                       [self _handlePacket];
+                       // start reading the next packet
+                       [mySocket readDataToLength:sizeof(TCPacketHeader) tag:0];
+               }
+       }
+       else if ( tag == 1 && [theData length] == _header.size ) {
+               // got packet parameter data
+               _parameters = [theData retain];
+               [self _handlePacket];
+               // start reading the next packet
+               [mySocket readDataToLength:sizeof(TCPacketHeader) tag:0];
+       }
+       else {
+               ChazLog( @"ServerChild - read unexpected data, disconnecting..." );
+               [_socket release];
+               _socket = nil;
+               if ( [_delegate respondsToSelector:@selector(serverChildDisconnected:)] ) {
+                       [_delegate serverChildDisconnected:self];
+               }
+       }
+}
+
+- (void)socketDidDisconnect:(MySocket *)mySocket
+{
+       [_socket release];
+       _socket = nil;
+       
+       if ( [_delegate respondsToSelector:@selector(serverChildDisconnected:)] ) {
+               [_delegate serverChildDisconnected:self];
+       }
+}
+
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark Accessors
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+- (NSString *)host
+{
+       return [_socket remoteHost];
+}
+
+- (NSString *)transfer
+{
+       unsigned bytes = [_socket bytesRead] + [_socket bytesWritten];
+       double speed = [_socket readSpeed] + [_socket writeSpeed];
+
+       if ( speed > 0.0 ) {
+               return [NSString stringWithFormat:@"%.1fMB (%.1fkbps)", (float)bytes/1038576.0f, (float)speed/1024.0f];
+       }
+       return [NSString stringWithFormat:@"%.1fMB", (float)bytes/1038576.0f];
+}
+
+
+- (id)delegate
+{
+       return _delegate;
+}
+
+- (void)setDelegate:(id)delegate
+{
+       _delegate = delegate;
+}
+
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark PrivateAPI
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+- (void)_handlePacket
+{
+       if ( strncmp( "connect", _header.name, sizeof(_header.name) ) == 0 ) {
+               ChazLog( @"ServerChild - connect received!!" );
+               [_cheater connect];
+               [self _setClient:[NSUnarchiver unarchiveObjectWithData:_parameters]];
+       }
+       else if ( strncmp( "authenticate", _header.name, sizeof(_header.name) ) == 0 ) {
+               ChazLog( @"ServerChild - process list requested" );
+               [_cheater authenticateWithPassword:[NSUnarchiver unarchiveObjectWithData:_parameters]];
+       }
+       else if ( strncmp( "getproclist", _header.name, sizeof(_header.name) ) == 0 ) {
+               ChazLog( @"ServerChild - process list requested" );
+               [_cheater getProcessList];
+       }
+       else if ( strncmp( "settarget", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_cheater setTarget:[NSUnarchiver unarchiveObjectWithData:_parameters]];
+       }
+       else if ( strncmp( "pausetarget", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_cheater pauseTarget];
+       }
+       else if ( strncmp( "resumetarget", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_cheater resumeTarget];
+       }
+       else if ( strncmp( "limitresults", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_cheater limitReturnedResults:[[NSUnarchiver unarchiveObjectWithData:_parameters] unsignedIntValue]];
+       }
+       else if ( strncmp( "search", _header.name, sizeof(_header.name) ) == 0 ) {
+               NSArray *params = [NSUnarchiver unarchiveObjectWithData:_parameters];
+               [_cheater searchForVariable:[params objectAtIndex:0] comparison:[[params objectAtIndex:1] unsignedCharValue]];
+       }
+       else if ( strncmp( "lastsearch", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_cheater searchLastValuesComparison:[[NSUnarchiver unarchiveObjectWithData:_parameters] unsignedCharValue]];
+       }
+       else if ( strncmp( "cancelsearch", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_cheater cancelSearch];
+       }
+       else if ( strncmp( "clearsearch", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_cheater clearSearch];
+       }
+       else if ( strncmp( "dump", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_cheater getMemoryDump];
+       }
+       else if ( strncmp( "canceldump", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_cheater cancelMemoryDump];
+       }
+       else if ( strncmp( "changevars", _header.name, sizeof(_header.name) ) == 0 ) {
+               NSArray *params = [NSUnarchiver unarchiveObjectWithData:_parameters];
+               [_cheater makeVariableChanges:[params objectAtIndex:0] repeat:[[params objectAtIndex:1] boolValue]
+                                                        interval:[[params objectAtIndex:2] doubleValue]];
+       }
+       else if ( strncmp( "stopchange", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_cheater stopChangingVariables];
+       }
+       else if ( strncmp( "undo", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_cheater undo];
+       }
+       else if ( strncmp( "redo", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_cheater redo];
+       }
+       else if ( strncmp( "watchvars", _header.name, sizeof(_header.name) ) == 0 ) {
+               NSArray *params = [NSUnarchiver unarchiveObjectWithData:_parameters];
+               [_cheater watchVariablesAtIndex:[[params objectAtIndex:0] unsignedIntValue] count:[[params objectAtIndex:1] unsignedIntValue]
+                                                        interval:[[params objectAtIndex:2] doubleValue]];
+       }
+       else if ( strncmp( "stopwatch", _header.name, sizeof(_header.name) ) == 0 ) {
+               [_cheater stopWatchingVariables];
+       }
+       
+       [_parameters release];
+       _parameters = nil;
+}
+
+
+- (void)_setClient:(NSString *)client
+{
+       [client retain];
+       [_client release];
+       _client = client;
+       if ( [_delegate respondsToSelector:@selector(serverChildChanged:)] ) {
+               [_delegate serverChildChanged:self];
+       }
+}
+
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#pragma mark CheaterDelegate
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+
+- (void)cheaterDidConnect:(Cheater *)cheater
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "connected" };
+       ChazLog( @"SENT didconnect" );
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+- (void)cheaterDidDisconnect:(Cheater *)cheater
+{
+       // nothing needs to be done
+}
+
+
+- (void)cheaterRequiresAuthentication:(Cheater *)cheater
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "requireauth" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+- (void)cheaterRejectedPassword:(Cheater *)cheater
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "rejectedauth" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+- (void)cheaterAcceptedPassword:(Cheater *)cheater
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "authenticated" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+
+- (void)cheater:(Cheater *)cheater didFindProcesses:(NSArray *)processes
+{      
+       NSData *params = [NSArchiver archivedDataWithRootObject:processes];
+       TCPacketHeader header = { TC_NIFTY, [params length], "proclist" };
+       
+       ChazLog( @"SENT proclist" );
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeData:params tag:0];
+
+}
+
+- (void)cheater:(Cheater *)cheater didAddProcess:(Process *)process
+{
+       NSData *params = [NSArchiver archivedDataWithRootObject:process];
+       TCPacketHeader header = { TC_NIFTY, [params length], "addprocess" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeData:params tag:0];
+}
+
+- (void)cheater:(Cheater *)cheater didRemoveProcess:(Process *)process
+{
+       NSData *params = [NSArchiver archivedDataWithRootObject:process];
+       TCPacketHeader header = { TC_NIFTY, [params length], "removeprocess" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeData:params tag:0];
+}
+
+
+- (void)cheater:(Cheater *)cheater didSetTarget:(Process *)target
+{
+       NSData *params = [NSArchiver archivedDataWithRootObject:target];
+       TCPacketHeader header = { TC_NIFTY, [params length], "didsettarget" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeData:params tag:0];
+}
+
+- (void)cheaterPausedTarget:(Cheater *)cheater
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "didpausetarget" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+- (void)cheaterResumedTarget:(Cheater *)cheater
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "didresumetarget" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+
+- (void)cheater:(Cheater *)cheater didFindVariables:(TCArray)variables actualAmount:(unsigned)count
+{
+       struct {
+               unsigned actualAmount;
+               unsigned varCount;
+               unsigned varSize;
+       } varInfo = { count, TCArrayElementCount(variables), TCArrayElementSize(variables) };
+       unsigned bufferLen = varInfo.varCount * varInfo.varSize;
+       
+       TCPacketHeader header = { TC_NIFTY, sizeof(varInfo) + bufferLen, "vars" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeBytes:&varInfo length:sizeof(varInfo) tag:0];
+       [_socket writeBytes:TCArrayBytes(variables) length:bufferLen tag:0];
+       
+       TCReleaseArray( variables );
+}
+
+- (void)cheater:(Cheater *)cheater didFindValues:(TCArray)values
+{
+       struct {
+               unsigned varCount;
+               unsigned varSize;
+       } varInfo = { TCArrayElementCount(values), TCArrayElementSize(values) };
+       unsigned bufferLen = varInfo.varCount * varInfo.varSize;
+       
+       TCPacketHeader header = { TC_NIFTY, sizeof(varInfo) + bufferLen, "values" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeBytes:&varInfo length:sizeof(varInfo) tag:0];
+       [_socket writeBytes:TCArrayBytes(values) length:bufferLen tag:0];
+       
+       TCReleaseArray( values );
+}
+
+- (void)cheaterDidCancelSearch:(Cheater *)cheater
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "didcancelsearch" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+- (void)cheaterDidClearSearch:(Cheater *)cheater
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "didclearsearch" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+
+- (void)cheater:(Cheater *)cheater didDumpMemory:(NSData *)memoryDump
+{
+       TCPacketHeader header = { TC_NIFTY, [memoryDump length], "memdump" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeData:memoryDump tag:0];
+}
+
+- (void)cheaterDidCancelMemoryDump:(Cheater *)cheater
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "didcanceldump" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+
+- (void)cheater:(Cheater *)cheater didChangeVariables:(unsigned)changeCount
+{
+       NSData *params = [NSArchiver archivedDataWithRootObject:[NSNumber numberWithUnsignedInt:changeCount]];
+       TCPacketHeader header = { TC_NIFTY, [params length], "changedvars" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeData:params tag:0];
+}
+
+- (void)cheaterDidStopChangingVariables:(Cheater *)cheater
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "didstopchanging" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+
+- (void)cheater:(Cheater *)cheater didReportProgress:(int)progress
+{
+       NSData *params = [NSArchiver archivedDataWithRootObject:[NSNumber numberWithInt:progress]];
+       TCPacketHeader header = { TC_NIFTY, [params length], "progress" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeData:params tag:0];
+}
+
+
+- (void)cheater:(Cheater *)cheater didRevertToVariables:(TCArray)variables actualAmount:(unsigned)count
+{
+       struct {
+               unsigned actualAmount;
+               unsigned varCount;
+               unsigned varSize;
+       } varInfo = { count, TCArrayElementCount(variables), TCArrayElementSize(variables) };
+       unsigned bufferLen = varInfo.varCount * varInfo.varSize;
+       
+       TCPacketHeader header = { TC_NIFTY, sizeof(varInfo) + bufferLen, "revertedto" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeBytes:&varInfo length:sizeof(varInfo) tag:0];
+       [_socket writeBytes:TCArrayBytes(variables) length:bufferLen tag:0];
+       
+       TCReleaseArray( variables );
+}
+
+
+- (void)cheaterDidUndo:(Cheater *)cheater
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "didundo" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+- (void)cheaterDidRedo:(Cheater *)cheater
+{
+       TCPacketHeader header = { TC_NIFTY, 0, "didredo" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+}
+
+
+- (void)cheater:(Cheater *)cheater variableAtIndex:(unsigned)index didChangeTo:(Variable *)variable
+{
+       NSData *params = [NSArchiver archivedDataWithRootObject:[NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:index], variable, nil]];
+       TCPacketHeader header = { TC_NIFTY, [params length], "varchanged" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeData:params tag:0];
+}
+
+
+- (void)cheater:(Cheater *)cheater didFailLastRequest:(NSString *)reason
+{
+       NSData *params = [NSArchiver archivedDataWithRootObject:reason];
+       TCPacketHeader header = { TC_NIFTY, [params length], "failed" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeData:params tag:0];
+}
+
+- (void)cheater:(Cheater *)cheater echo:(NSString *)message
+{
+       NSData *params = [NSArchiver archivedDataWithRootObject:message];
+       TCPacketHeader header = { TC_NIFTY, [params length], "echo" };
+       [_socket writeBytes:&header length:sizeof(header) tag:0];
+       [_socket writeData:params tag:0];
+}
+
+
+@end
diff --git a/ServerDelegate.h b/ServerDelegate.h
deleted file mode 100644 (file)
index f9ee572..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      ServerDelegate.h
-// Created:   Thu Sep 25 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#import <Cocoa/Cocoa.h>
-
-#include <sys/types.h>
-
-@class CheatServer;
-
-
-@protocol ServerDelegate
-
-- (void)server:(CheatServer *)server connectedWithSocket:(int)sock;
-- (void)serverDisconnected:(CheatServer *)server;
-
-- (void)server:(CheatServer *)server changedAddress:(NSString *)address;
-- (void)server:(CheatServer *)server changedAction:(NSString *)action;
-
-- (NSArray *)serverProcessList;
-- (pid_t)serverFirstProcess;
-
-@end
\ No newline at end of file
diff --git a/ServerDelegate.m b/ServerDelegate.m
deleted file mode 100644 (file)
index 94e7b2d..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      ServerDelegate.m
-// Created:   Thu Sep 25 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#import "ServerDelegate.h"
-
-
-@implementation ServerDelegate
-
-
-
-@end
\ No newline at end of file
diff --git a/ServerHolder.h b/ServerHolder.h
deleted file mode 100644 (file)
index e0342ad..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      ServerHolder.h
-// Created:   Sun Sep 28 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#import <Cocoa/Cocoa.h>
-
-
-@class CheatServer;
-
-
-@interface ServerHolder : NSObject
-{
-       NSConnection            *connection;
-       CheatServer                     *server;
-       int                                     sockfd;
-
-       NSString                        *address;
-       NSString                        *action;
-}
-
-+ (ServerHolder *)holderWithConnection:(NSConnection *)conn socket:(int)sock;
-- (id)initWithConnection:(NSConnection *)conn socket:(int)sock;
-
-- (NSConnection *)connection;
-- (void)setConnection:(NSConnection *)conn;
-- (CheatServer *)server;
-- (void)setServer:(CheatServer *)serv;
-- (int)sockfd;
-- (void)setSockFD:(int)sock;
-
-- (NSString *)address;
-- (void)setAddress:(NSString *)addr;
-- (NSString *)action;
-- (void)setAction:(NSString *)act;
-
-@end
\ No newline at end of file
diff --git a/ServerHolder.m b/ServerHolder.m
deleted file mode 100644 (file)
index d6f7290..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      ServerHolder.m
-// Created:   Sun Sep 28 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#import "ServerHolder.h"
-
-#import "CheatServer.h"
-
-
-@implementation ServerHolder
-
-
-+ (ServerHolder *)holderWithConnection:(NSConnection *)conn socket:(int)sock
-{
-       return [[[ServerHolder alloc] initWithConnection:conn socket:sock] autorelease];
-}
-
-- (id)initWithConnection:(NSConnection *)conn socket:(int)sock
-{
-       if ( self = [super init] )
-       {
-               connection = [conn retain];
-               sockfd = sock;
-       }
-
-       return self;
-}
-
-
-- (NSConnection *)connection
-{
-       return connection;
-}
-
-- (void)setConnection:(NSConnection *)conn
-{
-       [connection release];
-       connection = [conn retain];
-}
-
-- (CheatServer *)server
-{
-       return server;
-}
-
-- (void)setServer:(CheatServer *)serv
-{
-       [server release];
-       server = [serv retain];
-}
-
-
-- (int)sockfd
-{
-       return sockfd;
-}
-
-- (void)setSockFD:(int)sock
-{
-       sockfd = sock;
-}
-
-
-- (NSString *)address
-{
-       return address;
-}
-
-- (void)setAddress:(NSString *)addr
-{
-       [address release];
-       address = [addr retain];
-}
-
-- (NSString *)action
-{
-       return action;
-}
-
-- (void)setAction:(NSString *)act
-{
-       [action release];
-       action = [act retain];
-}
-
-
-- (void)dealloc
-{
-       [connection release];
-       [server release];
-
-       [super dealloc];
-}
-
-
-@end
\ No newline at end of file
diff --git a/ServerPrefs.h b/ServerPrefs.h
new file mode 100644 (file)
index 0000000..e35037e
--- /dev/null
@@ -0,0 +1,46 @@
+
+// **********************************************************************
+// 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 <Cocoa/Cocoa.h>
+#import "ChazLog.h"
+
+#include "cheat_global.h"
+
+#import "StatusTextField.h"
+
+
+@interface ServerPrefs : NSObject
+{
+       IBOutlet StatusTextField *ibStatusField;
+       IBOutlet NSTextField *ibNameField;
+       IBOutlet NSTextField *ibPortField;
+       IBOutlet NSButton *ibStartButton;
+       IBOutlet NSTableView *ibSessionTable;
+       IBOutlet NSTextField *ibDefaultPortText;
+       
+       NSTimer *_tableTimer;
+}
+
+- (IBAction)ibSetListenPort:(id)sender;
+- (IBAction)ibSetBroadcast:(id)sender;
+
+- (IBAction)ibStartServer:(id)sender;
+
+@end
diff --git a/ServerPrefs.m b/ServerPrefs.m
new file mode 100644 (file)
index 0000000..ce1214b
--- /dev/null
@@ -0,0 +1,208 @@
+
+// **********************************************************************
+// 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 "ServerPrefs.h"
+
+#include "cheat_global.h"
+
+#import "AppController.h"
+
+#import "CheatServer.h"
+#import "ServerChild.h"
+
+
+@interface ServerPrefs ( PrivateAPI )
+
+- (void)_serverStarted:(NSNotification *)note;
+- (void)_serverStopped:(NSNotification *)note;
+- (void)_childrenChanged:(NSNotification *)note;
+
+@end
+
+
+@implementation ServerPrefs
+
+
+- (id)init
+{
+       if ( self = [super init] ) {
+               NSNotificationCenter *nc= [NSNotificationCenter defaultCenter];
+               
+               // register for server notifications
+               [nc addObserver:self selector:@selector(_serverStarted:) name:TCServerStartedNote object:nil];
+               [nc addObserver:self selector:@selector(_serverStopped:) name:TCServerStoppedNote object:nil];
+               [nc addObserver:self selector:@selector(_childrenChanged:) name:TCServerConnectionsChangedNote object:nil];
+       }
+       return self;
+}
+
+- (void)dealloc
+{
+       [[NSNotificationCenter defaultCenter] removeObserver:self];
+       [super dealloc];
+}
+
+
+- (void)awakeFromNib
+{
+       [ibDefaultPortText setStringValue:[NSString stringWithFormat:@"Default cheat port is %i.", TCDefaultListenPort]];
+       
+       // set initial states
+       [ibNameField setStringValue:[[NSUserDefaults standardUserDefaults] objectForKey:TCBroadcastNamePref]];
+       [ibPortField setIntValue:[[NSUserDefaults standardUserDefaults] integerForKey:TCListenPortPref]];
+       
+       if ( [[NSApp cheatServer] isListening] ) {
+               [self _serverStarted:nil];
+       }
+       else {
+               [self _serverStopped:nil];
+       }
+}
+
+
+
+- (IBAction)ibSetListenPort:(id)sender
+{
+       short unsigned port = [ibPortField intValue];
+       
+       if ( port < 1024 ) {
+               port = TCDefaultListenPort;
+               [sender setIntValue:port];
+       }
+       
+       [[NSUserDefaults standardUserDefaults] setInteger:[ibPortField intValue] forKey:TCListenPortPref];
+}
+
+- (IBAction)ibSetBroadcast:(id)sender
+{
+       [[NSUserDefaults standardUserDefaults] setObject:[ibNameField stringValue] forKey:TCBroadcastNamePref];
+}
+
+- (IBAction)ibStartServer:(id)sender
+{
+       CheatServer *server = [NSApp cheatServer];
+       
+       [self ibSetListenPort:nil];
+       [self ibSetBroadcast:nil];
+       
+       if ( [server isListening] ) {
+               // stop it
+               [[NSUserDefaults standardUserDefaults] setBool:NO forKey:TCRunServerPref];
+               [NSApp stopCheatServer];
+       }
+       else {
+               [[NSUserDefaults standardUserDefaults] setBool:YES forKey:TCRunServerPref];
+               if ( ![NSApp startCheatServer] ) {
+                       // cheat server failed to start
+                       NSBeginAlertSheet( @"The Cheat could not start the server.", @"OK", nil, nil, [sender window], nil, NULL, NULL, NULL,
+                                                        @"The cheat server failed to start.  Make sure the port is not in use by another program and try again." );
+               }
+       }
+}
+
+
+- (int)numberOfRowsInTableView:(NSTableView *)table
+{
+       CheatServer *server = [NSApp cheatServer];
+       if ( [server isListening] ) {
+               return [server childCount];
+       }
+       return 0;
+}
+
+- (id)tableView:(NSTableView *)table objectValueForTableColumn:(NSTableColumn *)column row:(int)row
+{
+       NSString *identifier = [column identifier];
+       ServerChild *child;
+       
+       child = [[[NSApp cheatServer] children] objectAtIndex:row];
+       
+       return [child valueForKey:identifier];
+}
+
+- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)column row:(int)row
+{
+       
+}
+
+- (BOOL)tableView:(NSTableView *)aTableView shouldSelectTableColumn:(NSTableColumn *)aTableColumn
+{
+       return NO;
+}
+
+- (void)tableView:(NSTableView *)aTableView deleteRows:(NSArray *)rows
+{
+       int i, len;
+       
+       len = [rows count];
+       for ( i = len-1; i >= 0; i-- ) {
+               [[NSApp cheatServer] removeChildAtIndex:[[rows objectAtIndex:i] unsignedIntValue]];
+       }
+       // reselect the last item if the selection is now invalid
+       len = [[NSApp cheatServer] childCount] - 1;
+       if ( [aTableView selectedRow] > len ) {
+               [aTableView selectRow:len byExtendingSelection:NO];
+       }
+       [aTableView reloadData];
+}
+
+
+- (void)_serverStarted:(NSNotification *)note
+{
+       CheatServer *server = [NSApp cheatServer];
+       int port;
+       // server is running
+       port = [server port];
+       if ( port != TCDefaultListenPort ) {
+               [ibStatusField setDefaultStatus:[NSString stringWithFormat:@"cheat://%@:%i", [server host], port]];
+       }
+       else {
+               [ibStatusField setDefaultStatus:[NSString stringWithFormat:@"cheat://%@", [server host]]];
+       }
+       [ibNameField setEnabled:NO];
+       [ibPortField setEnabled:NO];
+       [ibStartButton setTitle:@"Stop Server"];
+       [ibSessionTable reloadData];
+       
+       _tableTimer = [[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(_childrenChanged:)
+                                                                                                 userInfo:nil repeats:YES] retain];
+}
+
+- (void)_serverStopped:(NSNotification *)note
+{
+       // server is not running
+       [ibStatusField setDefaultStatus:@"Not Running"];
+       [ibNameField setEnabled:YES];
+       [ibPortField setEnabled:YES];
+       [ibStartButton setTitle:@"Start Server"];
+       [ibSessionTable reloadData];
+       
+       [_tableTimer invalidate];
+       [_tableTimer release];
+       _tableTimer = nil;
+}
+
+- (void)_childrenChanged:(NSNotification *)note
+{
+       [ibSessionTable reloadData];
+}
+
+
+@end
diff --git a/SessionController.h b/SessionController.h
deleted file mode 100644 (file)
index 178ecfe..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      SessionController.h
-// Created:   Sun Sep 07 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#import <Cocoa/Cocoa.h>
-#import <Chaz/Chaz.h>
-
-#include <float.h>
-
-#import "ClientDelegate.h"
-
-#import "MenuExtras.h"
-
-#include "cheat_types.h"
-#include "cheat_globals.h"
-#include "cheat_net.h"
-
-
-@interface SessionController : NSWindowController < ClientDelegate >
-{
-       // allows for easy interface updating
-       TCstatus                        status, lastStatus;
-       
-       // dealing with connecting
-       BOOL                            waitingToConnect;
-       NSConnection            *connection;
-       NSData                          *connectionAddress;
-       NSString                        *connectionName;
-       int                                     sockfd;
-       
-       // for updating the interface
-       NSString                        *targetName;
-       int                                     targetPID;
-       BOOL                            targetPaused;
-
-       NSArray                         *serverList;
-       NSMutableArray          *addressList;
-
-       TCaddress                       *searchResults;
-       int                                     searchResultsAmount;
-       int                                     searchResultsAmountDisplayed;
-
-       // to allow for connecting on new document
-       BOOL                            everConnected;
-       
-       // for the status field
-       NSString                        *savedStatusText;
-       NSColor                         *savedStatusColor;
-       NSTimer                         *statusTextTimer;
-       
-       // for updating the interface
-       int                                     undoCount, redoCount;
-       BOOL                            addressSelected;
-       
-       // for changing variables every x seconds
-       NSTimer                         *changeTimer;
-       NSArray                         *changeSelectedItems;
-
-       // INTERFACE OUTLETS
-       IBOutlet NSWindow                               *cheatWindow;
-       IBOutlet NSPopUpButton                  *serverPopup;
-       IBOutlet NSButton                               *pauseButton;
-       IBOutlet NSPopUpButton                  *processPopup;
-       IBOutlet NSPopUpButton                  *typePopup;
-       IBOutlet NSPopUpButton                  *sizePopup;
-       IBOutlet NSTextField                    *searchTextField;
-       IBOutlet NSMatrix                               *searchRadioMatrix;
-       IBOutlet NSButton                               *searchButton;
-       IBOutlet NSButton                               *clearSearchButton;
-       IBOutlet NSButton                               *changeButton;
-       IBOutlet NSTableView                    *addressTable;
-       IBOutlet CMStatusView                   *statusText;
-       IBOutlet NSProgressIndicator    *statusBar;
-       IBOutlet NSTextField                    *descriptionText;
-
-       IBOutlet NSMenu                                 *serverMenu;
-       IBOutlet NSMenu                                 *processMenu;
-       IBOutlet NSMenu                                 *typeMenu;
-       IBOutlet NSMenu                                 *stringSizeMenu;
-       IBOutlet NSMenu                                 *integerSizeMenu;
-       IBOutlet NSMenu                                 *decimalSizeMenu;
-       
-       // FOR THE CHANGE SHEET
-       IBOutlet NSWindow                               *changeSheet;
-       IBOutlet NSTextField                    *changeTextField;
-       IBOutlet NSButton                               *recurringChangeButton;
-       IBOutlet NSComboBox                             *changeSecondsCombo;
-       IBOutlet NSButton                               *cancelButton;
-       IBOutlet NSButton                               *okButton;
-}
-
-// UPDATE INTERFACE
-- (void)initialInterfaceSetup;
-
-- (void)updateSearchButton;
-- (void)updatePauseButton;
-- (void)updateSearchBoxes;
-- (void)updateChangeButton;
-- (void)updateDescriptionText;
-
-- (void)setStatusDisconnected;
-- (void)setStatusConnected;
-- (void)setStatusCheating;
-- (void)setStatusSearching;
-- (void)setStatusChanging;
-- (void)setStatusChangingLater;
-- (void)setStatusChangingContinuously;
-- (void)setStatusUndoing;
-- (void)setStatusRedoing;
-//- (void)setStatusToLast;
-
-//- (void)setStatusText:(NSString *)msg duration:(NSTimeInterval)seconds;
-//- (void)setStatusText:(NSString *)msg duration:(NSTimeInterval)seconds color:(NSColor *)color;
-//- (void)statusTextTimer:(NSTimer *)timer;
-
-// UPDATE CHANGE SHEET
-
-
-
-// CONNECT/DISCONNECT TO SERVER
-- (void)connectToLocal;
-- (void)connectToServer:(NSData *)addr name:(NSString *)name;
-- (void)disconnect;
-
-// SEND NETWORK MESSAGE
-- (void)sendProcessListRequest;
-- (void)sendClearSearch;
-- (void)sendSearch:(char const *)data size:(int)size;
-- (void)sendChange:(char const *)data size:(int)size;
-- (void)sendPauseTarget;
-- (void)sendVariableValueRequest;
-- (void)sendUndoRequest;
-- (void)sendRedoRequest;
-- (void)sendSetTargetPID:(int)pid;
-
-// RECEIVED NETWORK MESSAGE
-- (void)receivedProcessList:(NSData *)data;
-- (void)receivedSearchFinished;
-- (void)receivedVariableList:(NSData *)data;
-- (void)receivedChangeFinished;
-- (void)receivedError:(NSData *)data;
-- (void)receivedUndoFinished;
-- (void)receivedRedoFinished;
-- (void)receivedUndoRedoStatus:(NSData *)data;
-- (void)receivedAppLaunched:(NSData *)data;
-- (void)receivedAppQuit:(NSData *)data;
-- (void)receivedTargetQuit;
-- (void)receivedPauseFinished:(NSData *)data;
-
-// SEARCHING/CHANGING COMMANDS
-- (void)search;
-- (void)change;
-
-- (void)changeSheet:(NSWindow *)sheet returned:(int)returned context:(void *)context;
-
-- (void)changeTimer:(NSTimer *)timer;
-
-// CHEAT WINDOW INTERFACE
-- (IBAction)typePopup:(id)sender;
-- (IBAction)sizePopup:(id)sender;
-
-- (IBAction)searchButton:(id)sender;
-- (IBAction)clearSearchButton:(id)sender;
-
-- (IBAction)changeButton:(id)sender;
-
-- (IBAction)serverMenuItem:(id)sender;
-- (IBAction)serverMenuDisconnect:(id)sender;
-- (IBAction)serverMenuLocal:(id)sender;
-- (IBAction)processMenuItem:(id)sender;
-
-- (IBAction)pauseButton:(id)sender;
-
-- (IBAction)undoMenu:(id)sender;
-- (IBAction)redoMenu:(id)sender;
-
-// CHANGE SHEET INTERFACE
-- (IBAction)cancelButton:(id)sender;
-- (IBAction)okButton:(id)sender;
-
-- (IBAction)recurringChangeButton:(id)sender;
-
-// CLEAN UP
-- (void)clearSearch;
-- (void)destroyResults;
-
-// NOTIFICATION SELECTORS
-- (void)listenerStarted:(NSNotification *)note;
-- (void)listenerStopped:(NSNotification *)note;
-
-- (void)windowsOnTopChanged:(NSNotification *)note;
-
-// ERROR HANDLING
-- (void)handleErrorMessage:(NSString *)msg fatal:(BOOL)fatal;
-
-@end
\ No newline at end of file
diff --git a/SessionController.m b/SessionController.m
deleted file mode 100644 (file)
index 35763fe..0000000
+++ /dev/null
@@ -1,1869 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      SessionController.m
-// Created:   Sun Sep 07 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#import "SessionController.h"
-
-#import "AppController.h"
-
-#import "CheatClient.h"
-
-
-// Internal Functions
-void TCPlaySound( NSString *name );
-
-
-@implementation SessionController
-
-- (id)init
-{
-    if ( self = [super initWithWindowNibName:@"Session"] )
-       {
-               NSNotificationCenter            *nc = [NSNotificationCenter defaultCenter];
-               
-               // initialize stuff
-               sockfd = -1;
-               addressList = [[NSMutableArray alloc] init];
-
-               // notifications to receive
-               [nc addObserver:self selector:@selector(listenerStarted:) name:@"TCListenerStarted" object:nil];
-               [nc addObserver:self selector:@selector(listenerStopped:) name:@"TCListenerStopped" object:nil];
-               [nc addObserver:self selector:@selector(windowsOnTopChanged:) name:@"TCWindowsOnTopChanged" object:nil];
-               
-               serverList = [(NSArray *)[NSApp serverList] retain];
-               
-               // register to recieve notes from the global browser
-               [nc addObserver:self selector:@selector(browserServerFound:) name:@"TCServerFound" object:nil];
-               [nc addObserver:self selector:@selector(browserServerLost:) name:@"TCServerLost" object:nil];
-
-               [self connectToLocal];
-       }
-       
-    return self;
-}
-
-/*- (NSString *)windowNibName
-{
-    return @"MyDocument";
-}
-
-- (NSString *)displayName
-{
-       return [NSString stringWithFormat:@"The Cheat %i", TCGlobalDocumentCount++];
-}
-
-- (void)windowControllerDidLoadNib:(NSWindowController *)controller
-{
-    [super windowControllerDidLoadNib:controller];
-
-       [self initialInterfaceSetup];
-}*/
-
-- (void)windowDidLoad
-{
-       [cheatWindow setTitle:[NSString stringWithFormat:@"The Cheat %i", ++TCGlobalSessionCount]];
-       
-       [self initialInterfaceSetup];
-}
-
-- (void)windowWillClose:(NSNotification *)aNotification
-{
-       // closing the window will automatically disconnect the client from the server,
-       // but if the application is quitting, the client may not get a chance to exit.
-       // this _should_ be OK.
-       [self disconnect];
-       
-       // clean up status timer stuff.
-       // we do this here because we don't want the timer to fire after the window is gone
-       // since we need to use the window in that method.
-       [savedStatusColor release], savedStatusColor = nil;
-       [savedStatusText release], savedStatusText = nil;
-       [statusTextTimer invalidate];
-       [statusTextTimer release], statusTextTimer = nil;
-       
-       // we keep track of ourselves so we have to release ourself.
-       [self release];
-}
-
-
-- (void)initialInterfaceSetup
-{
-       NSString                        *localName = @"Local"; //[NSString stringWithFormat:@"%@ (local)", TCGlobalBroadcastName];
-       
-       NSMenuItem                      *menuItem;
-       int                                     i, top = [serverList count];
-       
-       // misc window settings
-       [cheatWindow useOptimizedDrawing:YES];
-       [cheatWindow setFrameAutosaveName:@"TCCheatWindow"];
-
-       // set options
-       if ( TCGlobalWindowsOnTop )
-       {
-               [cheatWindow setLevel:NSPopUpMenuWindowLevel];
-       }
-
-       // set up the server menu default items
-       [serverMenu removeAllItems];
-       [serverMenu addItemWithTitle:@"Not Connected" action:@selector(serverMenuDisconnect:) keyEquivalent:@""];
-       [serverMenu addItemWithTitle:localName action:@selector(serverMenuLocal:) keyEquivalent:@""];
-       [processMenu removeAllItems];
-       
-       // update server menu
-       for ( i = 0; i < top; i++ )
-       {
-               menuItem = [[NSMenuItem alloc] initWithTitle:[(NSNetService *)[serverList objectAtIndex:i] name] action:@selector(serverMenuItem:) keyEquivalent:@""];
-               
-               [menuItem setTag:i];
-               
-               // if this is the first server, add a divider.
-               if ( [serverMenu numberOfItems] <= 2 )
-               {
-                       [serverMenu addItem:[NSMenuItem separatorItem]];
-               }
-               
-               [serverMenu addItem:[menuItem autorelease]];
-       }
-       
-       // give tags to the menu items.
-       [[typeMenu itemWithTitle:@"Integer"] setTag:TYPE_INTEGER];
-       [[typeMenu itemWithTitle:@"String"] setTag:TYPE_STRING];
-       [[typeMenu itemWithTitle:@"Decimal"] setTag:TYPE_DECIMAL];
-       [[typeMenu itemWithTitle:@"Unknown Value"] setTag:TYPE_UNKNOWN];
-       [[stringSizeMenu itemWithTitle:@"8-bit"] setTag:SIZE_8_BIT];
-       [[integerSizeMenu itemWithTitle:@"char"] setTag:SIZE_8_BIT];
-       [[integerSizeMenu itemWithTitle:@"short"] setTag:SIZE_16_BIT];
-       [[integerSizeMenu itemWithTitle:@"long"] setTag:SIZE_32_BIT];
-       [[decimalSizeMenu itemWithTitle:@"float"] setTag:SIZE_32_BIT];
-       [[decimalSizeMenu itemWithTitle:@"double"] setTag:SIZE_64_BIT];
-       
-       // set default state
-       [statusText setStringValue:@""];
-       [self setStatusDisconnected];
-       
-       // display the initial description text
-       [self updateDescriptionText];
-       
-       // change sheet initial interface.
-       [changeSecondsCombo setEnabled:NO];
-}
-
-- (void)updateSearchButton
-{
-       TCtype                  type = [typePopup indexOfSelectedItem];
-       
-       if ( type != TYPE_UNKNOWN )
-       {
-               if ( [[searchTextField stringValue] isEqualToString:@""] )
-               {
-                       [searchButton setEnabled:NO];
-               }
-               else
-               {
-                       [searchButton setEnabled:YES];
-               }
-       }
-       else
-       {
-               [searchButton setEnabled:YES];
-       }
-}
-
-- (void)updatePauseButton
-{
-       if ( !targetPaused )
-       {
-               [pauseButton setTitle:@"Pause Target"];
-       }
-       else
-       {
-               [pauseButton setTitle:@"Resume Target"];
-       }
-}
-
-- (void)updateSearchBoxes
-{
-       TCtype                  type = [typePopup indexOfSelectedItem];
-       
-       if ( type != TYPE_UNKNOWN )
-       {
-               [searchTextField setEnabled:YES];
-               [searchRadioMatrix setEnabled:NO];
-       }
-       else
-       {
-               [searchTextField setEnabled:NO];
-               [searchRadioMatrix setEnabled:YES];
-       }
-}
-
-- (void)updateChangeButton
-{
-       if ( addressSelected )
-       {
-               [changeButton setEnabled:YES];
-       }
-       else
-       {
-               [changeButton setEnabled:NO];
-       }
-}
-
-- (void)updateDescriptionText
-{
-       TCtype                  type = [[typePopup selectedItem] tag];
-       TCsize                  size = [[sizePopup selectedItem] tag];
-       
-       switch ( type )
-       {
-               case TYPE_STRING:
-                       [descriptionText setStringValue:@"A string is a series of characters.\n\nThis search allows you to find and change words and phrases.  Numbers can also be stored as strings, but they aren't recognized as numbers by the computer.  Changing strings probably won't change the game in a big way."];
-                       break;
-                       
-               case TYPE_INTEGER:
-                       switch ( size )
-                       {
-                               case SIZE_8_BIT:
-                                       [descriptionText setStringValue:@"An integer is a non-fraction number.\n\nExamples:   0, 1, 2, 3, 4\nRange: 0 - 255\n\nIntegers usually store variables like score, lives, and remaining ammo."];
-                                       break;
-                                       
-                               case SIZE_16_BIT:
-                                       [descriptionText setStringValue:@"An integer is a non-fraction number.\n\nExamples: -1, 0, 1, 2, 3\nRange: -32,768 - 32,767\n\nIntegers usually store variables like score, lives, and remaining ammo."];
-                                       break;
-                                       
-                               case SIZE_32_BIT:
-                                       [descriptionText setStringValue:@"An integer is a non-fraction number.\n\nExamples: -1, 0, 1, 2, 3\nRange: about -2 billion - 2 billion\n\nIntegers usually store variables like score, lives, and remaining ammo.  This is the most common size for integer variables."];
-                                       break;
-                       }
-                       break;
-                       
-               case TYPE_DECIMAL:
-                       [descriptionText setStringValue:@"A decimal is a fraction number.\n\nFloats and doubles are not often used as variables in games, but there may be other uses for cheating them.  Type in as many digits after the decimal place as possible to ensure that your input is matched with the variable you are looking for."];
-                       break;
-       }
-}
-
-
-- (void)setStatusDisconnected
-{
-       if ( status == STATUS_DISCONNECTED ) return;
-       lastStatus = status;
-       status = STATUS_DISCONNECTED;
-       
-       [serverPopup setEnabled:YES];
-       [pauseButton setTitle:@"Pause Target"];
-       [pauseButton setEnabled:NO];
-       [processPopup setEnabled:NO];
-       [typePopup setEnabled:NO];
-       [sizePopup setEnabled:NO];
-       [searchTextField setEnabled:NO];
-       [searchRadioMatrix setEnabled:NO];
-       [searchButton setEnabled:NO];
-       [clearSearchButton setEnabled:NO];
-       [statusText addStatus:@"Not Connected" duration:CM_STATUS_FOREVER];
-       [statusText setToolTip:@""];
-       [statusBar stopAnimation:self];
-       [addressTable setEnabled:NO];
-       [changeButton setTitle:@"Change..."];
-       [changeButton setEnabled:NO];
-       
-       [[serverMenu itemAtIndex:0] setTitle:@"Not Connected"];
-}
-
-- (void)setStatusConnected
-{
-       if ( status == STATUS_CONNECTED ) return;
-       lastStatus = status;
-       status = STATUS_CONNECTED;
-       
-       [serverPopup setEnabled:YES];
-       [self updatePauseButton];
-       [pauseButton setEnabled:YES];
-       [processPopup setEnabled:YES];
-       [typePopup setEnabled:YES];
-       [sizePopup setEnabled:YES];
-       [self updateSearchBoxes];
-       [self updateSearchButton];
-       [clearSearchButton setEnabled:NO];
-       [statusText addStatus:@"Connected" duration:CM_STATUS_FOREVER];
-       [statusText setToolTip:@""];
-       [statusBar stopAnimation:self];
-       [addressTable setEnabled:NO];
-       [changeButton setTitle:@"Change..."];
-       [changeButton setEnabled:NO];
-       
-       [[serverMenu itemAtIndex:0] setTitle:@"Disconnect"];
-}
-
-- (void)setStatusCheating
-{
-       if ( status == STATUS_CHEATING ) return;
-       lastStatus = status;
-       status = STATUS_CHEATING;
-       
-       [serverPopup setEnabled:YES];
-       [self updatePauseButton];
-       [pauseButton setEnabled:YES];
-       [processPopup setEnabled:NO];
-       [typePopup setEnabled:NO];
-       [sizePopup setEnabled:NO];
-       [self updateSearchBoxes];
-       [self updateSearchButton];
-       [clearSearchButton setEnabled:YES];
-       if ( searchResultsAmount <= searchResultsAmountDisplayed )
-       {
-               if ( searchResultsAmount == 1 )
-               {
-                       [statusText addStatus:@"One Result" color:[NSColor colorWithCalibratedRed:0.0f green:0.5f blue:0.0f alpha:1.0f] duration:CM_STATUS_FOREVER];
-               }
-               else if ( searchResultsAmount == 0 )
-               {
-                       [statusText addStatus:@"No Results" color:[NSColor colorWithCalibratedRed:0.5f green:0.0f blue:0.0f alpha:1.0f] duration:CM_STATUS_FOREVER];
-               }
-               else
-               {
-                       [statusText addStatus:[NSString stringWithFormat:@"Results: %i", searchResultsAmount] duration:CM_STATUS_FOREVER];
-               }
-               [statusText setToolTip:@""];
-       }
-       else
-       {
-               [statusText addStatus:[NSString stringWithFormat:@"Results: >%i", searchResultsAmountDisplayed] duration:CM_STATUS_FOREVER];
-               [statusText setToolTip:[NSString stringWithFormat:@"Results: %i", searchResultsAmount]];
-       }
-       [statusBar stopAnimation:self];
-       [addressTable setEnabled:YES];
-       [changeButton setTitle:@"Change..."];
-       [self updateChangeButton];
-       
-       [[serverMenu itemAtIndex:0] setTitle:@"Disconnect"];
-}
-
-- (void)setStatusSearching
-{
-       if ( status == STATUS_SEARCHING ) return;
-       lastStatus = status;
-       status = STATUS_SEARCHING;
-       
-       [serverPopup setEnabled:NO];
-       [self updatePauseButton];
-       [pauseButton setEnabled:NO];
-       [processPopup setEnabled:NO];
-       [typePopup setEnabled:NO];
-       [sizePopup setEnabled:NO];
-       [searchTextField setEnabled:NO];
-       [searchRadioMatrix setEnabled:NO];
-       [searchButton setEnabled:NO];
-       [clearSearchButton setEnabled:NO];
-       [statusText addStatus:@"Searching..." duration:CM_STATUS_FOREVER];
-       [statusText setToolTip:@""];
-       [statusBar startAnimation:self];
-       [addressTable setEnabled:NO];
-       [changeButton setTitle:@"Change..."];
-       [changeButton setEnabled:NO];
-       
-       [[serverMenu itemAtIndex:0] setTitle:@"Disconnect"];
-}
-
-- (void)setStatusChanging
-{
-       if ( status == STATUS_CHANGING ) return;
-       lastStatus = status;
-       status = STATUS_CHANGING;
-       
-       if ( lastStatus != STATUS_CHANGING_CONTINUOUSLY )
-       {
-               [serverPopup setEnabled:NO];
-               [self updatePauseButton];
-               [pauseButton setEnabled:NO];
-               [processPopup setEnabled:NO];
-               [typePopup setEnabled:NO];
-               [sizePopup setEnabled:NO];
-               [searchTextField setEnabled:NO];
-               [searchRadioMatrix setEnabled:NO];
-               [searchButton setEnabled:NO];
-               [clearSearchButton setEnabled:NO];
-               [statusBar startAnimation:self];
-               [addressTable setEnabled:NO];
-               [changeButton setEnabled:NO];
-               
-               [[serverMenu itemAtIndex:0] setTitle:@"Disconnect"];
-       }
-}
-
-- (void)setStatusChangingLater
-{
-       if ( status == STATUS_CHANGING_LATER ) return;
-       lastStatus = status;
-       status = STATUS_CHANGING_LATER;
-       
-       [serverPopup setEnabled:NO];
-       [self updatePauseButton];
-       [pauseButton setEnabled:NO];
-       [processPopup setEnabled:NO];
-       [typePopup setEnabled:NO];
-       [sizePopup setEnabled:NO];
-       [searchTextField setEnabled:NO];
-       [searchRadioMatrix setEnabled:NO];
-       [searchButton setEnabled:NO];
-       [clearSearchButton setEnabled:NO];
-       [statusText addStatus:@"Changing Later..." duration:CM_STATUS_FOREVER];
-       [statusText setToolTip:@""];
-       [statusBar startAnimation:self];
-       [addressTable setEnabled:NO];
-       [changeButton setTitle:@"Cancel Change"];
-       [changeButton setEnabled:YES];
-       
-       [[serverMenu itemAtIndex:0] setTitle:@"Disconnect"];
-}
-
-- (void)setStatusChangingContinuously
-{
-       if ( status == STATUS_CHANGING_CONTINUOUSLY ) return;
-       lastStatus = status;
-       status = STATUS_CHANGING_CONTINUOUSLY;
-       
-       [serverPopup setEnabled:NO];
-       [self updatePauseButton];
-       [pauseButton setEnabled:YES];
-       [processPopup setEnabled:NO];
-       [typePopup setEnabled:NO];
-       [sizePopup setEnabled:NO];
-       [searchTextField setEnabled:NO];
-       [searchRadioMatrix setEnabled:NO];
-       [searchButton setEnabled:NO];
-       [clearSearchButton setEnabled:NO];
-       [statusText addStatus:@"Repeating Change..." duration:CM_STATUS_FOREVER];
-       [statusText setToolTip:@""];
-       [statusBar startAnimation:self];
-       [addressTable setEnabled:NO];
-       [changeButton setTitle:@"Stop Change"];
-       [changeButton setEnabled:YES];
-       
-       [[serverMenu itemAtIndex:0] setTitle:@"Disconnect"];
-}
-
-- (void)setStatusUndoing
-{
-       if ( status == STATUS_UNDOING ) return;
-       lastStatus = status;
-       status = STATUS_UNDOING;
-       
-       [serverPopup setEnabled:NO];
-       [self updatePauseButton];
-       [pauseButton setEnabled:NO];
-       [processPopup setEnabled:NO];
-       [typePopup setEnabled:NO];
-       [sizePopup setEnabled:NO];
-       [searchTextField setEnabled:NO];
-       [searchRadioMatrix setEnabled:NO];
-       [searchButton setEnabled:NO];
-       [clearSearchButton setEnabled:NO];
-       [statusText addStatus:@"Undoing..." duration:CM_STATUS_FOREVER];
-       [statusBar startAnimation:self];
-       [addressTable setEnabled:NO];
-       [changeButton setTitle:@"Change..."];
-       [changeButton setEnabled:NO];
-       
-       [[serverMenu itemAtIndex:0] setTitle:@"Disconnect"];
-}
-
-- (void)setStatusRedoing
-{
-       if ( status == STATUS_REDOING ) return;
-       lastStatus = status;
-       status = STATUS_REDOING;
-       
-       [serverPopup setEnabled:NO];
-       [self updatePauseButton];
-       [pauseButton setEnabled:NO];
-       [processPopup setEnabled:NO];
-       [typePopup setEnabled:NO];
-       [sizePopup setEnabled:NO];
-       [searchTextField setEnabled:NO];
-       [searchRadioMatrix setEnabled:NO];
-       [searchButton setEnabled:NO];
-       [clearSearchButton setEnabled:NO];
-       [statusText addStatus:@"Redoing..." duration:CM_STATUS_FOREVER];
-       [statusText setToolTip:@""];
-       [statusBar startAnimation:self];
-       [addressTable setEnabled:NO];
-       [changeButton setTitle:@"Change..."];
-       [changeButton setEnabled:NO];
-       
-       [[serverMenu itemAtIndex:0] setTitle:@"Disconnect"];
-}
-
-/*- (void)setStatusToLast
-{
-       switch ( lastStatus )
-       {
-               case STATUS_DISCONNECTED:
-                       [self setStatusDisconnected];
-                       break;
-                       
-               case STATUS_CONNECTED:
-                       [self setStatusConnected];
-                       break;
-                       
-               case STATUS_CHEATING:
-                       [self setStatusCheating];
-                       break;
-                       
-               case STATUS_SEARCHING:
-                       [self setStatusSearching];
-                       break;
-                       
-               case STATUS_CHANGING:
-                       [self setStatusChanging];
-                       break;
-                       
-               case STATUS_CHANGING_LATER:
-                       [self setStatusChangingLater];
-                       break;
-                       
-               case STATUS_CHANGING_CONTINUOUSLY:
-                       [self setStatusChangingContinuously];
-                       break;
-                       
-               case STATUS_UNDOING:
-                       [self setStatusUndoing];
-                       break;
-                       
-               case STATUS_REDOING:
-                       [self setStatusRedoing];
-                       break;
-       }
-}*/
-
-/*
-- (void)setStatusText:(NSString *)msg duration:(NSTimeInterval)seconds
-{
-       [self setStatusText:msg duration:seconds color:[NSColor blackColor]];
-}
-
-- (void)setStatusText:(NSString *)msg duration:(NSTimeInterval)seconds color:(NSColor *)color
-{
-       if ( statusTextTimer )
-       {
-               [statusTextTimer invalidate];
-               [statusTextTimer release], statusTextTimer = nil;
-       }
-       else
-       {
-               [savedStatusText release];
-               [savedStatusColor release];
-               savedStatusText = [[statusText stringValue] retain];
-               savedStatusColor = [[statusText textColor] retain];
-       }
-       
-       [statusText setTextColor:color];
-       [statusText setStringValue:msg];
-       
-       if ( seconds != 0.0 )
-       {
-               statusTextTimer = [[NSTimer scheduledTimerWithTimeInterval:seconds target:self selector:@selector(statusTextTimer:) userInfo:nil repeats:NO] retain];
-       }
-}
-
-- (void)statusTextTimer:(NSTimer *)timer
-{
-       [statusText setTextColor:savedStatusColor];
-       [statusText setStringValue:savedStatusText];
-       
-       [savedStatusColor release], savedStatusColor = nil;
-       [savedStatusText release], savedStatusText = nil;
-       [statusTextTimer invalidate];
-       [statusTextTimer release], statusTextTimer = nil;
-}*/
-
-
-- (void)connectToLocal
-{
-       NSString                        *localName = @"Local"; //[NSString stringWithFormat:@"%@ (local)", TCGlobalBroadcastName];
-       
-       // depending on how the listener is listening, we need to use different means to connect to local
-       if ( TCGlobalListening )
-       {
-               if ( TCGlobalAllowRemote )
-               {
-                       struct sockaddr_in      addr;
-
-                       addr.sin_family = AF_INET;
-                       addr.sin_port = htonl( TCGlobalListenPort );
-                       addr.sin_addr.s_addr = INADDR_ANY;
-
-                       [self connectToServer:[NSData dataWithBytes:&addr length:sizeof(addr)] name:localName];
-               }
-               else
-               {
-                       struct sockaddr_un      addr;
-
-                       addr.sun_family = AF_UNIX;
-                       strncpy( addr.sun_path, TCDefaultListenPath, 103 );
-
-                       [self connectToServer:[NSData dataWithBytes:&addr length:sizeof(addr)] name:localName];
-               }
-       }
-}
-
-- (void)connectToServer:(NSData *)addr name:(NSString *)name
-{
-       everConnected = YES;
-       
-       if ( connection )
-       {
-               [self disconnect];
-               
-               waitingToConnect = YES;
-               connectionAddress = [addr retain];
-               connectionName = [name retain];
-       }
-       else
-       {
-               connection = [[CheatClient clientWithDelegate:self server:addr name:name] retain];
-               connectionAddress = [addr retain];
-               connectionName = [name retain];
-       }
-
-       [self setStatusConnected];
-}
-
-- (void)disconnect
-{
-       if ( connection )
-       {
-               [connection release], connection = nil;
-               close( sockfd );
-
-               [self clearSearch];
-
-               [connectionAddress release], connectionAddress = nil;
-               [connectionName release], connectionName = nil;
-
-               [processMenu removeAllItems];
-
-               [serverPopup selectItemAtIndex:0];
-               [self setStatusDisconnected];
-       }
-}
-
-
-- (void)sendProcessListRequest
-{
-       PacketHeader    header;
-       int                             length = sizeof(header);
-
-       header.checksum = RandomChecksum();
-       header.function = 1;
-       header.size = 0;
-
-       if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
-       {
-               CMLog( @"sendProcessListRequest failed on socket %i", sockfd );
-       }
-}
-
-- (void)sendClearSearch
-{
-       PacketHeader    header;
-       int                             length = sizeof(header);
-       
-       header.checksum = RandomChecksum();
-       header.function = 3;
-       header.size = 0;
-       
-       if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
-       {
-               CMLog( @"sendClearSearch failed on socket %i", sockfd );
-       }
-}
-
-- (void)sendSearch:(char const *)data size:(int)size
-{
-       PacketHeader    header;
-       int                             length = sizeof(header) + size;
-       int                             lengthAfter = length;
-
-       char                    *buffer, *ptr;
-
-       header.checksum = RandomChecksum();
-       header.function = 5;
-       header.size = size;
-
-       if ( (buffer = (char *)malloc( length )) == NULL )
-       {
-               CMLog( @"sendSearch:size: failed" );
-       }
-
-       ptr = buffer;
-
-       COPY_TO_BUFFER( ptr, &header, sizeof(header) );
-       COPY_TO_BUFFER( ptr, data, size );
-
-       if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
-       {
-               CMLog( @"sendSearch:size: failed" );
-       }
-
-       free( buffer );
-}
-
-- (void)sendChange:(char const *)data size:(int)size
-{
-       PacketHeader    header;
-       int                             length = sizeof(header) + size;
-       int                             lengthAfter = length;
-       
-       char                    *buffer, *ptr;
-       
-       header.checksum = RandomChecksum();
-       header.function = 8;
-       header.size = size;
-       
-       if ( (buffer = (char *)malloc( length )) == NULL )
-       {
-               CMLog( @"sendChange:size: failed" );
-       }
-       
-       ptr = buffer;
-       
-       COPY_TO_BUFFER( ptr, &header, sizeof(header) );
-       COPY_TO_BUFFER( ptr, data, size );
-       
-       if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
-       {
-               CMLog( @"sendChange:size: failed" );
-       }
-       
-       free( buffer );
-}
-
-- (void)sendPauseTarget;
-{
-       PacketHeader    header;
-       int                             length = sizeof(header);
-
-       header.checksum = RandomChecksum();
-       header.function = 10;
-       header.size = 0;
-
-       if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
-       {
-               CMLog( @"sendPauseTarget failed" );
-       }
-}
-
-- (void)sendVariableValueRequest
-{
-
-}
-
-- (void)sendUndoRequest
-{
-       PacketHeader    header;
-       int                             length = sizeof(header);
-
-       header.checksum = RandomChecksum();
-       header.function = 14;
-       header.size = 0;
-
-       if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
-       {
-               CMLog( @"sendUndoRequest failed" );
-       }
-}
-
-- (void)sendRedoRequest
-{
-       PacketHeader    header;
-       int                             length = sizeof(header);
-
-       header.checksum = RandomChecksum();
-       header.function = 16;
-       header.size = 0;
-
-       if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
-       {
-               CMLog( @"sendRedoRequest failed" );
-       }
-}
-
-- (void)sendSetTargetPID:(int)pid
-{
-       PacketHeader    header;
-       int                             length = sizeof(header) + sizeof(u_int32_t);
-       int                             lengthAfter = length;
-
-       u_int32_t               tarPID = (u_int32_t)pid;
-
-       char                    *buffer, *ptr;
-
-       header.checksum = RandomChecksum();
-       header.function = 18;
-       header.size = sizeof(u_int32_t);
-
-       if ( (buffer = (char *)malloc( length )) == NULL )
-       {
-               CMLog( @"sendSetTargetPID: failed" );
-       }
-
-       ptr = buffer;
-
-       COPY_TO_BUFFER( ptr, &header, sizeof(header) );
-       COPY_TO_BUFFER( ptr, &tarPID, sizeof(tarPID) );
-
-       if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
-       {
-               CMLog( @"sendSetTargetPID: failed" );
-       }
-
-       free( buffer );
-}
-
-
-- (void)receivedProcessList:(NSData *)data
-{
-       NSMenuItem              *item;
-       u_int32_t               processCount = 0;
-
-       char                    *ptr = (char *)[data bytes];
-       int                             i, max;
-
-       COPY_FROM_BUFFER( &processCount, ptr, sizeof(processCount) );
-
-       max = (int)processCount;
-
-       for ( i = 0; i < max; i++ )
-       {
-               u_int32_t       pid;
-               NSString        *name;
-
-               COPY_FROM_BUFFER( &pid, ptr, sizeof(pid) );
-               name = [NSString stringWithCString:ptr], ptr += [name length] + 1;
-
-               item = [[NSMenuItem alloc] initWithTitle:name action:@selector(processMenuItem:) keyEquivalent:@""];
-               [item setTag:(int)pid];
-
-               [processMenu addItem:[item autorelease]];
-       }
-}
-
-- (void)receivedSearchFinished
-{
-       if ( searchResultsAmount == 1 )
-       {
-               TCPlaySound( @"Submarine" );
-       }
-       else if ( searchResultsAmount == 0 )
-       {
-               TCPlaySound( @"Basso" );
-       }
-       
-       [self setStatusCheating];
-       //[self setStatusText:@"Search Finished" duration:1.5];
-       [cheatWindow makeFirstResponder:searchTextField];
-}
-
-- (void)receivedVariableList:(NSData *)data
-{
-       char                    *ptr = (char *)[data bytes];
-
-       [self destroyResults];
-
-       COPY_FROM_BUFFER( &searchResultsAmount, ptr, sizeof(searchResultsAmount) );
-       COPY_FROM_BUFFER( &searchResultsAmountDisplayed, ptr, sizeof(searchResultsAmountDisplayed) );
-
-       if ( searchResultsAmountDisplayed > 0 )
-       {
-               int                             memSize = TCAddressSize * searchResultsAmountDisplayed;
-               // TCAddressSize*maxSearchResultsAmount;
-               
-               if ( (searchResults = (TCaddress *)malloc( memSize )) == NULL )
-               {
-                       CMLog( @"receivedVariableList failed: malloc failed" );
-                       searchResultsAmount = 0;
-                       searchResultsAmountDisplayed = 0;
-                       return;
-               }
-               CMLog( @"CLIENT setting display amount to %i", searchResultsAmountDisplayed );
-
-               COPY_FROM_BUFFER( searchResults, ptr, memSize );
-       }
-
-       [addressTable reloadData];
-}
-
-- (void)receivedChangeFinished
-{
-       if ( status != STATUS_CHANGING_CONTINUOUSLY )
-       {
-               TCPlaySound( @"Tink" );
-               [self setStatusCheating];
-       }
-}
-
-- (void)receivedError:(NSData *)data
-{
-       u_int32_t               fatal;
-       NSString                *msg;
-
-       char                    *ptr = (char *)[data bytes];
-
-       COPY_FROM_BUFFER( &fatal, ptr, sizeof(fatal) );
-
-       msg = [NSString stringWithCString:ptr];
-       
-       // alert the user.
-       [self handleErrorMessage:msg fatal:fatal];
-}
-
-- (void)receivedUndoFinished
-{
-       [self setStatusCheating];
-}
-
-- (void)receivedRedoFinished
-{
-       [self setStatusCheating];
-}
-
-- (void)receivedUndoRedoStatus:(NSData *)data
-{
-       char                    *ptr = (char *)[data bytes];
-       
-       COPY_FROM_BUFFER( &undoCount, ptr, sizeof(undoCount) );
-       COPY_FROM_BUFFER( &redoCount, ptr, sizeof(redoCount) );
-       
-       CMLog( @"UNDO: %i, REDO: %i", undoCount, redoCount );
-}
-
-- (void)receivedAppLaunched:(NSData *)data
-{
-       NSMenuItem              *item;
-
-       char                    *ptr = (char *)[data bytes];
-
-       u_int32_t               pid;
-       NSString                *name;
-
-       COPY_FROM_BUFFER( &pid, ptr, sizeof(pid) );
-       name = [NSString stringWithCString:ptr], ptr += [name length] + 1;
-
-       item = [[NSMenuItem alloc] initWithTitle:name action:@selector(processMenuItem:) keyEquivalent:@""];
-       [item setTag:(int)pid];
-
-       [processMenu addItem:[item autorelease]];
-}
-
-- (void)receivedAppQuit:(NSData *)data
-{
-       u_int32_t               pid;
-       
-       char                    *ptr = (char *)[data bytes];
-
-       COPY_FROM_BUFFER( &pid, ptr, sizeof(pid) );
-
-       [processMenu removeItemWithTag:pid];
-}
-
-- (void)receivedTargetQuit
-{
-       [self clearSearch];
-       [self sendClearSearch];
-       
-       // tell the server that the first app is now the target.
-       targetPID = [[processMenu itemAtIndex:0] tag];
-       [self sendSetTargetPID:targetPID];
-       
-       // alert the user.
-       TCPlaySound( @"Frog" );
-       //[self handleErrorMessage:@"The application that was being cheated has quit." fatal:NO];
-       
-       [statusText addStatus:@"Target Quit"];
-       [self setStatusConnected];
-}
-
-- (void)receivedPauseFinished:(NSData *)data
-{
-       char                    *ptr = (char *)[data bytes];
-
-       COPY_FROM_BUFFER( &targetPaused, ptr, sizeof(targetPaused) );
-       
-       [self updatePauseButton];
-}
-
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%   Searching & Changing
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-- (void)search
-{
-       TCtype                  type = [[typePopup selectedItem] tag];
-       TCsize                  size = [[sizePopup selectedItem] tag];
-       
-       char                    *data, *ptr;
-       int                             dataSize = sizeof(type) + sizeof(size) + sizeof(TCGlobalHitsDisplayed);
-       
-       data = (char *)malloc( dataSize );
-       ptr = data;
-       
-       // copy the size and type of the variable.
-       COPY_TO_BUFFER( ptr, &type, sizeof(type) );
-       COPY_TO_BUFFER( ptr, &size, sizeof(size) );
-       
-       // copy the number of results to return.
-       COPY_TO_BUFFER( ptr, &TCGlobalHitsDisplayed, sizeof(TCGlobalHitsDisplayed) );
-       
-       CMLog( @"type: %i, size: %i", type, size );
-       
-       // switch to cheating mode if this is the first search.
-       if ( status == STATUS_CONNECTED )
-       {
-               [self setStatusCheating];
-       }
-       
-       // copy the value to search for.
-       switch ( type )
-       {
-               case TYPE_STRING:
-               {
-                       switch ( size )
-                       {
-                               case SIZE_8_BIT:
-                               {
-                                       NSString                        *string = [searchTextField stringValue];
-                                       int                                     stringLength = [string length] + 1;
-                                       
-                                       data = (char *)realloc( data, dataSize + stringLength );
-                                       ptr = data + dataSize;
-                                       dataSize += stringLength;
-                                       
-                                       COPY_TO_BUFFER( ptr, [string cString], stringLength );
-                               }
-                                       break;
-                       }
-               }
-                       break;
-                       
-               case TYPE_INTEGER:
-               {
-                       switch ( size )
-                       {
-                               case SIZE_8_BIT:
-                               {
-                                       int8_t                  value = [searchTextField intValue];
-                                       
-                                       data = (char *)realloc( data, dataSize + sizeof(value) );
-                                       ptr = data + dataSize;
-                                       dataSize += sizeof(value);
-                                       
-                                       COPY_TO_BUFFER( ptr, &value, sizeof(value) );
-                               }
-                                       break;
-                                       
-                               case SIZE_16_BIT:
-                               {
-                                       int16_t                 value = [searchTextField intValue];
-                                       
-                                       data = (char *)realloc( data, dataSize + sizeof(value) );
-                                       ptr = data + dataSize;
-                                       dataSize += sizeof(value);
-                                       
-                                       COPY_TO_BUFFER( ptr, &value, sizeof(value) );
-                               }
-                                       break;
-                                       
-                               case SIZE_32_BIT:
-                               {
-                                       int32_t                 value = [searchTextField intValue];
-                                       
-                                       data = (char *)realloc( data, dataSize + sizeof(value) );
-                                       ptr = data + dataSize;
-                                       dataSize += sizeof(value);
-                                       
-                                       COPY_TO_BUFFER( ptr, &value, sizeof(value) );
-                               }
-                                       break;
-                       }
-               }
-                       break;
-                       
-               case TYPE_DECIMAL:
-               {
-                       switch ( size )
-                       {
-                               case SIZE_32_BIT:
-                               {
-                                       float                   value = [searchTextField floatValue];
-                                       
-                                       data = (char *)realloc( data, dataSize + sizeof(value) );
-                                       ptr = data + dataSize;
-                                       dataSize += sizeof(value);
-                                       
-                                       COPY_TO_BUFFER( ptr, &value, sizeof(value) );
-                               }
-                                       break;
-                                       
-                               case SIZE_64_BIT:
-                               {
-                                       double                  value = [searchTextField doubleValue];
-                                       
-                                       data = (char *)realloc( data, dataSize + sizeof(value) );
-                                       ptr = data + dataSize;
-                                       dataSize += sizeof(value);
-                                       
-                                       COPY_TO_BUFFER( ptr, &value, sizeof(value) );
-                               }
-                                       break;
-                       }
-               }
-                       break;
-                       
-               case TYPE_UNKNOWN:
-               {
-                       u_int32_t               value = 0;//[searchTextField intValue];
-                       
-                       data = (char *)realloc( data, dataSize + sizeof(value) );
-                       ptr = data + dataSize;
-                       dataSize += sizeof(value);
-                       
-                       COPY_TO_BUFFER( ptr, &value, sizeof(value) );
-               }
-                       break;
-       }
-       
-       [self sendSearch:data size:dataSize];
-       free( data );
-       
-       [self setStatusSearching];
-}
-
-- (void)change
-{
-       TCtype                  type = [[typePopup selectedItem] tag];
-       TCsize                  size = [[sizePopup selectedItem] tag];
-       
-       int                             i, addressCount = [changeSelectedItems count];
-       
-       char                    *data, *ptr;
-       int                             dataSize = sizeof(type) + sizeof(size) + sizeof(addressCount) + TCAddressSize*addressCount;
-       
-       data = (char *)malloc( dataSize );
-       ptr = data;
-       
-       // copy the size and type of the variable.
-       COPY_TO_BUFFER( ptr, &type, sizeof(type) );
-       COPY_TO_BUFFER( ptr, &size, sizeof(size) );
-
-       // copy the amount and the list of addresses to change.
-       COPY_TO_BUFFER( ptr, &addressCount, sizeof(addressCount) );
-       for ( i = 0; i < addressCount; i++ )
-       {
-               COPY_TO_BUFFER( ptr, &((TCaddress *)searchResults)[ [[changeSelectedItems objectAtIndex:i] intValue] ], sizeof(TCaddress) );
-       }
-       
-       // copy the new value.
-       switch ( type )
-       {
-               case TYPE_STRING:
-               {
-                       switch ( size )
-                       {
-                               case SIZE_8_BIT:
-                               {
-                                       NSString                        *string = [changeTextField stringValue];
-                                       int                                     stringLength = [string length] + 1;
-                                       
-                                       data = (char *)realloc( data, dataSize + stringLength );
-                                       ptr = data + dataSize;
-                                       dataSize += stringLength;
-                                       
-                                       COPY_TO_BUFFER( ptr, [string cString], stringLength );
-                               }
-                                       break;
-                       }
-               }
-                       break;
-                       
-               case TYPE_INTEGER:
-               {
-                       switch ( size )
-                       {
-                               case SIZE_8_BIT:
-                               {
-                                       int8_t                  value = [changeTextField intValue];
-                                       
-                                       data = (char *)realloc( data, dataSize + sizeof(value) );
-                                       ptr = data + dataSize;
-                                       dataSize += sizeof(value);
-                                       
-                                       COPY_TO_BUFFER( ptr, &value, sizeof(value) );
-                               }
-                                       break;
-                                       
-                               case SIZE_16_BIT:
-                               {
-                                       int16_t                 value = [changeTextField intValue];
-                                       
-                                       data = (char *)realloc( data, dataSize + sizeof(value) );
-                                       ptr = data + dataSize;
-                                       dataSize += sizeof(value);
-                                       
-                                       COPY_TO_BUFFER( ptr, &value, sizeof(value) );
-                               }
-                                       break;
-                                       
-                               case SIZE_32_BIT:
-                               {
-                                       int32_t                 value = [changeTextField intValue];
-                                       
-                                       data = (char *)realloc( data, dataSize + sizeof(value) );
-                                       ptr = data + dataSize;
-                                       dataSize += sizeof(value);
-                                       
-                                       COPY_TO_BUFFER( ptr, &value, sizeof(value) );
-                               }
-                                       break;
-                       }
-               }
-                       break;
-                       
-               case TYPE_DECIMAL:
-               {
-                       switch ( size )
-                       {
-                               case SIZE_32_BIT:
-                               {
-                                       float                   value = [changeTextField floatValue];
-                                       
-                                       data = (char *)realloc( data, dataSize + sizeof(value) );
-                                       ptr = data + dataSize;
-                                       dataSize += sizeof(value);
-                                       
-                                       COPY_TO_BUFFER( ptr, &value, sizeof(value) );
-                               }
-                                       break;
-                                       
-                               case SIZE_64_BIT:
-                               {
-                                       double                  value = [changeTextField doubleValue];
-                                       
-                                       data = (char *)realloc( data, dataSize + sizeof(value) );
-                                       ptr = data + dataSize;
-                                       dataSize += sizeof(value);
-                                       
-                                       COPY_TO_BUFFER( ptr, &value, sizeof(value) );
-                               }
-                                       break;
-                       }
-               }
-                       break;
-                       
-               case TYPE_UNKNOWN:
-               {
-                       u_int32_t               value = 0;//[searchTextField intValue];
-                       
-                       data = (char *)realloc( data, dataSize + sizeof(value) );
-                       ptr = data + dataSize;
-                       dataSize += sizeof(value);
-                       
-                       COPY_TO_BUFFER( ptr, &value, sizeof(value) );
-               }
-                       break;
-       }
-       
-       [self sendChange:data size:dataSize];
-       free( data );
-}
-
-
-- (void)changeSheet:(NSWindow *)sheet returned:(int)returned context:(void *)context
-{
-       if ( returned == 1 )
-       {
-               [changeSelectedItems release], changeSelectedItems = [[[addressTable selectedRowEnumerator] allObjects] retain];
-               
-               if ( [recurringChangeButton state] == NSOnState )
-               {
-                       float                   seconds = [changeSecondsCombo floatValue];
-                       
-                       [self setStatusChangingContinuously];
-                       
-                       [self change];
-                       
-                       changeTimer = [[NSTimer scheduledTimerWithTimeInterval:seconds target:self selector:@selector(changeTimer:) userInfo:nil repeats:YES] retain];
-               }
-               else
-               {
-                       [self change];
-               }
-       }
-}
-
-
-- (void)changeTimer:(NSTimer *)timer
-{
-       [self change];
-}
-
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%   Cheat Window Interface
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-- (IBAction)typePopup:(id)sender
-{
-       switch ( [typePopup indexOfSelectedItem] )
-       {
-               case TYPE_STRING:
-                       [sizePopup setMenu:stringSizeMenu];
-                       break;
-
-               case TYPE_INTEGER:
-               case TYPE_UNKNOWN:
-                       [sizePopup setMenu:integerSizeMenu];
-                       break;
-
-               case TYPE_DECIMAL:
-                       [sizePopup setMenu:decimalSizeMenu];
-                       break;
-       }
-       
-       [self updateSearchBoxes];
-       [self updateSearchButton];
-       [self updateDescriptionText];
-}
-
-- (IBAction)sizePopup:(id)sender
-{
-       [self updateDescriptionText];
-}
-
-
-- (IBAction)searchButton:(id)sender
-{
-       /*if ( [searchTextField intValue] == 0 )
-       {
-               if ( NSRunAlertPanel( @"Warning", @"Performing a search with this value will probably take a long time.  You should try to search for the variable at a different value.", @"Search Anyway", @"Cancel", nil ) == NSAlertAlternateReturn )
-               {
-                       return;
-               }
-       }*/
-       
-       [self search];
-}
-
-- (IBAction)clearSearchButton:(id)sender
-{
-       [self clearSearch];
-       
-       [statusText addStatus:@"Search Cleared" duration:1.5];
-       [self setStatusConnected];
-
-       [self sendClearSearch];
-}
-
-
-- (IBAction)changeButton:(id)sender
-{
-       [changeTimer invalidate];
-       [changeTimer release], changeTimer = nil;
-       
-       if ( status == STATUS_CHANGING_CONTINUOUSLY )
-       {
-               [changeSelectedItems release], changeSelectedItems = nil;
-               
-               [self setStatusCheating];
-       }
-       else if ( status == STATUS_CHEATING )
-       {
-               [NSApp beginSheet:changeSheet modalForWindow:cheatWindow modalDelegate:self didEndSelector:@selector(changeSheet:returned:context:) contextInfo:NULL];
-               //[NSApp runModalForWindow:changeSheet];
-               //[NSApp endSheet:changeSheet];
-               //[changeSheet orderOut:self];
-       }
-}
-
-
-- (IBAction)serverMenuItem:(id)sender
-{
-       NSData                          *data = [[[serverList objectAtIndex:[sender tag]] addresses] objectAtIndex:0];
-/*     struct sockaddr_in      addr;
-
-       [data getBytes:&addr];*/
-
-       [self connectToServer:data name:[serverPopup titleOfSelectedItem]];
-}
-
-- (IBAction)serverMenuDisconnect:(id)sender
-{
-       [self disconnect];
-}
-
-- (IBAction)serverMenuLocal:(id)sender
-{
-       [self connectToLocal];
-}
-
-- (IBAction)processMenuItem:(id)sender
-{
-       targetPID = [sender tag];
-
-       [self sendSetTargetPID:targetPID];
-       
-       [statusText addStatus:[NSString stringWithFormat:@"PID: %i", targetPID] duration:CM_STATUS_FOREVER];
-}
-
-
-- (IBAction)pauseButton:(id)sender
-{
-       [self sendPauseTarget];
-}
-
-
-- (void)undoMenu:(id)sender
-{
-       if ( undoCount == 1 )
-       {
-               [self clearSearchButton:self];
-       }
-       else
-       {
-               [self sendUndoRequest];
-
-               [self setStatusUndoing];
-       }
-}
-
-- (void)redoMenu:(id)sender
-{
-       [self sendRedoRequest];
-
-       [self setStatusRedoing];
-}
-
-- (BOOL)respondsToSelector:(SEL)aSelector
-{
-       if ( aSelector == @selector(undoMenu:) )
-       {
-               if ( status == STATUS_CHEATING && undoCount > 0 )
-               {
-                       return YES;
-               }
-               else
-               {
-                       return NO;
-               }
-       }
-       
-       if ( aSelector == @selector(redoMenu:) )
-       {
-               if ( status == STATUS_CHEATING && redoCount > 0 )
-               {
-                       return YES;
-               }
-               else
-               {
-                       return NO;
-               }
-       }
-       
-       return [super respondsToSelector:aSelector];
-}
-
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%   Change Sheet Interface
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-- (IBAction)cancelButton:(id)sender
-{
-       [changeSheet orderOut:sender];
-       [NSApp endSheet:changeSheet returnCode:0];
-       //[NSApp stopModal];
-}
-
-- (IBAction)okButton:(id)sender
-{
-       [changeSheet orderOut:sender];
-       [NSApp endSheet:changeSheet returnCode:1];
-       if ( [recurringChangeButton state] == NSOnState )
-       {
-               [self setStatusChangingContinuously];
-       }
-       else
-       {
-               [self setStatusChanging];
-       }
-       //[NSApp stopModal];
-}
-
-
-- (IBAction)recurringChangeButton:(id)sender
-{
-       if ( [recurringChangeButton state] == NSOnState )
-       {
-               [changeSecondsCombo setEnabled:YES];
-       }
-       else
-       {
-               [changeSecondsCombo setEnabled:NO];
-       }
-}
-
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%   Cleaning Up
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-- (void)clearSearch
-{
-       undoCount = 0;
-       redoCount = 0;
-       
-       targetPaused = NO;
-       
-       [changeTimer invalidate];
-       [changeTimer release], changeTimer = nil;
-       
-       [self destroyResults];
-       [addressTable reloadData];
-}
-
-- (void)destroyResults
-{
-       if ( searchResultsAmountDisplayed > 0 )
-       {
-               free( searchResults );
-               
-               searchResultsAmount = 0;
-               searchResultsAmountDisplayed = 0;
-       }
-}
-
-
-- (void)dealloc
-{
-       [[NSNotificationCenter defaultCenter] removeObserver:self];
-       
-       [self disconnect];
-       
-       // clean up status timer stuff
-       [savedStatusColor release];
-       [savedStatusText release];
-       [statusTextTimer invalidate];
-       [statusTextTimer release];
-       
-       [changeTimer invalidate];
-       [changeTimer release];
-       
-       [self destroyResults];
-       
-       [changeSelectedItems release];
-       
-       [serverList release];
-       [addressList release];
-
-       [super dealloc];
-}
-
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%   TCListener Notifications
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-- (void)listenerStarted:(NSNotification *)note
-{
-       if ( !everConnected )
-       {
-               [self connectToLocal];
-       }
-}
-
-- (void)listenerStopped:(NSNotification *)note
-{
-       
-}
-
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%   TCWindowsOnTopChanged Notification
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-- (void)windowsOnTopChanged:(NSNotification *)note
-{
-       if ( [[note object] boolValue] )
-       {
-               [cheatWindow setLevel:NSPopUpMenuWindowLevel];
-       }
-       else
-       {
-               [cheatWindow setLevel:NSNormalWindowLevel];
-       }
-}
-
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%   TCWindowsOnTopChanged Notification
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-- (void)handleErrorMessage:(NSString *)msg fatal:(BOOL)fatal
-{
-       CMLog( @"error received" );
-       // close the change sheet if it's open.
-       if ( [cheatWindow attachedSheet] )
-       {
-               [changeSheet orderOut:self];
-               [NSApp endSheet:changeSheet returnCode:0];
-       }
-       
-       // show message.
-       NSBeginAlertSheet( fatal? @"Fatal Error":@"Error", @"OK", nil, nil, cheatWindow, nil, nil, nil, 0, msg );
-}
-
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%   Cheat Window Delegate
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-- (BOOL)windowShouldClose:(id)sender
-{
-       if ( sender == cheatWindow && ( status == STATUS_SEARCHING || status == STATUS_CHANGING ) )
-       {
-               NSBeep();
-               return NO;
-       }
-       
-       return YES;
-}
-
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%   ClientDelegate
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-- (void)clientConnectedWithSocket:(int)sock name:(NSString *)name
-{
-       // the client is reporting that a connection has been made.
-       sockfd = sock;
-
-       [self sendProcessListRequest];
-       
-       [serverPopup selectItemWithTitle:name];
-       
-       [self setStatusConnected];
-}
-
-- (void)clientDisconnected
-{
-       // if there is a pending connection, connect now.
-       if ( waitingToConnect )
-       {
-               waitingToConnect = NO;
-               connection = [[CheatClient clientWithDelegate:self server:connectionAddress name:connectionName] retain];
-       }
-       // if our connection variable is still valid, we were disconnected unexpectedly.
-       else if ( connection )
-       {
-               [self disconnect];
-               NSBeginAlertSheet( @"Network Failure", @"OK", nil, nil, cheatWindow, nil, nil, nil, 0, @"The server has disconnected you." );
-       }
-}
-
-- (void)clientError:(NSString *)error message:(NSString *)message
-{
-       NSBeginAlertSheet( error, @"OK", nil, nil, cheatWindow, nil, nil, nil, 0, message );
-}
-
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%   NSToolbar Delegate
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-/*
-*** A toolbar is no longer used, but the code still remains for possible future use. ***
-- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag
-{
-       NSToolbarItem           *item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
-
-       if ( [itemIdentifier isEqualToString:@"Disconnect"] )
-       {
-               disconnectButton = item;
-               
-        [item setLabel:@"Disconnect"];
-        [item setPaletteLabel:[item label]];
-        [item setImage:[NSImage imageNamed:@"disconnect"]];
-        [item setTarget:self];
-               [item setToolTip:@"Click here to pause or unpause the program being cheated."];
-    }
-       else if ( [itemIdentifier isEqualToString:@"ServerPopup"] )
-       {
-               NSRect          fRect = [typePopup frame];
-               NSSize          fSize = NSMakeSize( FLT_MAX, fRect.size.height );
-               NSMenuItem      *menu = [[NSMenuItem alloc] initWithTitle:@"Server" action:@selector(serverPopup:) keyEquivalent:@""];
-
-               [menu setSubmenu:[serverPopup menu]];
-               
-        [item setLabel:@"Server"];
-        [item setPaletteLabel:[item label]];
-        [item setView:serverPopup];
-               [item setMinSize:fRect.size];
-               [item setMaxSize:fSize];
-               [item setMenuFormRepresentation:[menu autorelease]];
-               [item autorelease];
-    }
-
-    return item;
-}
-
-- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar
-{
-       return [NSArray arrayWithObjects:NSToolbarSeparatorItemIdentifier,
-               NSToolbarSpaceItemIdentifier,
-               NSToolbarFlexibleSpaceItemIdentifier,
-               NSToolbarCustomizeToolbarItemIdentifier,
-               @"Disconnect", @"ServerPopup", nil];
-}
-
-- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar
-{
-       return [NSArray arrayWithObjects:@"Disconnect", @"ServerPopup", nil];
-}*/
-
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%   NSTableView Data Source/Delegate
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-- (void)controlTextDidChange:(NSNotification *)aNotification
-{
-       [self updateSearchButton];
-}
-
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%   NSTableView Data Source/Delegate
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-- (int)numberOfRowsInTableView:(NSTableView *)table
-{
-       return searchResultsAmountDisplayed;
-}
-
-- (id)tableView:(NSTableView *)table objectValueForTableColumn:(NSTableColumn *)column row:(int)row
-{
-       return [NSString stringWithFormat:@"%0.8X", ((TCaddress *)searchResults)[row]];
-}
-
-- (void)tableView:(NSTableView *) setObjectValue:(id)object forTableColumn:(NSTableColumn *)column row:(int)row
-{
-       return;
-}
-
-- (void)tableViewSelectionDidChange:(NSNotification *)note
-{
-       if ( [addressTable selectedRow] != -1 )
-       {
-               addressSelected = YES;
-       }
-       else
-       {
-               addressSelected = NO;
-       }
-       
-       [self updateChangeButton];
-}
-
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%   Global Browser Notifications
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-
-- (void)browserServerFound:(NSNotification *)note
-{
-       NSNetService                            *service = (NSNetService *)[note object];
-       
-       NSString                                        *name = [service name];
-       int                                                     tag = [serverList count] - 1;
-       NSMenuItem                                      *item;
-       
-       CMLog( @"server found" );
-       
-       if ( [serverMenu itemWithTitle:name] == nil )
-       {
-               item = [[NSMenuItem alloc] initWithTitle:[service name] action:@selector(serverMenuItem:) keyEquivalent:@""];
-               
-               [item setTag:tag];
-               
-               // if this is the first server, add a divider.
-               if ( [serverMenu numberOfItems] <= 2 )
-               {
-                       [serverMenu addItem:[NSMenuItem separatorItem]];
-               }
-               
-               //[serverList addObject:service];
-               [serverMenu addItem:[item autorelease]];
-               
-               // select the item if we are already connected to the server.
-               // this could happen if the server rebroadcast as a different name.
-               if ( connection && [[[service addresses] objectAtIndex:0] isEqualToData:connectionAddress] )
-               {
-                       [serverPopup selectItemWithTitle:[service name]];
-               }
-       }
-}
-
-- (void)browserServerLost:(NSNotification *)note
-{
-       NSNetService                            *service = (NSNetService *)[note object];
-       NSString                                        *name = [service name];
-       
-       int                                                     i, top = [serverMenu numberOfItems];
-       
-       for ( i = [serverMenu indexOfItemWithTitle:name] + 1; i < top; i++ )
-       {
-               [[serverMenu itemWithTitle:name] setTag:[[serverMenu itemWithTitle:name] tag] - 1];
-       }
-       
-       [serverMenu removeAllItemsWithTitle:name];
-       
-       // if this is the last broadcast server, take away the divider.
-       if ( [serverMenu numberOfItems] == 3 )
-       {
-               [serverMenu removeItemAtIndex:2];
-       }
-}
-
-
-@end
-
-
-// Internal Functions
-void TCPlaySound( NSString *name )
-{
-       if ( TCGlobalPlaySounds )
-       {
-               [[NSSound soundNamed:name] play];
-       }
-}
diff --git a/StatusTextField.h b/StatusTextField.h
new file mode 100644 (file)
index 0000000..bd99877
--- /dev/null
@@ -0,0 +1,40 @@
+
+// **********************************************************************
+// 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 <Cocoa/Cocoa.h>
+
+
+@interface StatusTextField : NSTextField
+{
+       NSString *myDefaultStatus;
+       NSColor *myDefaultColor;
+       
+       NSTimer *myTimer;
+}
+
+- (void)setDefaultStatus:(NSString *)message; // defaults to black
+- (void)setDefaultStatus:(NSString *)message color:(NSColor *)color;
+
+- (void)setTemporaryStatus:(NSString *)message; // defaults to black
+- (void)setTemporaryStatus:(NSString *)message color:(NSColor *)color; // defaults to 4 seconds
+- (void)setTemporaryStatus:(NSString *)message duration:(NSTimeInterval)duration;
+- (void)setTemporaryStatus:(NSString *)message color:(NSColor *)color duration:(NSTimeInterval)duration;
+
+@end
diff --git a/StatusTextField.m b/StatusTextField.m
new file mode 100644 (file)
index 0000000..fa8f353
--- /dev/null
@@ -0,0 +1,132 @@
+
+// **********************************************************************
+// 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 "StatusTextField.h"
+
+
+@interface StatusTextField ( Private )
+
+- (void)doTimer:(NSTimer *)timer;
+
+@end
+
+
+@implementation StatusTextField
+
+
+- (id)init
+{
+       if ( self = [super init] ) {
+               myTimer = nil;
+       }
+       return self;
+}
+
+- (void)dealloc
+{
+       [myDefaultStatus release];
+       [myTimer invalidate];
+       [myTimer release];
+       
+       [super dealloc];
+}
+
+
+- (void)setDefaultStatus:(NSString *)message
+{
+       [self setDefaultStatus:message color:[NSColor blackColor]];
+}
+
+- (void)setDefaultStatus:(NSString *)message color:(NSColor *)color
+{
+       if ( !message ) {
+               message = [NSString stringWithString:@""];
+       }
+       if ( !color ) {
+               color = [NSColor blackColor];
+       }
+       // save the new values
+       [message retain];
+       [myDefaultStatus release];
+       myDefaultStatus = message;
+       // save the new values
+       [color retain];
+       [myDefaultColor release];
+       myDefaultColor = color;
+       // set the new default if there isn't already a temp showing
+       if ( !myTimer ) {
+               [self setStringValue:myDefaultStatus];
+               [self setTextColor:myDefaultColor];
+       }
+}
+
+
+- (void)setTemporaryStatus:(NSString *)message
+{
+       [self setTemporaryStatus:message color:[NSColor blackColor]];
+}
+
+- (void)setTemporaryStatus:(NSString *)message color:(NSColor *)color
+{
+       [self setTemporaryStatus:message color:color duration:4.0];
+}
+
+- (void)setTemporaryStatus:(NSString *)message duration:(NSTimeInterval)duration
+{
+       [self setTemporaryStatus:message color:[NSColor blackColor] duration:duration];
+}
+
+- (void)setTemporaryStatus:(NSString *)message color:(NSColor *)color duration:(NSTimeInterval)duration
+{
+       // stop any current temporary status
+       [myTimer invalidate];
+       [myTimer release];
+       
+       if ( !message ) {
+               message = [NSString stringWithString:@""];
+       }
+       if ( !color ) {
+               color = [NSColor blackColor];
+       }
+       // set the new temporary status
+       [self setStringValue:message];
+       [self setTextColor:color];
+       // start the timer
+       myTimer = [[NSTimer scheduledTimerWithTimeInterval:duration target:self selector:@selector(doTimer:) userInfo:nil repeats:NO] retain];
+}
+
+
+- (void)doTimer:(NSTimer *)timer
+{
+       // kill the timer
+       [myTimer release];
+       myTimer = nil;
+       
+       // set the default status
+       if ( myDefaultStatus ) {
+               [self setStringValue:myDefaultStatus];
+       }
+       if ( myDefaultColor ) {
+               [self setTextColor:myDefaultColor];
+       }
+}
+
+
+@end
diff --git a/The Cheat.pbproj/chaz.pbxuser b/The Cheat.pbproj/chaz.pbxuser
deleted file mode 100644 (file)
index d912312..0000000
+++ /dev/null
@@ -1,2133 +0,0 @@
-// !$*UTF8*$!
-{
-       089C1660FE840EACC02AAC07 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 584}}";
-                       sepNavSelRange = "{110, 0}";
-                       sepNavVisRect = "{{0, 0}, {1002, 584}}";
-               };
-       };
-       2A37F4A9FDCFA73011CA2CEA = {
-               activeBuildStyle = 4A9504D1FFE6A4CB11CA0CBA;
-               activeExecutable = 6EF8EC0A055A1730008BBE46;
-               activeTarget = 6EF8EBD9055A1730008BBE46;
-               addToTargets = (
-                       6EF8EBD9055A1730008BBE46,
-               );
-               breakpoints = (
-                       6EF0870C0575382B00B81D60,
-               );
-               codeSenseManager = 6EAD5EEB054C3932005761EE;
-               executables = (
-                       6EF8EC0A055A1730008BBE46,
-               );
-               perUserDictionary = {
-                       PBXConfiguration.PBXFileTableDataSource3.PBXBookmarksDataSource = {
-                               PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
-                               PBXFileTableDataSourceColumnSortingKey = PBXBookmarksDataSource_NameID;
-                               PBXFileTableDataSourceColumnWidthsKey = (
-                                       532.2085,
-                                       517.5991,
-                               );
-                               PBXFileTableDataSourceColumnsKey = (
-                                       PBXBookmarksDataSource_LocationID,
-                                       PBXBookmarksDataSource_NameID,
-                               );
-                       };
-                       PBXConfiguration.PBXFileTableDataSource3.PBXErrorsWarningsDataSource = {
-                               PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
-                               PBXFileTableDataSourceColumnSortingKey = PBXErrorsWarningsDataSource_MessageID;
-                               PBXFileTableDataSourceColumnWidthsKey = (
-                                       20,
-                                       651.8799,
-                                       348.2085,
-                               );
-                               PBXFileTableDataSourceColumnsKey = (
-                                       PBXErrorsWarningsDataSource_TypeID,
-                                       PBXErrorsWarningsDataSource_MessageID,
-                                       PBXErrorsWarningsDataSource_LocationID,
-                               );
-                       };
-                       PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = {
-                               PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
-                               PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID;
-                               PBXFileTableDataSourceColumnWidthsKey = (
-                                       22,
-                                       1000,
-                               );
-                               PBXFileTableDataSourceColumnsKey = (
-                                       PBXExecutablesDataSource_ActiveFlagID,
-                                       PBXExecutablesDataSource_NameID,
-                               );
-                       };
-                       PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
-                               PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
-                               PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
-                               PBXFileTableDataSourceColumnWidthsKey = (
-                                       20,
-                                       729,
-                                       20,
-                                       129,
-                                       43,
-                                       43,
-                                       20,
-                               );
-                               PBXFileTableDataSourceColumnsKey = (
-                                       PBXFileDataSource_FiletypeID,
-                                       PBXFileDataSource_Filename_ColumnID,
-                                       PBXFileDataSource_Built_ColumnID,
-                                       PBXFileDataSource_ObjectSize_ColumnID,
-                                       PBXFileDataSource_Errors_ColumnID,
-                                       PBXFileDataSource_Warnings_ColumnID,
-                                       PBXFileDataSource_Target_ColumnID,
-                               );
-                       };
-                       PBXConfiguration.PBXFileTableDataSource3.PBXFindDataSource = {
-                               PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
-                               PBXFileTableDataSourceColumnSortingKey = PBXFindDataSource_LocationID;
-                               PBXFileTableDataSourceColumnWidthsKey = (
-                                       523.2974,
-                                       526.2085,
-                               );
-                               PBXFileTableDataSourceColumnsKey = (
-                                       PBXFindDataSource_MessageID,
-                                       PBXFindDataSource_LocationID,
-                               );
-                       };
-                       PBXConfiguration.PBXFileTableDataSource3.PBXSymbolsDataSource = {
-                               PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
-                               PBXFileTableDataSourceColumnSortingKey = PBXSymbolsDataSource_SymbolNameID;
-                               PBXFileTableDataSourceColumnWidthsKey = (
-                                       16,
-                                       322.8008,
-                                       350.0356,
-                                       327.2085,
-                               );
-                               PBXFileTableDataSourceColumnsKey = (
-                                       PBXSymbolsDataSource_SymbolTypeIconID,
-                                       PBXSymbolsDataSource_SymbolNameID,
-                                       PBXSymbolsDataSource_SymbolTypeID,
-                                       PBXSymbolsDataSource_ReferenceNameID,
-                               );
-                       };
-                       PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = {
-                               PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
-                               PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
-                               PBXFileTableDataSourceColumnWidthsKey = (
-                                       20,
-                                       616,
-                                       131,
-                                       20,
-                                       131,
-                                       43,
-                                       43,
-                               );
-                               PBXFileTableDataSourceColumnsKey = (
-                                       PBXFileDataSource_FiletypeID,
-                                       PBXFileDataSource_Filename_ColumnID,
-                                       PBXTargetDataSource_PrimaryAttribute,
-                                       PBXFileDataSource_Built_ColumnID,
-                                       PBXFileDataSource_ObjectSize_ColumnID,
-                                       PBXFileDataSource_Errors_ColumnID,
-                                       PBXFileDataSource_Warnings_ColumnID,
-                               );
-                       };
-                       PBXPerProjectTemplateStateSaveDate = 101460657;
-                       PBXPrepackagedSmartGroups_v2 = (
-                               {
-                                       PBXTransientLocationAtTop = bottom;
-                                       absolutePathToBundle = "";
-                                       activationKey = OldTargetSmartGroup;
-                                       clz = PBXTargetSmartGroup;
-                                       description = "Displays all targets of the project.";
-                                       globalID = 1C37FABC04509CD000000102;
-                                       name = Targets;
-                                       preferences = {
-                                               image = Targets;
-                                       };
-                               },
-                               {
-                                       PBXTransientLocationAtTop = bottom;
-                                       absolutePathToBundle = "";
-                                       clz = PBXTargetSmartGroup2;
-                                       description = "Displays all targets of the project as well as nested build phases.";
-                                       globalID = 1C37FBAC04509CD000000102;
-                                       name = Targets;
-                                       preferences = {
-                                               image = Targets;
-                                       };
-                               },
-                               {
-                                       PBXTransientLocationAtTop = bottom;
-                                       absolutePathToBundle = "";
-                                       clz = PBXExecutablesSmartGroup;
-                                       description = "Displays all executables of the project.";
-                                       globalID = 1C37FAAC04509CD000000102;
-                                       name = Executables;
-                                       preferences = {
-                                               image = Executable;
-                                       };
-                               },
-                               {
-                                       " PBXTransientLocationAtTop " = bottom;
-                                       absolutePathToBundle = "";
-                                       clz = PBXErrorsWarningsSmartGroup;
-                                       description = "Displays files with errors or warnings.";
-                                       globalID = 1C08E77C0454961000C914BD;
-                                       name = "Errors and Warnings";
-                                       preferences = {
-                                               fnmatch = "";
-                                               image = WarningsErrors;
-                                               recursive = 1;
-                                               regex = "";
-                                               root = "<PROJECT>";
-                                       };
-                               },
-                               {
-                                       PBXTransientLocationAtTop = bottom;
-                                       absolutePathToBundle = "";
-                                       clz = PBXFilenameSmartGroup;
-                                       description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter.";
-                                       globalID = 1CC0EA4004350EF90044410B;
-                                       name = "Implementation Files";
-                                       preferences = {
-                                               canSave = 1;
-                                               fnmatch = "";
-                                               image = SmartFolder;
-                                               isLeaf = 0;
-                                               recursive = 1;
-                                               regex = "?*\\.[mcMC]";
-                                               root = "<PROJECT>";
-                                       };
-                               },
-                               {
-                                       PBXTransientLocationAtTop = bottom;
-                                       absolutePathToBundle = "";
-                                       clz = PBXFilenameSmartGroup;
-                                       description = "This group displays Interface Builder NIB Files.";
-                                       globalID = 1CC0EA4004350EF90041110B;
-                                       name = "NIB Files";
-                                       preferences = {
-                                               canSave = 1;
-                                               fnmatch = "*.nib";
-                                               image = SmartFolder;
-                                               isLeaf = 0;
-                                               recursive = 1;
-                                               regex = "";
-                                               root = "<PROJECT>";
-                                       };
-                               },
-                               {
-                                       PBXTransientLocationAtTop = no;
-                                       absolutePathToBundle = "";
-                                       clz = PBXFindSmartGroup;
-                                       description = "Displays Find Results.";
-                                       globalID = 1C37FABC05509CD000000102;
-                                       name = "Find Results";
-                                       preferences = {
-                                               image = spyglass;
-                                       };
-                               },
-                               {
-                                       PBXTransientLocationAtTop = no;
-                                       absolutePathToBundle = "";
-                                       clz = PBXBookmarksSmartGroup;
-                                       description = "Displays Project Bookmarks.";
-                                       globalID = 1C37FABC05539CD112110102;
-                                       name = Bookmarks;
-                                       preferences = {
-                                               image = Bookmarks;
-                                       };
-                               },
-                               {
-                                       PBXTransientLocationAtTop = bottom;
-                                       absolutePathToBundle = "";
-                                       clz = XCSCMSmartGroup;
-                                       description = "Displays files with interesting SCM status.";
-                                       globalID = E2644B35053B69B200211256;
-                                       name = SCM;
-                                       preferences = {
-                                               image = PBXRepository;
-                                               isLeaf = 0;
-                                       };
-                               },
-                               {
-                                       PBXTransientLocationAtTop = bottom;
-                                       absolutePathToBundle = "";
-                                       clz = PBXSymbolsSmartGroup;
-                                       description = "Displays all symbols for the project.";
-                                       globalID = 1C37FABC04509CD000100104;
-                                       name = "Project Symbols";
-                                       preferences = {
-                                               image = ProjectSymbols;
-                                               isLeaf = 1;
-                                       };
-                               },
-                               {
-                                       PBXTransientLocationAtTop = bottom;
-                                       absolutePathToBundle = "";
-                                       clz = PBXFilenameSmartGroup;
-                                       description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter.";
-                                       globalID = PBXTemplateMarker;
-                                       name = "Simple Filter SmartGroup";
-                                       preferences = {
-                                               canSave = 1;
-                                               fnmatch = "*.nib";
-                                               image = SmartFolder;
-                                               isLeaf = 0;
-                                               recursive = 1;
-                                               regex = "";
-                                               root = "<PROJECT>";
-                                       };
-                               },
-                               {
-                                       PBXTransientLocationAtTop = bottom;
-                                       absolutePathToBundle = "";
-                                       clz = PBXFilenameSmartGroup;
-                                       description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter.";
-                                       globalID = PBXTemplateMarker;
-                                       name = "Simple Regular Expression SmartGroup";
-                                       preferences = {
-                                               canSave = 1;
-                                               fnmatch = "";
-                                               image = SmartFolder;
-                                               isLeaf = 0;
-                                               recursive = 1;
-                                               regex = "?*\\.[mcMC]";
-                                               root = "<PROJECT>";
-                                       };
-                               },
-                       );
-                       PBXWorkspaceContents = (
-                               {
-                                       PBXProjectWorkspaceModule_StateKey_Rev39 = {
-                                               PBXProjectWorkspaceModule_DEGV_Geometry = {
-                                                       _collapsingFrameDimension = 0;
-                                                       _indexOfCollapsedView = 0;
-                                                       _percentageOfCollapsedView = 0;
-                                                       isCollapsed = yes;
-                                                       sizes = (
-                                                               "{{0, 0}, {1047, 125}}",
-                                                               "{{0, 125}, {1047, 744}}",
-                                                       );
-                                               };
-                                               PBXProjectWorkspaceModule_DataSourceSelectionKey_Rev6 = {
-                                                       BoundsStr = "{{0, 0}, {1032, 108}}";
-                                                       Rows = (
-                                                               0,
-                                                       );
-                                                       VisibleRectStr = "{{0, 0}, {1032, 108}}";
-                                               };
-                                               PBXProjectWorkspaceModule_EditorOpen = true;
-                                               PBXProjectWorkspaceModule_EmbeddedNavigatorGroup = {
-                                                       PBXSplitModuleInNavigatorKey = {
-                                                               Split0 = {
-                                                                       bookmark = 6EF4D0BF060C2CF300F4728B;
-                                                                       history = (
-                                                                               6E90C09D05FA7EAA00857F22,
-                                                                               6E90C0DC05FA979F00857F22,
-                                                                               6E90C16605FAA5FB00857F22,
-                                                                               6E90C39A05FC0B3600857F22,
-                                                                               6E8DD55E05FC512600D2C0EA,
-                                                                               6E8DD56405FC5BD100D2C0EA,
-                                                                               6E8DD5EA05FC607A00D2C0EA,
-                                                                               6E8DD64605FC674200D2C0EA,
-                                                                               6E8DD66605FC696100D2C0EA,
-                                                                               6E8DD68105FC6AF400D2C0EA,
-                                                                               6E8DD6EA05FC748B00D2C0EA,
-                                                                               6E8DD70C05FC762900D2C0EA,
-                                                                               6E8DD71105FC762C00D2C0EA,
-                                                                               6E8DD71605FC763300D2C0EA,
-                                                                               6E8DD71B05FC763C00D2C0EA,
-                                                                               6E8DD75305FC778700D2C0EA,
-                                                                               6E55007005FD2C9D00EE693C,
-                                                                               6E6A7F8005FEDDD3004D2DF3,
-                                                                               6E6A7FAB05FEDEE9004D2DF3,
-                                                                               6E6A7FD805FEE064004D2DF3,
-                                                                               6EE811830602584A00F1CD3F,
-                                                                               6EE811C40602592500F1CD3F,
-                                                                               6EE811EE060259D600F1CD3F,
-                                                                               6EE811FD06025A4300F1CD3F,
-                                                                               6EE8120F06025ABA00F1CD3F,
-                                                                               6EE8122306025C6300F1CD3F,
-                                                                               6E8DD76205FC783B00D2C0EA,
-                                                                               6EE815E40602A97C00F1CD3F,
-                                                                               6E1B2CDA060AB14300B6B2F9,
-                                                                               6E1B2CDB060AB14300B6B2F9,
-                                                                               6E1B2CDC060AB14300B6B2F9,
-                                                                               6E1B2CDD060AB14300B6B2F9,
-                                                                               6E1B2CDE060AB14300B6B2F9,
-                                                                               6E1B2CDF060AB14300B6B2F9,
-                                                                               6E1B2CE0060AB14300B6B2F9,
-                                                                               6E1B2CE2060AB14300B6B2F9,
-                                                                               6E1B2D45060AC5AC00B6B2F9,
-                                                                               6E976BD3060BC2AB00FDABB0,
-                                                                               6E976BD4060BC2AB00FDABB0,
-                                                                               6EF4D0B9060C2CF300F4728B,
-                                                                               6EF4D0BA060C2CF300F4728B,
-                                                                               6EF4D0BB060C2CF300F4728B,
-                                                                       );
-                                                                       prevStack = (
-                                                                               6E486275059421D8006D09F8,
-                                                                               6E486276059421D8006D09F8,
-                                                                               6E486277059421D8006D09F8,
-                                                                               6E48627C059421D8006D09F8,
-                                                                               6E9D6CED059429D400D9A2D7,
-                                                                               6E8EDFDA05F7DBEE00ED3F4F,
-                                                                               6E90BB0805F7EC7600857F22,
-                                                                               6E90BE2A05F86C7800857F22,
-                                                                               6E90BE4F05F86D1000857F22,
-                                                                               6E90BE5405F86D3200857F22,
-                                                                               6E90C09A05FA7EA900857F22,
-                                                                               6E90C09E05FA7EAA00857F22,
-                                                                               6E90C16705FAA5FB00857F22,
-                                                                               6E90C28705FAADF700857F22,
-                                                                               6E90C35F05FB0DAD00857F22,
-                                                                               6E90C36C05FC07B100857F22,
-                                                                               6E8DD58F05FC5D1E00D2C0EA,
-                                                                               6E8DD65F05FC692500D2C0EA,
-                                                                               6E8DD68A05FC6B5C00D2C0EA,
-                                                                               6E8DD6F305FC74F400D2C0EA,
-                                                                               6E8DD70505FC761C00D2C0EA,
-                                                                               6E8DD70905FC762000D2C0EA,
-                                                                               6E8DD71305FC762C00D2C0EA,
-                                                                               6E8DD71805FC763300D2C0EA,
-                                                                               6E8DD71C05FC763C00D2C0EA,
-                                                                               6EE811D50602595D00F1CD3F,
-                                                                               6EE811FF06025A4300F1CD3F,
-                                                                               6EE8121006025ABA00F1CD3F,
-                                                                               6EE8122406025C6300F1CD3F,
-                                                                               6EE81236060274E900F1CD3F,
-                                                                               6E1B2CE9060AB14300B6B2F9,
-                                                                               6E1B2CEC060AB14300B6B2F9,
-                                                                               6E1B2CED060AB14300B6B2F9,
-                                                                               6E1B2CFD060AB14300B6B2F9,
-                                                                               6E1B2D07060AB14300B6B2F9,
-                                                                               6E1B2D08060AB14300B6B2F9,
-                                                                               6EF4D0BC060C2CF300F4728B,
-                                                                               6EF4D0BD060C2CF300F4728B,
-                                                                               6EF4D0BE060C2CF300F4728B,
-                                                                       );
-                                                               };
-                                                               SplitCount = 1;
-                                                       };
-                                               };
-                                               PBXProjectWorkspaceModule_GeometryKey_Rev15 = {
-                                                       PBXProjectWorkspaceModule_SGTM_Geometry = {
-                                                               _collapsingFrameDimension = 0;
-                                                               _indexOfCollapsedView = 0;
-                                                               _percentageOfCollapsedView = 0;
-                                                               sizes = (
-                                                                       "{{0, 0}, {233, 869}}",
-                                                                       "{{233, 0}, {1047, 869}}",
-                                                               );
-                                                       };
-                                               };
-                                               PBXProjectWorkspaceModule_OldDetailFrame = "{{0, 0}, {1047, 125}}";
-                                               PBXProjectWorkspaceModule_OldEditorFrame = "{{0, 125}, {1047, 744}}";
-                                               PBXProjectWorkspaceModule_OldSuperviewFrame = "{{233, 0}, {1047, 869}}";
-                                               PBXProjectWorkspaceModule_SGTM = {
-                                                       PBXBottomSmartGroupGIDs = (
-                                                               1C37FBAC04509CD000000102,
-                                                               1C37FAAC04509CD000000102,
-                                                               1C08E77C0454961000C914BD,
-                                                               1CC0EA4004350EF90044410B,
-                                                               1CC0EA4004350EF90041110B,
-                                                               1C37FABC05509CD000000102,
-                                                               1C37FABC05539CD112110102,
-                                                               E2644B35053B69B200211256,
-                                                               1C37FABC04509CD000100104,
-                                                       );
-                                                       PBXSmartGroupTreeModuleColumnData = {
-                                                               PBXSmartGroupTreeModuleColumnWidthsKey = (
-                                                                       216,
-                                                               );
-                                                               PBXSmartGroupTreeModuleColumnsKey_v4 = (
-                                                                       MainColumn,
-                                                               );
-                                                       };
-                                                       PBXSmartGroupTreeModuleOutlineStateKey_v7 = {
-                                                               PBXSmartGroupTreeModuleOutlineStateExpansionKey = (
-                                                                       2A37F4AAFDCFA73011CA2CEA,
-                                                                       6E0D40B3052243B800A80003,
-                                                                       2A37F4ABFDCFA73011CA2CEA,
-                                                                       6E0D40BF05224F4B00A80003,
-                                                                       2A37F4AFFDCFA73011CA2CEA,
-                                                                       2A37F4B8FDCFA73011CA2CEA,
-                                                                       6E8EE12505F7EA8100ED3F4F,
-                                                                       1058C7A6FEA54F5311CA2CBB,
-                                                                       6E90BC2805F7FB9000857F22,
-                                                                       1C37FBAC04509CD000000102,
-                                                               );
-                                                               PBXSmartGroupTreeModuleOutlineStateSelectionKey = (
-                                                                       (
-                                                                               11,
-                                                                               1,
-                                                                               0,
-                                                                       ),
-                                                               );
-                                                               PBXSmartGroupTreeModuleOutlineStateVisibleRectKey = "{{0, 0}, {216, 851}}";
-                                                       };
-                                                       PBXTopSmartGroupGIDs = (
-                                                       );
-                                               };
-                                       };
-                               },
-                       );
-                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXBatchFindModule" = {
-                       };
-                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXBuildResultsModule" = {
-                       };
-                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXClassBrowserModule" = {
-                               OptionsSetName = "Hierarchy, project classes";
-                       };
-                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXDebugBreakpointsModule" = {
-                       };
-                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXDebugCLIModule" = {
-                       };
-                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXDebugSessionModule" = {
-                               Debugger = {
-                                       HorizontalSplitView = {
-                                               _collapsingFrameDimension = 0;
-                                               _indexOfCollapsedView = 0;
-                                               _percentageOfCollapsedView = 0;
-                                               isCollapsed = yes;
-                                               sizes = (
-                                                       "{{0, 0}, {327, 349}}",
-                                                       "{{327, 0}, {534, 349}}",
-                                               );
-                                       };
-                                       VerticalSplitView = {
-                                               _collapsingFrameDimension = 0;
-                                               _indexOfCollapsedView = 0;
-                                               _percentageOfCollapsedView = 0;
-                                               isCollapsed = yes;
-                                               sizes = (
-                                                       "{{0, 0}, {861, 349}}",
-                                                       "{{0, 349}, {861, 366}}",
-                                               );
-                                       };
-                               };
-                               LauncherConfigVersion = 8;
-                       };
-                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXNavigatorGroup" = {
-                               Split0 = {
-                                       bookmark = 6ECC8F0E0579B23800AA179F;
-                                       history = (
-                                               6ECC8F0D0579B23800AA179F,
-                                       );
-                               };
-                               SplitCount = 1;
-                       };
-                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXProjectFindModule" = {
-                       };
-                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXProjectWorkspaceModule" = {
-                               PBXProjectWorkspaceModule_StateKey_Rev39 = {
-                                       PBXProjectWorkspaceModule_DEGV_Geometry = {
-                                               _collapsingFrameDimension = 0;
-                                               _indexOfCollapsedView = 0;
-                                               _percentageOfCollapsedView = 0;
-                                               isCollapsed = yes;
-                                               sizes = (
-                                                       "{{0, 0}, {1047, 233}}",
-                                                       "{{0, 233}, {1047, 636}}",
-                                               );
-                                       };
-                                       PBXProjectWorkspaceModule_DataSourceSelectionKey_Rev6 = {
-                                               BoundsStr = "{{0, 0}, {1032, 216}}";
-                                               Rows = (
-                                                       0,
-                                               );
-                                               VisibleRectStr = "{{0, 0}, {1032, 216}}";
-                                       };
-                                       PBXProjectWorkspaceModule_EditorOpen = true;
-                                       PBXProjectWorkspaceModule_EmbeddedNavigatorGroup = {
-                                               PBXSplitModuleInNavigatorKey = {
-                                                       Split0 = {
-                                                               bookmark = 6E1900E8060570B5001883C1;
-                                                               history = (
-                                                                       6E90C09D05FA7EAA00857F22,
-                                                                       6E90C0DC05FA979F00857F22,
-                                                                       6E90C16605FAA5FB00857F22,
-                                                                       6E90C39A05FC0B3600857F22,
-                                                                       6E8DD55E05FC512600D2C0EA,
-                                                                       6E8DD56405FC5BD100D2C0EA,
-                                                                       6E8DD5D705FC5F3500D2C0EA,
-                                                                       6E8DD5EA05FC607A00D2C0EA,
-                                                                       6E8DD64605FC674200D2C0EA,
-                                                                       6E8DD66605FC696100D2C0EA,
-                                                                       6E8DD68105FC6AF400D2C0EA,
-                                                                       6E8DD6EA05FC748B00D2C0EA,
-                                                                       6E8DD70C05FC762900D2C0EA,
-                                                                       6E8DD71105FC762C00D2C0EA,
-                                                                       6E8DD71605FC763300D2C0EA,
-                                                                       6E8DD71B05FC763C00D2C0EA,
-                                                                       6E8DD74405FC776700D2C0EA,
-                                                                       6E8DD75305FC778700D2C0EA,
-                                                                       6E55007005FD2C9D00EE693C,
-                                                                       6E55007205FD2C9D00EE693C,
-                                                                       6E55008505FD2CD800EE693C,
-                                                                       6E6A7F7C05FEDDCB004D2DF3,
-                                                                       6E6A7F8005FEDDD3004D2DF3,
-                                                                       6E6A7FAB05FEDEE9004D2DF3,
-                                                                       6E6A7FD805FEE064004D2DF3,
-                                                                       6EE811830602584A00F1CD3F,
-                                                                       6EE811C40602592500F1CD3F,
-                                                                       6EE811E20602598600F1CD3F,
-                                                                       6EE811EE060259D600F1CD3F,
-                                                                       6EE811FD06025A4300F1CD3F,
-                                                                       6EE8120F06025ABA00F1CD3F,
-                                                                       6EE8122306025C6300F1CD3F,
-                                                                       6E8DD76205FC783B00D2C0EA,
-                                                                       6EE815E40602A97C00F1CD3F,
-                                                                       6EE815E80602A98100F1CD3F,
-                                                                       6EE8168C0602B00100F1CD3F,
-                                                                       6E78A01A06043FA3008F8B51,
-                                                               );
-                                                               prevStack = (
-                                                                       6E486275059421D8006D09F8,
-                                                                       6E486276059421D8006D09F8,
-                                                                       6E486277059421D8006D09F8,
-                                                                       6E48627C059421D8006D09F8,
-                                                                       6E9D6CED059429D400D9A2D7,
-                                                                       6E8EDFDA05F7DBEE00ED3F4F,
-                                                                       6E90BB0805F7EC7600857F22,
-                                                                       6E90BE2A05F86C7800857F22,
-                                                                       6E90BE4F05F86D1000857F22,
-                                                                       6E90BE5405F86D3200857F22,
-                                                                       6E90C09A05FA7EA900857F22,
-                                                                       6E90C09E05FA7EAA00857F22,
-                                                                       6E90C16705FAA5FB00857F22,
-                                                                       6E90C28705FAADF700857F22,
-                                                                       6E90C35F05FB0DAD00857F22,
-                                                                       6E90C36C05FC07B100857F22,
-                                                                       6E8DD58F05FC5D1E00D2C0EA,
-                                                                       6E8DD65F05FC692500D2C0EA,
-                                                                       6E8DD68A05FC6B5C00D2C0EA,
-                                                                       6E8DD6F305FC74F400D2C0EA,
-                                                                       6E8DD70505FC761C00D2C0EA,
-                                                                       6E8DD70905FC762000D2C0EA,
-                                                                       6E8DD71305FC762C00D2C0EA,
-                                                                       6E8DD71805FC763300D2C0EA,
-                                                                       6E8DD71C05FC763C00D2C0EA,
-                                                                       6E55006805FD21B800EE693C,
-                                                                       6EE811D50602595D00F1CD3F,
-                                                                       6EE811FF06025A4300F1CD3F,
-                                                                       6EE8121006025ABA00F1CD3F,
-                                                                       6EE8122406025C6300F1CD3F,
-                                                                       6EE81236060274E900F1CD3F,
-                                                               );
-                                                       };
-                                                       SplitCount = 1;
-                                               };
-                                       };
-                                       PBXProjectWorkspaceModule_GeometryKey_Rev15 = {
-                                               PBXProjectWorkspaceModule_SGTM_Geometry = {
-                                                       _collapsingFrameDimension = 0;
-                                                       _indexOfCollapsedView = 0;
-                                                       _percentageOfCollapsedView = 0;
-                                                       sizes = (
-                                                               "{{0, 0}, {233, 869}}",
-                                                               "{{233, 0}, {1047, 869}}",
-                                                       );
-                                               };
-                                       };
-                                       PBXProjectWorkspaceModule_OldDetailFrame = "{{0, 0}, {1047, 233}}";
-                                       PBXProjectWorkspaceModule_OldEditorFrame = "{{0, 233}, {1047, 636}}";
-                                       PBXProjectWorkspaceModule_OldSuperviewFrame = "{{233, 0}, {1047, 869}}";
-                                       PBXProjectWorkspaceModule_SGTM = {
-                                               PBXBottomSmartGroupGIDs = (
-                                                       1C37FBAC04509CD000000102,
-                                                       1C37FAAC04509CD000000102,
-                                                       1C08E77C0454961000C914BD,
-                                                       1CC0EA4004350EF90044410B,
-                                                       1CC0EA4004350EF90041110B,
-                                                       1C37FABC05509CD000000102,
-                                                       1C37FABC05539CD112110102,
-                                                       E2644B35053B69B200211256,
-                                                       1C37FABC04509CD000100104,
-                                               );
-                                               PBXSmartGroupTreeModuleColumnData = {
-                                                       PBXSmartGroupTreeModuleColumnWidthsKey = (
-                                                               216,
-                                                       );
-                                                       PBXSmartGroupTreeModuleColumnsKey_v4 = (
-                                                               MainColumn,
-                                                       );
-                                               };
-                                               PBXSmartGroupTreeModuleOutlineStateKey_v7 = {
-                                                       PBXSmartGroupTreeModuleOutlineStateExpansionKey = (
-                                                               2A37F4AAFDCFA73011CA2CEA,
-                                                               6E0D40B3052243B800A80003,
-                                                               2A37F4ABFDCFA73011CA2CEA,
-                                                               6E0D40BF05224F4B00A80003,
-                                                               2A37F4AFFDCFA73011CA2CEA,
-                                                               2A37F4B8FDCFA73011CA2CEA,
-                                                               6E8EE12505F7EA8100ED3F4F,
-                                                               1C37FBAC04509CD000000102,
-                                                       );
-                                                       PBXSmartGroupTreeModuleOutlineStateSelectionKey = (
-                                                               (
-                                                                       42,
-                                                                       37,
-                                                                       0,
-                                                               ),
-                                                       );
-                                                       PBXSmartGroupTreeModuleOutlineStateVisibleRectKey = "{{0, 0}, {216, 851}}";
-                                               };
-                                               PBXTopSmartGroupGIDs = (
-                                               );
-                                       };
-                               };
-                       };
-                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXRunSessionModule" = {
-                               LauncherConfigVersion = 3;
-                               Runner = {
-                                       HorizontalSplitView = {
-                                               _collapsingFrameDimension = 0;
-                                               _indexOfCollapsedView = 0;
-                                               _percentageOfCollapsedView = 0;
-                                               isCollapsed = yes;
-                                               sizes = (
-                                                       "{{0, 0}, {365, 167}}",
-                                                       "{{0, 176}, {365, 267}}",
-                                               );
-                                       };
-                                       VerticalSplitView = {
-                                               _collapsingFrameDimension = 0;
-                                               _indexOfCollapsedView = 0;
-                                               _percentageOfCollapsedView = 0;
-                                               isCollapsed = yes;
-                                               sizes = (
-                                                       "{{0, 0}, {405, 443}}",
-                                                       "{{414, 0}, {514, 443}}",
-                                               );
-                                       };
-                               };
-                       };
-                       PBXWorkspaceGeometries = (
-                               {
-                                       Frame = "{{0, 0}, {1280, 869}}";
-                                       PBXProjectWorkspaceModule_GeometryKey_Rev15 = {
-                                               PBXProjectWorkspaceModule_DebuggerWindowVisible = true;
-                                               PBXProjectWorkspaceModule_RunWindowVisible = true;
-                                       };
-                                       RubberWindowFrame = "0 91 1280 911 0 0 1280 1002 ";
-                               },
-                       );
-                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXBatchFindModule" = {
-                               Frame = "{{0, 0}, {543, 158}}";
-                               WindowFrame = "{{369, 822}, {543, 158}}";
-                       };
-                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXBuildResultsModule" = {
-                               Frame = "{{0, 0}, {1126, 575}}";
-                               PBXModuleWindowStatusBarHidden = YES;
-                               RubberWindowFrame = "80 221 1126 596 0 0 1280 1002 ";
-                       };
-                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXClassBrowserModule" = {
-                               ClassesFrame = "{{0, 0}, {408, 92}}";
-                               ClassesTreeTableConfiguration = (
-                                       PBXClassNameColumnIdentifier,
-                                       208,
-                                       PBXClassBookColumnIdentifier,
-                                       22,
-                               );
-                               Frame = "{{0, 0}, {655, 496}}";
-                               MembersFrame = "{{0, 92}, {408, 384}}";
-                               MembersTreeTableConfiguration = (
-                                       PBXMemberTypeIconColumnIdentifier,
-                                       22,
-                                       PBXMemberNameColumnIdentifier,
-                                       216,
-                                       PBXMemberTypeColumnIdentifier,
-                                       133,
-                                       PBXMemberBookColumnIdentifier,
-                                       22,
-                               );
-                               WindowFrame = "{{312, 398}, {655, 574}}";
-                       };
-                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXDebugBreakpointsModule" = {
-                               BreakpointsTreeTableConfiguration = (
-                                       enabledColumn,
-                                       16,
-                                       breakpointColumn,
-                                       282.583,
-                               );
-                               Frame = "{{0, 0}, {208, 494}}";
-                               WindowFrame = "{{390, 424}, {208, 516}}";
-                       };
-                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXDebugCLIModule" = {
-                               Frame = "{{0, 0}, {400, 201}}";
-                               PBXModuleWindowStatusBarHidden = YES;
-                               RubberWindowFrame = "50 974 400 222 0 0 1280 1002 ";
-                       };
-                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXDebugSessionModule" = {
-                               DebugConsoleDrawerSize = "{100, 120}";
-                               DebugConsoleVisible = Drawer;
-                               DebugConsoleWindowFrame = "{{200, 200}, {500, 300}}";
-                               DebugSTDIOWindowFrame = "{{200, 200}, {500, 300}}";
-                               Frame = "{{0, 0}, {861, 715}}";
-                               RubberWindowFrame = "381 245 861 757 0 0 1280 1002 ";
-                       };
-                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXNavigatorGroup" = {
-                               Frame = "{{0, 0}, {750, 480}}";
-                               WindowFrame = "{{61, 397}, {750, 558}}";
-                       };
-                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXProjectFindModule" = {
-                               Frame = "{{0, 0}, {634, 488}}";
-                               RubberWindowFrame = "373 471 634 530 0 0 1280 1002 ";
-                       };
-                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXProjectWorkspaceModule" = {
-                               Frame = "{{0, 0}, {1280, 869}}";
-                               PBXProjectWorkspaceModule_GeometryKey_Rev15 = {
-                               };
-                               RubberWindowFrame = "0 91 1280 911 0 0 1280 1002 ";
-                       };
-                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXRunSessionModule" = {
-                               Frame = "{{0, 0}, {767, 743}}";
-                               PBXModuleWindowStatusBarHidden = YES;
-                               RubberWindowFrame = "398 146 767 764 0 0 1280 1002 ";
-                       };
-                       PBXWorkspaceStateSaveDate = 101460657;
-               };
-               perUserProjectItems = {
-                       6E1B2CDA060AB14300B6B2F9 = 6E1B2CDA060AB14300B6B2F9;
-                       6E1B2CDB060AB14300B6B2F9 = 6E1B2CDB060AB14300B6B2F9;
-                       6E1B2CDC060AB14300B6B2F9 = 6E1B2CDC060AB14300B6B2F9;
-                       6E1B2CDD060AB14300B6B2F9 = 6E1B2CDD060AB14300B6B2F9;
-                       6E1B2CDE060AB14300B6B2F9 = 6E1B2CDE060AB14300B6B2F9;
-                       6E1B2CDF060AB14300B6B2F9 = 6E1B2CDF060AB14300B6B2F9;
-                       6E1B2CE0060AB14300B6B2F9 = 6E1B2CE0060AB14300B6B2F9;
-                       6E1B2CE2060AB14300B6B2F9 = 6E1B2CE2060AB14300B6B2F9;
-                       6E1B2CE9060AB14300B6B2F9 = 6E1B2CE9060AB14300B6B2F9;
-                       6E1B2CEC060AB14300B6B2F9 = 6E1B2CEC060AB14300B6B2F9;
-                       6E1B2CED060AB14300B6B2F9 = 6E1B2CED060AB14300B6B2F9;
-                       6E1B2CFD060AB14300B6B2F9 = 6E1B2CFD060AB14300B6B2F9;
-                       6E1B2D07060AB14300B6B2F9 = 6E1B2D07060AB14300B6B2F9;
-                       6E1B2D08060AB14300B6B2F9 = 6E1B2D08060AB14300B6B2F9;
-                       6E1B2D45060AC5AC00B6B2F9 = 6E1B2D45060AC5AC00B6B2F9;
-                       6E486275059421D8006D09F8 = 6E486275059421D8006D09F8;
-                       6E486276059421D8006D09F8 = 6E486276059421D8006D09F8;
-                       6E486277059421D8006D09F8 = 6E486277059421D8006D09F8;
-                       6E48627C059421D8006D09F8 = 6E48627C059421D8006D09F8;
-                       6E55007005FD2C9D00EE693C = 6E55007005FD2C9D00EE693C;
-                       6E6A7F8005FEDDD3004D2DF3 = 6E6A7F8005FEDDD3004D2DF3;
-                       6E6A7FAB05FEDEE9004D2DF3 = 6E6A7FAB05FEDEE9004D2DF3;
-                       6E6A7FD805FEE064004D2DF3 = 6E6A7FD805FEE064004D2DF3;
-                       6E8DD55E05FC512600D2C0EA = 6E8DD55E05FC512600D2C0EA;
-                       6E8DD56405FC5BD100D2C0EA = 6E8DD56405FC5BD100D2C0EA;
-                       6E8DD58F05FC5D1E00D2C0EA = 6E8DD58F05FC5D1E00D2C0EA;
-                       6E8DD5EA05FC607A00D2C0EA = 6E8DD5EA05FC607A00D2C0EA;
-                       6E8DD64605FC674200D2C0EA = 6E8DD64605FC674200D2C0EA;
-                       6E8DD65F05FC692500D2C0EA = 6E8DD65F05FC692500D2C0EA;
-                       6E8DD66605FC696100D2C0EA = 6E8DD66605FC696100D2C0EA;
-                       6E8DD68105FC6AF400D2C0EA = 6E8DD68105FC6AF400D2C0EA;
-                       6E8DD68A05FC6B5C00D2C0EA = 6E8DD68A05FC6B5C00D2C0EA;
-                       6E8DD6EA05FC748B00D2C0EA = 6E8DD6EA05FC748B00D2C0EA;
-                       6E8DD6F305FC74F400D2C0EA = 6E8DD6F305FC74F400D2C0EA;
-                       6E8DD70505FC761C00D2C0EA = 6E8DD70505FC761C00D2C0EA;
-                       6E8DD70905FC762000D2C0EA = 6E8DD70905FC762000D2C0EA;
-                       6E8DD70C05FC762900D2C0EA = 6E8DD70C05FC762900D2C0EA;
-                       6E8DD71105FC762C00D2C0EA = 6E8DD71105FC762C00D2C0EA;
-                       6E8DD71305FC762C00D2C0EA = 6E8DD71305FC762C00D2C0EA;
-                       6E8DD71605FC763300D2C0EA = 6E8DD71605FC763300D2C0EA;
-                       6E8DD71805FC763300D2C0EA = 6E8DD71805FC763300D2C0EA;
-                       6E8DD71B05FC763C00D2C0EA = 6E8DD71B05FC763C00D2C0EA;
-                       6E8DD71C05FC763C00D2C0EA = 6E8DD71C05FC763C00D2C0EA;
-                       6E8DD75305FC778700D2C0EA = 6E8DD75305FC778700D2C0EA;
-                       6E8DD76205FC783B00D2C0EA = 6E8DD76205FC783B00D2C0EA;
-                       6E8EDFDA05F7DBEE00ED3F4F = 6E8EDFDA05F7DBEE00ED3F4F;
-                       6E90BB0805F7EC7600857F22 = 6E90BB0805F7EC7600857F22;
-                       6E90BE2A05F86C7800857F22 = 6E90BE2A05F86C7800857F22;
-                       6E90BE4F05F86D1000857F22 = 6E90BE4F05F86D1000857F22;
-                       6E90BE5405F86D3200857F22 = 6E90BE5405F86D3200857F22;
-                       6E90C09A05FA7EA900857F22 = 6E90C09A05FA7EA900857F22;
-                       6E90C09D05FA7EAA00857F22 = 6E90C09D05FA7EAA00857F22;
-                       6E90C09E05FA7EAA00857F22 = 6E90C09E05FA7EAA00857F22;
-                       6E90C0DC05FA979F00857F22 = 6E90C0DC05FA979F00857F22;
-                       6E90C16605FAA5FB00857F22 = 6E90C16605FAA5FB00857F22;
-                       6E90C16705FAA5FB00857F22 = 6E90C16705FAA5FB00857F22;
-                       6E90C28705FAADF700857F22 = 6E90C28705FAADF700857F22;
-                       6E90C35F05FB0DAD00857F22 = 6E90C35F05FB0DAD00857F22;
-                       6E90C36C05FC07B100857F22 = 6E90C36C05FC07B100857F22;
-                       6E90C39A05FC0B3600857F22 = 6E90C39A05FC0B3600857F22;
-                       6E976BD3060BC2AB00FDABB0 = 6E976BD3060BC2AB00FDABB0;
-                       6E976BD4060BC2AB00FDABB0 = 6E976BD4060BC2AB00FDABB0;
-                       6E9D6CED059429D400D9A2D7 = 6E9D6CED059429D400D9A2D7;
-                       6EE811830602584A00F1CD3F = 6EE811830602584A00F1CD3F;
-                       6EE811C40602592500F1CD3F = 6EE811C40602592500F1CD3F;
-                       6EE811D50602595D00F1CD3F = 6EE811D50602595D00F1CD3F;
-                       6EE811EE060259D600F1CD3F = 6EE811EE060259D600F1CD3F;
-                       6EE811FD06025A4300F1CD3F = 6EE811FD06025A4300F1CD3F;
-                       6EE811FF06025A4300F1CD3F = 6EE811FF06025A4300F1CD3F;
-                       6EE8120F06025ABA00F1CD3F = 6EE8120F06025ABA00F1CD3F;
-                       6EE8121006025ABA00F1CD3F = 6EE8121006025ABA00F1CD3F;
-                       6EE8122306025C6300F1CD3F = 6EE8122306025C6300F1CD3F;
-                       6EE8122406025C6300F1CD3F = 6EE8122406025C6300F1CD3F;
-                       6EE81236060274E900F1CD3F = 6EE81236060274E900F1CD3F;
-                       6EE815E40602A97C00F1CD3F = 6EE815E40602A97C00F1CD3F;
-                       6EF4D0B9060C2CF300F4728B = 6EF4D0B9060C2CF300F4728B;
-                       6EF4D0BA060C2CF300F4728B = 6EF4D0BA060C2CF300F4728B;
-                       6EF4D0BB060C2CF300F4728B = 6EF4D0BB060C2CF300F4728B;
-                       6EF4D0BC060C2CF300F4728B = 6EF4D0BC060C2CF300F4728B;
-                       6EF4D0BD060C2CF300F4728B = 6EF4D0BD060C2CF300F4728B;
-                       6EF4D0BE060C2CF300F4728B = 6EF4D0BE060C2CF300F4728B;
-                       6EF4D0BF060C2CF300F4728B = 6EF4D0BF060C2CF300F4728B;
-               };
-               sourceControlManager = 6EAD5EEA054C3932005761EE;
-               userBuildSettings = {
-               };
-       };
-       2A37F4ACFDCFA73011CA2CEA = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {2309, 29919}}";
-                       sepNavSelRange = "{23043, 0}";
-                       sepNavVisRect = "{{0, 14084}, {1002, 712}}";
-                       sepNavWindowFrame = "{{15, 439}, {750, 558}}";
-               };
-       };
-       2A37F4AEFDCFA73011CA2CEA = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 3232}}";
-                       sepNavSelRange = "{3017, 0}";
-                       sepNavVisRect = "{{0, 663}, {1002, 712}}";
-               };
-       };
-       2A37F4B0FDCFA73011CA2CEA = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 594}}";
-                       sepNavSelRange = "{363, 0}";
-                       sepNavVisRect = "{{0, 0}, {1002, 594}}";
-               };
-       };
-       2A37F4B7FDCFA73011CA2CEA = {
-               uiCtxt = {
-                       sepNavWindowFrame = "{{61, 397}, {750, 558}}";
-               };
-       };
-       32DBCF750370BD2300C91783 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 616}}";
-                       sepNavSelRange = "{162, 8}";
-                       sepNavVisRect = "{{0, 0}, {1002, 616}}";
-               };
-       };
-       6E0BDF7D0511568D00A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1266, 655}}";
-                       sepNavSelRange = "{504, 0}";
-                       sepNavVisRect = "{{0, 0}, {1002, 597}}";
-               };
-       };
-       6E0D40AC05223CCE00A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 800}}";
-                       sepNavSelRange = "{256, 0}";
-                       sepNavVisRect = "{{0, 92}, {1002, 616}}";
-               };
-       };
-       6E0D40AD05223CCE00A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 2960}}";
-                       sepNavSelRange = "{1743, 0}";
-                       sepNavVisRect = "{{0, 959}, {1002, 594}}";
-               };
-       };
-       6E0D40B4052243D500A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 736}}";
-                       sepNavSelRange = "{362, 0}";
-                       sepNavVisRect = "{{0, 104}, {1002, 616}}";
-               };
-       };
-       6E0D40B5052243D500A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1133, 1872}}";
-                       sepNavSelRange = "{1682, 0}";
-                       sepNavVisRect = "{{0, 1002}, {1002, 616}}";
-               };
-       };
-       6E0D40B80522449500A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 656}}";
-                       sepNavSelRange = "{355, 0}";
-                       sepNavVisRect = "{{0, 0}, {1002, 616}}";
-               };
-       };
-       6E0D40B90522449500A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1224, 2912}}";
-                       sepNavSelRange = "{4006, 0}";
-                       sepNavVisRect = "{{0, 2372}, {822, 329}}";
-               };
-       };
-       6E0D40C005224FD000A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 587}}";
-                       sepNavSelRange = "{0, 0}";
-                       sepNavVisRect = "{{0, 0}, {1002, 587}}";
-               };
-       };
-       6E0D40C405225DA100A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 834}}";
-                       sepNavSelRange = "{377, 53}";
-                       sepNavVisRect = "{{0, 0}, {1002, 834}}";
-               };
-       };
-       6E0D40CA0522815100A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 587}}";
-                       sepNavSelRange = "{0, 0}";
-                       sepNavVisRect = "{{0, 0}, {1002, 587}}";
-               };
-       };
-       6E0D40CE0522820D00A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 587}}";
-                       sepNavSelRange = "{0, 0}";
-                       sepNavVisRect = "{{0, 0}, {1002, 587}}";
-               };
-       };
-       6E146B11051FA42C00A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 616}}";
-                       sepNavSelRange = "{353, 0}";
-                       sepNavVisRect = "{{0, 0}, {1002, 616}}";
-               };
-       };
-       6E146B12051FA42C00A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 3680}}";
-                       sepNavSelRange = "{424, 0}";
-                       sepNavVisRect = "{{0, 0}, {1002, 616}}";
-               };
-       };
-       6E1B2CDA060AB14300B6B2F9 = {
-               fRef = 6E71F41B051BCCC600A80003;
-               isa = PBXTextBookmark;
-               name = "cheat_globals.h: 23";
-               rLen = 0;
-               rLoc = 688;
-               rType = 0;
-               vrLen = 1265;
-               vrLoc = 106;
-       };
-       6E1B2CDB060AB14300B6B2F9 = {
-               fRef = 6E3F0D01050D4ACC00A80003;
-               isa = PBXTextBookmark;
-               name = "cheat_net.h: 29";
-               rLen = 0;
-               rLoc = 725;
-               rType = 0;
-               vrLen = 832;
-               vrLoc = 0;
-       };
-       6E1B2CDC060AB14300B6B2F9 = {
-               fRef = 6E3F0D02050D4ACC00A80003;
-               isa = PBXTextBookmark;
-               name = "int SendBuffer( int sockfd, char const *buffer, int *length )\n";
-               rLen = 62;
-               rLoc = 1498;
-               rType = 0;
-               vrLen = 520;
-               vrLoc = 1378;
-       };
-       6E1B2CDD060AB14300B6B2F9 = {
-               fRef = 6E4E098F050BB21400A80003;
-               isa = PBXTextBookmark;
-               name = "CheatServer.h: maxSearchResultsAmount";
-               rLen = 0;
-               rLoc = 884;
-               rType = 0;
-               vrLen = 681;
-               vrLoc = 438;
-       };
-       6E1B2CDE060AB14300B6B2F9 = {
-               fRef = 2A37F4B0FDCFA73011CA2CEA;
-               isa = PBXTextBookmark;
-               name = "main.m: 14";
-               rLen = 0;
-               rLoc = 363;
-               rType = 0;
-               vrLen = 477;
-               vrLoc = 0;
-       };
-       6E1B2CDF060AB14300B6B2F9 = {
-               fRef = 6E1B2D18060AB14400B6B2F9;
-               isa = PBXTextBookmark;
-               name = "(null): 26";
-               rLen = 0;
-               rLoc = 530;
-               rType = 0;
-               vrLen = 1163;
-               vrLoc = 0;
-       };
-       6E1B2CE0060AB14300B6B2F9 = {
-               fRef = 6E1B2D17060AB14400B6B2F9;
-               isa = PBXTextBookmark;
-               name = "(null): 1";
-               rLen = 0;
-               rLoc = 0;
-               rType = 0;
-               vrLen = 390;
-               vrLoc = 0;
-       };
-       6E1B2CE2060AB14300B6B2F9 = {
-               fRef = 6E0D40AD05223CCE00A80003;
-               isa = PBXTextBookmark;
-               name = "NetTrafficController.m: 79";
-               rLen = 0;
-               rLoc = 1743;
-               rType = 0;
-               vrLen = 885;
-               vrLoc = 1326;
-       };
-       6E1B2CE9060AB14300B6B2F9 = {
-               fRef = 6E3F0D01050D4ACC00A80003;
-               isa = PBXTextBookmark;
-               name = "cheat_net.h: 14";
-               rLen = 0;
-               rLoc = 370;
-               rType = 0;
-               vrLen = 816;
-               vrLoc = 0;
-       };
-       6E1B2CEC060AB14300B6B2F9 = {
-               fRef = 6E4E098E050BB21400A80003;
-               isa = PBXTextBookmark;
-               name = SendBuffer;
-               rLen = 10;
-               rLoc = 31880;
-               rType = 0;
-               vrLen = 1001;
-               vrLoc = 30972;
-       };
-       6E1B2CED060AB14300B6B2F9 = {
-               fRef = 6E3F0D02050D4ACC00A80003;
-               isa = PBXTextBookmark;
-               name = "int SendBuffer( int sockfd, char const *buffer, int *length )\n";
-               rLen = 62;
-               rLoc = 1498;
-               rType = 0;
-               vrLen = 520;
-               vrLoc = 1378;
-       };
-       6E1B2CFD060AB14300B6B2F9 = {
-               fRef = 2A37F4B0FDCFA73011CA2CEA;
-               isa = PBXTextBookmark;
-               name = "main.m: 14";
-               rLen = 0;
-               rLoc = 363;
-               rType = 0;
-               vrLen = 477;
-               vrLoc = 0;
-       };
-       6E1B2D07060AB14300B6B2F9 = {
-               fRef = 6E1B2D16060AB14400B6B2F9;
-               isa = PBXTextBookmark;
-               name = "(null): 26";
-               rLen = 0;
-               rLoc = 530;
-               rType = 0;
-               vrLen = 1163;
-               vrLoc = 0;
-       };
-       6E1B2D08060AB14300B6B2F9 = {
-               fRef = 6E1B2D1A060AB14400B6B2F9;
-               isa = PBXTextBookmark;
-               name = "(null): 1";
-               rLen = 0;
-               rLoc = 0;
-               rType = 0;
-               vrLen = 390;
-               vrLoc = 0;
-       };
-       6E1B2D16060AB14400B6B2F9 = {
-               isa = PBXFileReference;
-               lastKnownFileType = sourcecode.c.h;
-               name = CMUpdateCheck.h;
-               path = /Users/chaz/Projects/Chaz/build/Chaz.framework/Versions/A/Headers/CMUpdateCheck.h;
-               refType = 0;
-               sourceTree = "<absolute>";
-       };
-       6E1B2D17060AB14400B6B2F9 = {
-               isa = PBXFileReference;
-               lastKnownFileType = sourcecode.c.h;
-               name = CMStatusView.h;
-               path = /Users/chaz/Projects/Chaz/build/Chaz.framework/Versions/A/Headers/CMStatusView.h;
-               refType = 0;
-               sourceTree = "<absolute>";
-       };
-       6E1B2D18060AB14400B6B2F9 = {
-               isa = PBXFileReference;
-               lastKnownFileType = sourcecode.c.h;
-               name = CMUpdateCheck.h;
-               path = /Users/chaz/Projects/Chaz/build/Chaz.framework/Versions/A/Headers/CMUpdateCheck.h;
-               refType = 0;
-               sourceTree = "<absolute>";
-       };
-       6E1B2D1A060AB14400B6B2F9 = {
-               isa = PBXFileReference;
-               lastKnownFileType = sourcecode.c.h;
-               name = CMStatusView.h;
-               path = /Users/chaz/Projects/Chaz/build/Chaz.framework/Versions/A/Headers/CMStatusView.h;
-               refType = 0;
-               sourceTree = "<absolute>";
-       };
-       6E1B2D45060AC5AC00B6B2F9 = {
-               fRef = 6E4E098E050BB21400A80003;
-               isa = PBXTextBookmark;
-               name = "CheatServer.m: 1564";
-               rLen = 0;
-               rLoc = 37370;
-               rType = 0;
-               vrLen = 635;
-               vrLoc = 37133;
-       };
-       6E3F0D01050D4ACC00A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 831}}";
-                       sepNavSelRange = "{725, 0}";
-                       sepNavVisRect = "{{0, 0}, {1002, 594}}";
-               };
-       };
-       6E3F0D02050D4ACC00A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 1808}}";
-                       sepNavSelRange = "{1498, 62}";
-                       sepNavVisRect = "{{0, 939}, {1002, 594}}";
-               };
-       };
-       6E486275059421D8006D09F8 = {
-               fRef = 6E4E098C050BB21400A80003;
-               isa = PBXTextBookmark;
-               name = "AppController.h: launchWebsiteMenu:";
-               rLen = 0;
-               rLoc = 1572;
-               rType = 0;
-               vrLen = 986;
-               vrLoc = 516;
-       };
-       6E486276059421D8006D09F8 = {
-               fRef = 6E51A987057330B900506538;
-               isa = PBXTextBookmark;
-               name = "cheat_shared.m: 21";
-               rLen = 0;
-               rLoc = 609;
-               rType = 0;
-               vrLen = 607;
-               vrLoc = 0;
-       };
-       6E486277059421D8006D09F8 = {
-               fRef = 6E51A986057330B900506538;
-               isa = PBXTextBookmark;
-               name = "cheat_shared.h: 17";
-               rLen = 0;
-               rLoc = 401;
-               rType = 0;
-               vrLen = 409;
-               vrLoc = 0;
-       };
-       6E48627C059421D8006D09F8 = {
-               fRef = 6E146B12051FA42C00A80003;
-               isa = PBXTextBookmark;
-               name = "CheatClient.m: 149";
-               rLen = 0;
-               rLoc = 3391;
-               rType = 0;
-               vrLen = 894;
-               vrLoc = 3020;
-       };
-       6E4E098C050BB21400A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 1072}}";
-                       sepNavSelRange = "{1308, 0}";
-                       sepNavVisRect = "{{0, 440}, {1002, 611}}";
-               };
-       };
-       6E4E098D050BB21400A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1063, 8784}}";
-                       sepNavSelRange = "{1035, 0}";
-                       sepNavVisRect = "{{0, 447}, {1002, 594}}";
-               };
-       };
-       6E4E098E050BB21400A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1287, 33760}}";
-                       sepNavSelRange = "{37370, 0}";
-                       sepNavVisRect = "{{0, 24832}, {1002, 589}}";
-                       sepNavWindowFrame = "{{0, 51}, {1280, 951}}";
-               };
-       };
-       6E4E098F050BB21400A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 1711}}";
-                       sepNavSelRange = "{884, 0}";
-                       sepNavVisRect = "{{0, 288}, {1002, 594}}";
-               };
-       };
-       6E51A97C0573304C00506538 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 616}}";
-                       sepNavSelRange = "{335, 0}";
-                       sepNavVisRect = "{{0, 0}, {1002, 616}}";
-               };
-       };
-       6E51A97D0573304C00506538 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 671}}";
-                       sepNavSelRange = "{372, 0}";
-                       sepNavVisRect = "{{0, 55}, {1002, 616}}";
-               };
-       };
-       6E51A986057330B900506538 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 587}}";
-                       sepNavSelRange = "{401, 0}";
-                       sepNavVisRect = "{{0, 0}, {1002, 587}}";
-               };
-       };
-       6E51A987057330B900506538 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 587}}";
-                       sepNavSelRange = "{456, 0}";
-                       sepNavVisRect = "{{0, 0}, {1002, 587}}";
-               };
-       };
-       6E55007005FD2C9D00EE693C = {
-               fRef = 6E55007605FD2CAE00EE693C;
-               isa = PBXTextBookmark;
-               name = "kern_return_t vm_read_overwrite\n";
-               rLen = 32;
-               rLoc = 3105;
-               rType = 0;
-               vrLen = 843;
-               vrLoc = 2681;
-       };
-       6E55007605FD2CAE00EE693C = {
-               isa = PBXFileReference;
-               lastKnownFileType = sourcecode.c.h;
-               name = vm_map.h;
-               path = /Developer/SDKs/MacOSX10.2.7.sdk/usr/include/mach/vm_map.h;
-               refType = 0;
-               sourceTree = "<absolute>";
-       };
-       6E6A7F8005FEDDD3004D2DF3 = {
-               fRef = 6E0D40C405225DA100A80003;
-               isa = PBXTextBookmark;
-               name = "- (void)preferenceSetWindowsOnTop:(BOOL)windowsOnTop;";
-               rLen = 53;
-               rLoc = 377;
-               rType = 0;
-               vrLen = 695;
-               vrLoc = 0;
-       };
-       6E6A7FAB05FEDEE9004D2DF3 = {
-               fRef = 6E6A7FB105FEDEF5004D2DF3;
-               isa = PBXTextBookmark;
-               name = "@interface NSNotification : NSObject <NSCopying, NSCoding>\n";
-               rLen = 59;
-               rLoc = 195;
-               rType = 0;
-               vrLen = 1240;
-               vrLoc = 0;
-       };
-       6E6A7FB105FEDEF5004D2DF3 = {
-               isa = PBXFileReference;
-               lastKnownFileType = sourcecode.c.h;
-               name = NSNotification.h;
-               path = /Developer/SDKs/MacOSX10.2.7.sdk/System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSNotification.h;
-               refType = 0;
-               sourceTree = "<absolute>";
-       };
-       6E6A7FD805FEE064004D2DF3 = {
-               fRef = 6E0D40B4052243D500A80003;
-               isa = PBXTextBookmark;
-               name = "- (IBAction)apply:(id)sender";
-               rLen = 28;
-               rLoc = 936;
-               rType = 0;
-               vrLen = 834;
-               vrLoc = 176;
-       };
-       6E71F41B051BCCC600A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 719}}";
-                       sepNavSelRange = "{688, 0}";
-                       sepNavVisRect = "{{0, 63}, {1002, 594}}";
-               };
-       };
-       6E71F41C051BCCC600A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 616}}";
-                       sepNavSelRange = "{405, 20}";
-                       sepNavVisRect = "{{0, 0}, {1002, 616}}";
-               };
-       };
-       6E8DD55E05FC512600D2C0EA = {
-               fRef = 6E51A986057330B900506538;
-               isa = PBXTextBookmark;
-               name = "cheat_shared.h: 17";
-               rLen = 0;
-               rLoc = 401;
-               rType = 0;
-               vrLen = 409;
-               vrLoc = 0;
-       };
-       6E8DD56405FC5BD100D2C0EA = {
-               fRef = 6E51A987057330B900506538;
-               isa = PBXTextBookmark;
-               name = "cheat_shared.m: LaunchWebsite";
-               rLen = 0;
-               rLoc = 456;
-               rType = 0;
-               vrLen = 611;
-               vrLoc = 0;
-       };
-       6E8DD58F05FC5D1E00D2C0EA = {
-               fRef = 2A37F4AEFDCFA73011CA2CEA;
-               isa = PBXTextBookmark;
-               name = "MyDocument.h: maxSearchResultsAmount";
-               rLen = 0;
-               rLoc = 1041;
-               rType = 0;
-               vrLen = 850;
-               vrLoc = 576;
-       };
-       6E8DD5EA05FC607A00D2C0EA = {
-               fRef = 6E8DD5EF05FC609800D2C0EA;
-               isa = PBXTextBookmark;
-               name = "- (void)setToolTip:(NSString *)string;\n";
-               rLen = 39;
-               rLoc = 7558;
-               rType = 0;
-               vrLen = 1345;
-               vrLoc = 6975;
-       };
-       6E8DD5EF05FC609800D2C0EA = {
-               isa = PBXFileReference;
-               lastKnownFileType = sourcecode.c.h;
-               name = NSView.h;
-               path = /Developer/SDKs/MacOSX10.2.7.sdk/System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSView.h;
-               refType = 0;
-               sourceTree = "<absolute>";
-       };
-       6E8DD64605FC674200D2C0EA = {
-               fRef = 6E8DD64F05FC674900D2C0EA;
-               isa = PBXTextBookmark;
-               name = "- (void)orderOut:(id)sender;\n";
-               rLen = 29;
-               rLoc = 9802;
-               rType = 0;
-               vrLen = 1051;
-               vrLoc = 9293;
-       };
-       6E8DD64F05FC674900D2C0EA = {
-               isa = PBXFileReference;
-               lastKnownFileType = sourcecode.c.h;
-               name = NSWindow.h;
-               path = /Developer/SDKs/MacOSX10.2.7.sdk/System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSWindow.h;
-               refType = 0;
-               sourceTree = "<absolute>";
-       };
-       6E8DD65F05FC692500D2C0EA = {
-               fRef = 6E0D40C005224FD000A80003;
-               isa = PBXTextBookmark;
-               name = "NetTrafficControlling.h: 1";
-               rLen = 0;
-               rLoc = 0;
-               rType = 0;
-               vrLen = 501;
-               vrLoc = 0;
-       };
-       6E8DD66605FC696100D2C0EA = {
-               fRef = 6E51A97C0573304C00506538;
-               isa = PBXTextBookmark;
-               name = "AboutBoxController.h: nameVersionText";
-               rLen = 0;
-               rLoc = 476;
-               rType = 0;
-               vrLen = 573;
-               vrLoc = 0;
-       };
-       6E8DD68105FC6AF400D2C0EA = {
-               fRef = 6E8DD68505FC6B1200D2C0EA;
-               isa = PBXTextBookmark;
-               name = "    NSOnState    =  1    \n";
-               rLen = 26;
-               rLoc = 1481;
-               rType = 0;
-               vrLen = 837;
-               vrLoc = 1061;
-       };
-       6E8DD68505FC6B1200D2C0EA = {
-               isa = PBXFileReference;
-               lastKnownFileType = sourcecode.c.h;
-               name = NSCell.h;
-               path = /Developer/SDKs/MacOSX10.2.7.sdk/System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSCell.h;
-               refType = 0;
-               sourceTree = "<absolute>";
-       };
-       6E8DD68A05FC6B5C00D2C0EA = {
-               fRef = 6E0D40B5052243D500A80003;
-               isa = PBXTextBookmark;
-               name = "PreferenceController.m: 172";
-               rLen = 0;
-               rLoc = 3248;
-               rType = 0;
-               vrLen = 0;
-               vrLoc = 3290;
-       };
-       6E8DD6EA05FC748B00D2C0EA = {
-               fRef = 6E8DD6ED05FC74A900D2C0EA;
-               isa = PBXTextBookmark;
-               name = "@interface NSNetService : NSObject {\n";
-               rLen = 37;
-               rLoc = 678;
-               rType = 0;
-               vrLen = 2029;
-               vrLoc = 529;
-       };
-       6E8DD6ED05FC74A900D2C0EA = {
-               isa = PBXFileReference;
-               lastKnownFileType = sourcecode.c.h;
-               name = NSNetServices.h;
-               path = /Developer/SDKs/MacOSX10.2.7.sdk/System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSNetServices.h;
-               refType = 0;
-               sourceTree = "<absolute>";
-       };
-       6E8DD6F305FC74F400D2C0EA = {
-               fRef = 6E4E098D050BB21400A80003;
-               isa = PBXTextBookmark;
-               name = broadcastWithName;
-               rLen = 17;
-               rLoc = 2917;
-               rType = 0;
-               vrLen = 1300;
-               vrLoc = 1648;
-       };
-       6E8DD70505FC761C00D2C0EA = {
-               fRef = 6E0D40AD05223CCE00A80003;
-               isa = PBXTextBookmark;
-               name = "- (void)allowRemoteChanged:(BOOL)allow\n";
-               rLen = 39;
-               rLoc = 2038;
-               rType = 0;
-               vrLen = 728;
-               vrLoc = 1206;
-       };
-       6E8DD70905FC762000D2C0EA = {
-               fRef = 6E0D40AC05223CCE00A80003;
-               isa = PBXTextBookmark;
-               name = "NetTrafficController.h: 1";
-               rLen = 0;
-               rLoc = 0;
-               rType = 0;
-               vrLen = 894;
-               vrLoc = 0;
-       };
-       6E8DD70C05FC762900D2C0EA = {
-               fRef = 6E0D40C005224FD000A80003;
-               isa = PBXTextBookmark;
-               name = "NetTrafficControlling.h: 1";
-               rLen = 0;
-               rLoc = 0;
-               rType = 0;
-               vrLen = 501;
-               vrLoc = 0;
-       };
-       6E8DD71105FC762C00D2C0EA = {
-               fRef = 6E0D40CA0522815100A80003;
-               isa = PBXTextBookmark;
-               name = "ListenerDelegate.h: 1";
-               rLen = 0;
-               rLoc = 0;
-               rType = 0;
-               vrLen = 568;
-               vrLoc = 0;
-       };
-       6E8DD71305FC762C00D2C0EA = {
-               fRef = 6E0D40CA0522815100A80003;
-               isa = PBXTextBookmark;
-               name = "ListenerDelegate.h: 1";
-               rLen = 0;
-               rLoc = 0;
-               rType = 0;
-               vrLen = 568;
-               vrLoc = 0;
-       };
-       6E8DD71605FC763300D2C0EA = {
-               fRef = 6EBCEEE60523E23700A80003;
-               isa = PBXTextBookmark;
-               name = "ServerDelegate.h: 1";
-               rLen = 0;
-               rLoc = 0;
-               rType = 0;
-               vrLen = 738;
-               vrLoc = 0;
-       };
-       6E8DD71805FC763300D2C0EA = {
-               fRef = 6EBCEEE60523E23700A80003;
-               isa = PBXTextBookmark;
-               name = "ServerDelegate.h: 1";
-               rLen = 0;
-               rLoc = 0;
-               rType = 0;
-               vrLen = 738;
-               vrLoc = 0;
-       };
-       6E8DD71B05FC763C00D2C0EA = {
-               fRef = 6E0D40CE0522820D00A80003;
-               isa = PBXTextBookmark;
-               name = "ClientDelegate.h: 1";
-               rLen = 0;
-               rLoc = 0;
-               rType = 0;
-               vrLen = 530;
-               vrLoc = 0;
-       };
-       6E8DD71C05FC763C00D2C0EA = {
-               fRef = 6E0D40CE0522820D00A80003;
-               isa = PBXTextBookmark;
-               name = "ClientDelegate.h: 1";
-               rLen = 0;
-               rLoc = 0;
-               rType = 0;
-               vrLen = 530;
-               vrLoc = 0;
-       };
-       6E8DD75305FC778700D2C0EA = {
-               fRef = 6E0D40AC05223CCE00A80003;
-               isa = PBXTextBookmark;
-               name = serverSet;
-               rLen = 9;
-               rLoc = 800;
-               rType = 0;
-               vrLen = 832;
-               vrLoc = 235;
-       };
-       6E8DD76205FC783B00D2C0EA = {
-               fRef = 2A37F4B5FDCFA73011CA2CEA;
-               isa = PBXBookmark;
-               name = "MyDocument.nib (English)";
-       };
-       6E8EDFDA05F7DBEE00ED3F4F = {
-               fRef = 6E71F41B051BCCC600A80003;
-               isa = PBXTextBookmark;
-               name = "cheat_globals.h: 21";
-               rLen = 0;
-               rLoc = 648;
-               rType = 0;
-               vrLen = 1218;
-               vrLoc = 0;
-       };
-       6E90BB0805F7EC7600857F22 = {
-               fRef = 6E4E098F050BB21400A80003;
-               isa = PBXTextBookmark;
-               name = "
-";
-               rLen = 1;
-               rLoc = 1118;
-               rType = 0;
-               vrLen = 727;
-               vrLoc = 0;
-       };
-       6E90BE2A05F86C7800857F22 = {
-               fRef = 6E71F41C051BCCC600A80003;
-               isa = PBXTextBookmark;
-               name = "cheat_globals.m: TCGlobalUpdateAutomatically";
-               rLen = 0;
-               rLoc = 619;
-               rType = 0;
-               vrLen = 994;
-               vrLoc = 0;
-       };
-       6E90BE4F05F86D1000857F22 = {
-               fRef = 6E0D40C405225DA100A80003;
-               isa = PBXTextBookmark;
-               name = "PreferenceControlling.h: 1";
-               rLen = 0;
-               rLoc = 0;
-               rType = 0;
-               vrLen = 536;
-               vrLoc = 0;
-       };
-       6E90BE5405F86D3200857F22 = {
-               fRef = 6E0D40B4052243D500A80003;
-               isa = PBXTextBookmark;
-               name = "PreferenceController.h: updateAutomaticallyButton";
-               rLen = 0;
-               rLoc = 635;
-               rType = 0;
-               vrLen = 904;
-               vrLoc = 106;
-       };
-       6E90C09A05FA7EA900857F22 = {
-               fRef = 6E1E43700588275100526509;
-               isa = PBXBookmark;
-       };
-       6E90C09D05FA7EAA00857F22 = {
-               fRef = 6E0BDF7D0511568D00A80003;
-               isa = PBXTextBookmark;
-               name = "cheat_types.h: 23";
-               rLen = 0;
-               rLoc = 504;
-               rType = 0;
-               vrLen = 939;
-               vrLoc = 0;
-       };
-       6E90C09E05FA7EAA00857F22 = {
-               fRef = 6E0BDF7D0511568D00A80003;
-               isa = PBXTextBookmark;
-               name = "cheat_types.h: 23";
-               rLen = 0;
-               rLoc = 504;
-               rType = 0;
-               vrLen = 939;
-               vrLoc = 0;
-       };
-       6E90C0DC05FA979F00857F22 = {
-               fRef = 6E1E43700588275100526509;
-               isa = PBXBookmark;
-       };
-       6E90C16605FAA5FB00857F22 = {
-               fRef = 6E90C16A05FAA60C00857F22;
-               isa = PBXTextBookmark;
-               name = "(null): 1";
-               rLen = 0;
-               rLoc = 0;
-               rType = 0;
-               vrLen = 1316;
-               vrLoc = 3041;
-       };
-       6E90C16705FAA5FB00857F22 = {
-               fRef = 6E90C16905FAA60C00857F22;
-               isa = PBXTextBookmark;
-               name = "(null): 1";
-               rLen = 0;
-               rLoc = 0;
-               rType = 0;
-               vrLen = 1316;
-               vrLoc = 3041;
-       };
-       6E90C16905FAA60C00857F22 = {
-               isa = PBXFileReference;
-               lastKnownFileType = sourcecode.c.h;
-               name = string.h;
-               path = /usr/include/string.h;
-               refType = 0;
-               sourceTree = "<absolute>";
-       };
-       6E90C16A05FAA60C00857F22 = {
-               isa = PBXFileReference;
-               lastKnownFileType = sourcecode.c.h;
-               name = string.h;
-               path = /usr/include/string.h;
-               refType = 0;
-               sourceTree = "<absolute>";
-       };
-       6E90C28705FAADF700857F22 = {
-               fRef = 6EF8EC08055A1730008BBE46;
-               isa = PBXTextBookmark;
-               name = "Info-The_Cheat.plist: 1";
-               rLen = 0;
-               rLoc = 0;
-               rType = 0;
-               vrLen = 952;
-               vrLoc = 218;
-       };
-       6E90C35F05FB0DAD00857F22 = {
-               fRef = 6E51A97D0573304C00506538;
-               isa = PBXTextBookmark;
-               name = "AboutBoxController.m: 20";
-               rLen = 0;
-               rLoc = 424;
-               rType = 0;
-               vrLen = 656;
-               vrLoc = 0;
-       };
-       6E90C36C05FC07B100857F22 = {
-               fRef = 6E51A97C0573304C00506538;
-               isa = PBXTextBookmark;
-               name = "AboutBoxController.h: aboutWindow";
-               rLen = 0;
-               rLoc = 431;
-               rType = 0;
-               vrLen = 533;
-               vrLoc = 0;
-       };
-       6E90C39A05FC0B3600857F22 = {
-               fRef = 6E51A97D0573304C00506538;
-               isa = PBXTextBookmark;
-               name = "AboutBoxController.m: 28";
-               rLen = 0;
-               rLoc = 623;
-               rType = 0;
-               vrLen = 646;
-               vrLoc = 174;
-       };
-       6E976BD3060BC2AB00FDABB0 = {
-               fRef = 6E4E098D050BB21400A80003;
-               isa = PBXTextBookmark;
-               name = "AppController.m: 41";
-               rLen = 0;
-               rLoc = 1033;
-               rType = 0;
-               vrLen = 1865;
-               vrLoc = 569;
-       };
-       6E976BD4060BC2AB00FDABB0 = {
-               fRef = 089C1660FE840EACC02AAC07;
-               isa = PBXTextBookmark;
-               name = "English: 4";
-               rLen = 0;
-               rLoc = 110;
-               rType = 0;
-               vrLen = 207;
-               vrLoc = 0;
-       };
-       6E9D6CED059429D400D9A2D7 = {
-               fRef = 089C1660FE840EACC02AAC07;
-               isa = PBXTextBookmark;
-               name = "English: 5";
-               rLen = 0;
-               rLoc = 145;
-               rType = 0;
-               vrLen = 199;
-               vrLoc = 0;
-       };
-       6EAD5EEA054C3932005761EE = {
-               isa = PBXSourceControlManager;
-               scmConfiguration = {
-               };
-               scmType = scm.cvs;
-       };
-       6EAD5EEB054C3932005761EE = {
-               indexTemplatePath = "";
-               isa = PBXCodeSenseManager;
-               usesDefaults = 1;
-               wantsCodeCompletion = 1;
-               wantsCodeCompletionAutoPopup = 0;
-               wantsCodeCompletionAutoSuggestions = 0;
-               wantsCodeCompletionCaseSensitivity = 1;
-               wantsCodeCompletionOnlyMatchingItems = 1;
-               wantsCodeCompletionParametersIncluded = 1;
-               wantsCodeCompletionPlaceholdersInserted = 1;
-               wantsCodeCompletionTabCompletes = 1;
-               wantsIndex = 1;
-       };
-       6EBCEEE60523E23700A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 587}}";
-                       sepNavSelRange = "{0, 0}";
-                       sepNavVisRect = "{{0, 0}, {1002, 587}}";
-               };
-       };
-       6ED3E46305192E2B00A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1034, 710}}";
-                       sepNavSelRange = "{0, 0}";
-                       sepNavVisRect = "{{0, 0}, {1034, 710}}";
-               };
-       };
-       6ED3E46405192E2B00A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1034, 1424}}";
-                       sepNavSelRange = "{0, 0}";
-                       sepNavVisRect = "{{0, 0}, {1034, 710}}";
-               };
-       };
-       6EE811830602584A00F1CD3F = {
-               fRef = 6E0D40B5052243D500A80003;
-               isa = PBXTextBookmark;
-               name = "PreferenceController.m: 76";
-               rLen = 0;
-               rLoc = 1682;
-               rType = 0;
-               vrLen = 1634;
-               vrLoc = 1501;
-       };
-       6EE811C40602592500F1CD3F = {
-               fRef = 6E71F41C051BCCC600A80003;
-               isa = PBXTextBookmark;
-               name = TCGlobalSessionCount;
-               rLen = 20;
-               rLoc = 405;
-               rType = 0;
-               vrLen = 1137;
-               vrLoc = 0;
-       };
-       6EE811D50602595D00F1CD3F = {
-               fRef = 2A37F4ACFDCFA73011CA2CEA;
-               isa = PBXTextBookmark;
-               name = "SessionController.m: 53";
-               rLen = 0;
-               rLoc = 1477;
-               rType = 0;
-               vrLen = 882;
-               vrLoc = 1117;
-       };
-       6EE811EE060259D600F1CD3F = {
-               fRef = 6E146B12051FA42C00A80003;
-               isa = PBXTextBookmark;
-               name = "CheatClient.m: clientWithDelegate:server:name:";
-               rLen = 0;
-               rLoc = 424;
-               rType = 0;
-               vrLen = 1237;
-               vrLoc = 0;
-       };
-       6EE811FD06025A4300F1CD3F = {
-               fRef = 6EE8120606025A6E00F1CD3F;
-               isa = PBXTextBookmark;
-               name = "(null): 1";
-               rLen = 0;
-               rLoc = 0;
-               rType = 0;
-               vrLen = 658;
-               vrLoc = 0;
-       };
-       6EE811FF06025A4300F1CD3F = {
-               fRef = 6EE8120806025A6E00F1CD3F;
-               isa = PBXTextBookmark;
-               name = "(null): 1";
-               rLen = 0;
-               rLoc = 0;
-               rType = 0;
-               vrLen = 658;
-               vrLoc = 0;
-       };
-       6EE8120606025A6E00F1CD3F = {
-               isa = PBXFileReference;
-               lastKnownFileType = sourcecode.c.objc;
-               name = AboutBoxController.m;
-               path = "/Users/chaz/Projects/The Cheat/AboutBoxController.m";
-               refType = 0;
-               sourceTree = "<absolute>";
-       };
-       6EE8120806025A6E00F1CD3F = {
-               isa = PBXFileReference;
-               lastKnownFileType = sourcecode.c.objc;
-               name = AboutBoxController.m;
-               path = "/Users/chaz/Projects/The Cheat/AboutBoxController.m";
-               refType = 0;
-               sourceTree = "<absolute>";
-       };
-       6EE8120F06025ABA00F1CD3F = {
-               fRef = 6EE8121206025AD800F1CD3F;
-               isa = PBXTextBookmark;
-               name = "\n/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\n#pragma mark Accessors\n/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/";
-               rLen = 269;
-               rLoc = 13432;
-               rType = 0;
-               vrLen = 1093;
-               vrLoc = 12661;
-       };
-       6EE8121006025ABA00F1CD3F = {
-               fRef = 6EE8121406025AD800F1CD3F;
-               isa = PBXTextBookmark;
-               name = "\n/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\n#pragma mark Accessors\n/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/";
-               rLen = 269;
-               rLoc = 13432;
-               rType = 0;
-               vrLen = 1093;
-               vrLoc = 12661;
-       };
-       6EE8121206025AD800F1CD3F = {
-               isa = PBXFileReference;
-               lastKnownFileType = sourcecode.c.objc;
-               name = AppController.m;
-               path = "/Users/chaz/Projects/The Cheat/AppController.m";
-               refType = 0;
-               sourceTree = "<absolute>";
-       };
-       6EE8121406025AD800F1CD3F = {
-               isa = PBXFileReference;
-               lastKnownFileType = sourcecode.c.objc;
-               name = AppController.m;
-               path = "/Users/chaz/Projects/The Cheat/AppController.m";
-               refType = 0;
-               sourceTree = "<absolute>";
-       };
-       6EE8122306025C6300F1CD3F = {
-               fRef = 6EE8122606025C8100F1CD3F;
-               isa = PBXTextBookmark;
-               name = "- (void)windowWillClose:(NSNotification *)aNotification\n{\n\t// closing the window will automatically disconnect the client from the server,\n\t// but if the application is quitting, the client may not get a chance to exit.\n\t// this _should_ be OK.\n\t[self disconnect];\n\t\n\t// clean up status timer stuff.\n\t// we do this here because we don't want the timer to fire after the window is gone\n\t// since we need to use the window in that method.\n\t[savedStatusColor release], savedStatusColor = nil;\n\t[savedStatusText release], savedStatusText = nil;\n\t[statusTextTimer invalidate];\n\t[statusTextTimer release], statusTextTimer = nil;\n\t\n\t[self release];\n\t\n\t//[super close];\n}";
-               rLen = 663;
-               rLoc = 2013;
-               rType = 0;
-               vrLen = 1125;
-               vrLoc = 1716;
-       };
-       6EE8122406025C6300F1CD3F = {
-               fRef = 6EE8122706025C8100F1CD3F;
-               isa = PBXTextBookmark;
-               name = "- (void)windowWillClose:(NSNotification *)aNotification\n{\n\t// closing the window will automatically disconnect the client from the server,\n\t// but if the application is quitting, the client may not get a chance to exit.\n\t// this _should_ be OK.\n\t[self disconnect];\n\t\n\t// clean up status timer stuff.\n\t// we do this here because we don't want the timer to fire after the window is gone\n\t// since we need to use the window in that method.\n\t[savedStatusColor release], savedStatusColor = nil;\n\t[savedStatusText release], savedStatusText = nil;\n\t[statusTextTimer invalidate];\n\t[statusTextTimer release], statusTextTimer = nil;\n\t\n\t[self release];\n\t\n\t//[super close];\n}";
-               rLen = 663;
-               rLoc = 2013;
-               rType = 0;
-               vrLen = 1125;
-               vrLoc = 1716;
-       };
-       6EE8122606025C8100F1CD3F = {
-               isa = PBXFileReference;
-               lastKnownFileType = sourcecode.c.objc;
-               name = ClientController.m;
-               path = "/Users/chaz/Projects/The Cheat/ClientController.m";
-               refType = 0;
-               sourceTree = "<absolute>";
-       };
-       6EE8122706025C8100F1CD3F = {
-               isa = PBXFileReference;
-               lastKnownFileType = sourcecode.c.objc;
-               name = ClientController.m;
-               path = "/Users/chaz/Projects/The Cheat/ClientController.m";
-               refType = 0;
-               sourceTree = "<absolute>";
-       };
-       6EE81236060274E900F1CD3F = {
-               fRef = 6EE81239060274E900F1CD3F;
-               isa = PBXBookmark;
-       };
-       6EE81239060274E900F1CD3F = {
-               isa = PBXFileReference;
-               lastKnownFileType = folder;
-               refType = 4;
-               sourceTree = "<group>";
-       };
-       6EE815E40602A97C00F1CD3F = {
-               fRef = 6E4E098C050BB21400A80003;
-               isa = PBXTextBookmark;
-               name = "AppController.h: newSessionWindow:";
-               rLen = 0;
-               rLoc = 1308;
-               rType = 0;
-               vrLen = 920;
-               vrLoc = 722;
-       };
-       6EF0870C0575382B00B81D60 = {
-               fileReference = 6E4E098E050BB21400A80003;
-               isa = PBXFileBreakpoint;
-               lineNumber = 355;
-               state = 1;
-       };
-       6EF4D0B9060C2CF300F4728B = {
-               fRef = 6EF8EC08055A1730008BBE46;
-               isa = PBXTextBookmark;
-               name = "Info-The_Cheat.plist: 16";
-               rLen = 0;
-               rLoc = 467;
-               rType = 0;
-               vrLen = 1278;
-               vrLoc = 0;
-       };
-       6EF4D0BA060C2CF300F4728B = {
-               fRef = 2A37F4AEFDCFA73011CA2CEA;
-               isa = PBXTextBookmark;
-               name = "SessionController.h: 116";
-               rLen = 0;
-               rLoc = 3017;
-               rType = 0;
-               vrLen = 1333;
-               vrLoc = 916;
-       };
-       6EF4D0BB060C2CF300F4728B = {
-               fRef = 2A37F4ACFDCFA73011CA2CEA;
-               isa = PBXTextBookmark;
-               name = "if ( [recurringChangeButton state] == NSOnState )\n\t{\n\t\t[changeSecondsCombo setEnabled:YES];\n\t}\n\telse\n\t{\n\t\t[changeSecondsCombo setEnabled:NO];\n\t}";
-               rLen = 144;
-               rLoc = 36184;
-               rType = 0;
-               vrLen = 898;
-               vrLoc = 35395;
-       };
-       6EF4D0BC060C2CF300F4728B = {
-               fRef = 6EF8EC08055A1730008BBE46;
-               isa = PBXTextBookmark;
-               name = "Info-The_Cheat.plist: 16";
-               rLen = 0;
-               rLoc = 467;
-               rType = 0;
-               vrLen = 1278;
-               vrLoc = 0;
-       };
-       6EF4D0BD060C2CF300F4728B = {
-               fRef = 2A37F4ACFDCFA73011CA2CEA;
-               isa = PBXTextBookmark;
-               name = "if ( [recurringChangeButton state] == NSOnState )\n\t{\n\t\t[changeSecondsCombo setEnabled:YES];\n\t}\n\telse\n\t{\n\t\t[changeSecondsCombo setEnabled:NO];\n\t}";
-               rLen = 144;
-               rLoc = 36184;
-               rType = 0;
-               vrLen = 898;
-               vrLoc = 35395;
-       };
-       6EF4D0BE060C2CF300F4728B = {
-               fRef = 2A37F4AEFDCFA73011CA2CEA;
-               isa = PBXTextBookmark;
-               name = "SessionController.h: 116";
-               rLen = 0;
-               rLoc = 3017;
-               rType = 0;
-               vrLen = 1333;
-               vrLoc = 916;
-       };
-       6EF4D0BF060C2CF300F4728B = {
-               fRef = 2A37F4ACFDCFA73011CA2CEA;
-               isa = PBXTextBookmark;
-               name = "SessionController.m: 905";
-               rLen = 0;
-               rLoc = 23043;
-               rType = 0;
-               vrLen = 1044;
-               vrLoc = 22364;
-       };
-       6EF8EBD9055A1730008BBE46 = {
-               activeExec = 0;
-               executables = (
-                       6EF8EC0A055A1730008BBE46,
-               );
-       };
-       6EF8EC08055A1730008BBE46 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1002, 799}}";
-                       sepNavSelRange = "{1162, 0}";
-                       sepNavVisRect = "{{0, 0}, {1002, 714}}";
-               };
-       };
-       6EF8EC0A055A1730008BBE46 = {
-               activeArgIndex = 2147483647;
-               activeArgIndices = (
-               );
-               argumentStrings = (
-               );
-               configStateDict = {
-               };
-               debuggerPlugin = GDBDebugging;
-               dylibVariantSuffix = "";
-               enableDebugStr = 1;
-               environmentEntries = (
-               );
-               isa = PBXExecutable;
-               name = "The Cheat";
-               shlibInfoDictList = (
-               );
-               sourceDirectories = (
-               );
-       };
-       6EFB422D052F601400A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1034, 710}}";
-                       sepNavSelRange = "{726, 0}";
-                       sepNavVisRect = "{{0, 0}, {1034, 710}}";
-               };
-       };
-       6EFB422E052F601400A80003 = {
-               uiCtxt = {
-                       sepNavIntBoundsRect = "{{0, 0}, {1034, 1088}}";
-                       sepNavSelRange = "{896, 0}";
-                       sepNavVisRect = "{{0, 330}, {1034, 710}}";
-               };
-       };
-}
diff --git a/The Cheat.pbproj/project.pbxproj b/The Cheat.pbproj/project.pbxproj
deleted file mode 100644 (file)
index c02181c..0000000
+++ /dev/null
@@ -1,1208 +0,0 @@
-// !$*UTF8*$!
-{
-       archiveVersion = 1;
-       classes = {
-       };
-       objectVersion = 39;
-       objects = {
-               089C165FFE840EACC02AAC07 = {
-                       children = (
-                               089C1660FE840EACC02AAC07,
-                       );
-                       isa = PBXVariantGroup;
-                       name = InfoPlist.strings;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               089C1660FE840EACC02AAC07 = {
-                       fileEncoding = 10;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.plist.strings;
-                       name = English;
-                       path = English.lproj/InfoPlist.strings;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-//080
-//081
-//082
-//083
-//084
-//100
-//101
-//102
-//103
-//104
-               1058C7A6FEA54F5311CA2CBB = {
-                       children = (
-                               6E90BC2805F7FB9000857F22,
-                               1058C7A7FEA54F5311CA2CBB,
-                       );
-                       isa = PBXGroup;
-                       name = "Linked Frameworks";
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               1058C7A7FEA54F5311CA2CBB = {
-                       fallbackIsa = PBXFileReference;
-                       isa = PBXFrameworkReference;
-                       lastKnownFileType = wrapper.framework;
-                       name = Cocoa.framework;
-                       path = /System/Library/Frameworks/Cocoa.framework;
-                       refType = 0;
-                       sourceTree = "<absolute>";
-               };
-               1058C7A8FEA54F5311CA2CBB = {
-                       children = (
-                               2A37F4C5FDCFA73011CA2CEA,
-                               2A37F4C4FDCFA73011CA2CEA,
-                       );
-                       isa = PBXGroup;
-                       name = "Other Frameworks";
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-//100
-//101
-//102
-//103
-//104
-//190
-//191
-//192
-//193
-//194
-               19C28FB0FE9D524F11CA2CBB = {
-                       children = (
-                               6EF8EC09055A1730008BBE46,
-                       );
-                       isa = PBXGroup;
-                       name = Products;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-//190
-//191
-//192
-//193
-//194
-//2A0
-//2A1
-//2A2
-//2A3
-//2A4
-               2A37F4A9FDCFA73011CA2CEA = {
-                       buildSettings = {
-                               MACOSX_DEPLOYMENT_TARGET = 10.2;
-                               SDKROOT = /Developer/SDKs/MacOSX10.2.7.sdk;
-                       };
-                       buildStyles = (
-                               4A9504D0FFE6A4CB11CA0CBA,
-                               4A9504D1FFE6A4CB11CA0CBA,
-                       );
-                       hasScannedForEncodings = 1;
-                       isa = PBXProject;
-                       mainGroup = 2A37F4AAFDCFA73011CA2CEA;
-                       projectDirPath = "";
-                       targets = (
-                               6EF8EBD9055A1730008BBE46,
-                       );
-               };
-               2A37F4AAFDCFA73011CA2CEA = {
-                       children = (
-                               6E0D40B3052243B800A80003,
-                               2A37F4ABFDCFA73011CA2CEA,
-                               6EAF23070527D7DB00A80003,
-                               6E0D40BF05224F4B00A80003,
-                               6ED3E46705192F0C00A80003,
-                               2A37F4AFFDCFA73011CA2CEA,
-                               2A37F4B8FDCFA73011CA2CEA,
-                               6E8EE12505F7EA8100ED3F4F,
-                               19C28FB0FE9D524F11CA2CBB,
-                       );
-                       isa = PBXGroup;
-                       name = "The Cheat";
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               2A37F4ABFDCFA73011CA2CEA = {
-                       children = (
-                               6E0D40B80522449500A80003,
-                               6E0D40B90522449500A80003,
-                               6E4E098F050BB21400A80003,
-                               6E4E098E050BB21400A80003,
-                               6E146B11051FA42C00A80003,
-                               6E146B12051FA42C00A80003,
-                       );
-                       isa = PBXGroup;
-                       name = "Network Classes";
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               2A37F4ACFDCFA73011CA2CEA = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = SessionController.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               2A37F4AEFDCFA73011CA2CEA = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = SessionController.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               2A37F4AFFDCFA73011CA2CEA = {
-                       children = (
-                               2A37F4B0FDCFA73011CA2CEA,
-                               6E51A986057330B900506538,
-                               6E51A987057330B900506538,
-                               6E3F0D01050D4ACC00A80003,
-                               6E3F0D02050D4ACC00A80003,
-                               6E71F41B051BCCC600A80003,
-                               6E71F41C051BCCC600A80003,
-                               6E0BDF7D0511568D00A80003,
-                               32DBCF750370BD2300C91783,
-                       );
-                       isa = PBXGroup;
-                       name = "Other Sources";
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               2A37F4B0FDCFA73011CA2CEA = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = main.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               2A37F4B4FDCFA73011CA2CEA = {
-                       children = (
-                               2A37F4B5FDCFA73011CA2CEA,
-                       );
-                       isa = PBXVariantGroup;
-                       name = Session.nib;
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               2A37F4B5FDCFA73011CA2CEA = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = wrapper.nib;
-                       name = English;
-                       path = English.lproj/Session.nib;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               2A37F4B6FDCFA73011CA2CEA = {
-                       children = (
-                               2A37F4B7FDCFA73011CA2CEA,
-                       );
-                       isa = PBXVariantGroup;
-                       name = MainMenu.nib;
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               2A37F4B7FDCFA73011CA2CEA = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = wrapper.nib;
-                       name = English;
-                       path = English.lproj/MainMenu.nib;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               2A37F4B8FDCFA73011CA2CEA = {
-                       children = (
-                               6E8DD52805FC4EB600D2C0EA,
-                               6E1E43700588275100526509,
-                               6E789E4A0603A52B008F8B51,
-                               2A37F4B6FDCFA73011CA2CEA,
-                               2A37F4B4FDCFA73011CA2CEA,
-                               6EE8122A0602610900F1CD3F,
-                               6E51A97605732B9000506538,
-                               6E0D40BC052245E700A80003,
-                               6E0D40B005223D4E00A80003,
-                               089C165FFE840EACC02AAC07,
-                               6EF8EC08055A1730008BBE46,
-                       );
-                       isa = PBXGroup;
-                       name = Resources;
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               2A37F4C4FDCFA73011CA2CEA = {
-                       fallbackIsa = PBXFileReference;
-                       isa = PBXFrameworkReference;
-                       lastKnownFileType = wrapper.framework;
-                       name = AppKit.framework;
-                       path = /System/Library/Frameworks/AppKit.framework;
-                       refType = 0;
-                       sourceTree = "<absolute>";
-               };
-               2A37F4C5FDCFA73011CA2CEA = {
-                       fallbackIsa = PBXFileReference;
-                       isa = PBXFrameworkReference;
-                       lastKnownFileType = wrapper.framework;
-                       name = Foundation.framework;
-                       path = /System/Library/Frameworks/Foundation.framework;
-                       refType = 0;
-                       sourceTree = "<absolute>";
-               };
-//2A0
-//2A1
-//2A2
-//2A3
-//2A4
-//320
-//321
-//322
-//323
-//324
-               32DBCF750370BD2300C91783 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = The_Cheat_Prefix.pch;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-//320
-//321
-//322
-//323
-//324
-//4A0
-//4A1
-//4A2
-//4A3
-//4A4
-               4A9504D0FFE6A4CB11CA0CBA = {
-                       buildRules = (
-                       );
-                       buildSettings = {
-                               COPY_PHASE_STRIP = NO;
-                               GCC_DYNAMIC_NO_PIC = NO;
-                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
-                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
-                               GCC_OPTIMIZATION_LEVEL = 0;
-                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
-                               OPTIMIZATION_CFLAGS = "-O0";
-                               ZERO_LINK = YES;
-                       };
-                       isa = PBXBuildStyle;
-                       name = Development;
-               };
-               4A9504D1FFE6A4CB11CA0CBA = {
-                       buildRules = (
-                       );
-                       buildSettings = {
-                               COPY_PHASE_STRIP = YES;
-                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
-                               ZERO_LINK = NO;
-                       };
-                       isa = PBXBuildStyle;
-                       name = Deployment;
-               };
-//4A0
-//4A1
-//4A2
-//4A3
-//4A4
-//6E0
-//6E1
-//6E2
-//6E3
-//6E4
-               6E0BDF7D0511568D00A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = cheat_types.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E0D40AC05223CCE00A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = NetTrafficController.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E0D40AD05223CCE00A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = NetTrafficController.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E0D40B005223D4E00A80003 = {
-                       children = (
-                               6E0D40B105223D4E00A80003,
-                       );
-                       isa = PBXVariantGroup;
-                       name = NetTraffic.nib;
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E0D40B105223D4E00A80003 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = wrapper.nib;
-                       name = English;
-                       path = English.lproj/NetTraffic.nib;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E0D40B3052243B800A80003 = {
-                       children = (
-                               6E4E098C050BB21400A80003,
-                               6E4E098D050BB21400A80003,
-                               6E51A97C0573304C00506538,
-                               6E51A97D0573304C00506538,
-                               6E0D40B4052243D500A80003,
-                               6E0D40B5052243D500A80003,
-                               6E0D40AC05223CCE00A80003,
-                               6E0D40AD05223CCE00A80003,
-                               2A37F4AEFDCFA73011CA2CEA,
-                               2A37F4ACFDCFA73011CA2CEA,
-                       );
-                       isa = PBXGroup;
-                       name = Controllers;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E0D40B4052243D500A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = PreferenceController.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E0D40B5052243D500A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = PreferenceController.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E0D40B80522449500A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = CheatListener.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E0D40B90522449500A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = CheatListener.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E0D40BC052245E700A80003 = {
-                       children = (
-                               6E0D40BD052245E700A80003,
-                       );
-                       isa = PBXVariantGroup;
-                       name = Preferences.nib;
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E0D40BD052245E700A80003 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = wrapper.nib;
-                       name = English;
-                       path = English.lproj/Preferences.nib;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E0D40BF05224F4B00A80003 = {
-                       children = (
-                               6E0D40C405225DA100A80003,
-                               6E0D40C005224FD000A80003,
-                               6E0D40CA0522815100A80003,
-                               6EBCEEE60523E23700A80003,
-                               6E0D40CE0522820D00A80003,
-                       );
-                       isa = PBXGroup;
-                       name = Protocols;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E0D40C005224FD000A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = NetTrafficControlling.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E0D40C405225DA100A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = PreferenceControlling.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E0D40CA0522815100A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = ListenerDelegate.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E0D40CE0522820D00A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = ClientDelegate.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E146B11051FA42C00A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = CheatClient.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E146B12051FA42C00A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = CheatClient.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E1E43700588275100526509 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = image.icns;
-                       path = icon.icns;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E1E43710588275100526509 = {
-                       fileRef = 6E1E43700588275100526509;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6E3F0D01050D4ACC00A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = cheat_net.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E3F0D02050D4ACC00A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = cheat_net.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E4E098C050BB21400A80003 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = AppController.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E4E098D050BB21400A80003 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = AppController.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E4E098E050BB21400A80003 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = CheatServer.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E4E098F050BB21400A80003 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = CheatServer.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E51A97605732B9000506538 = {
-                       children = (
-                               6E51A97705732B9000506538,
-                       );
-                       isa = PBXVariantGroup;
-                       name = AboutBox.nib;
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E51A97705732B9000506538 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = wrapper.nib;
-                       name = English;
-                       path = English.lproj/AboutBox.nib;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E51A97905732B9000506538 = {
-                       fileRef = 6E51A97605732B9000506538;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6E51A97C0573304C00506538 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = AboutBoxController.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E51A97D0573304C00506538 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = AboutBoxController.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E51A9800573304C00506538 = {
-                       fileRef = 6E51A97C0573304C00506538;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6E51A9810573304C00506538 = {
-                       fileRef = 6E51A97D0573304C00506538;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6E51A986057330B900506538 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = cheat_shared.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E51A987057330B900506538 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = cheat_shared.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E51A98A057330B900506538 = {
-                       fileRef = 6E51A986057330B900506538;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6E51A98B057330B900506538 = {
-                       fileRef = 6E51A987057330B900506538;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6E71F41B051BCCC600A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = cheat_globals.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E71F41C051BCCC600A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = cheat_globals.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E789E4A0603A52B008F8B51 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = image.icns;
-                       path = icondoc.icns;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E789E4B0603A52B008F8B51 = {
-                       fileRef = 6E789E4A0603A52B008F8B51;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6E8DD52305FC4EA100D2C0EA = {
-                       buildActionMask = 2147483647;
-                       dstPath = "";
-                       dstSubfolderSpec = 7;
-                       files = (
-                               6E8DD52D05FC4EC100D2C0EA,
-                       );
-                       isa = PBXCopyFilesBuildPhase;
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               6E8DD52805FC4EB600D2C0EA = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.rtf;
-                       path = "Read Me.rtf";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E8DD52905FC4EB600D2C0EA = {
-                       fileRef = 6E8DD52805FC4EB600D2C0EA;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6E8DD52D05FC4EC100D2C0EA = {
-                       fileRef = 6E8DD52805FC4EB600D2C0EA;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6E8EE12505F7EA8100ED3F4F = {
-                       children = (
-                               1058C7A6FEA54F5311CA2CBB,
-                               1058C7A8FEA54F5311CA2CBB,
-                       );
-                       isa = PBXGroup;
-                       name = "Frameworks & Libraries";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6E90BC2805F7FB9000857F22 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = wrapper.framework;
-                       name = Chaz.framework;
-                       path = /Users/chaz/Projects/Chaz/build/Chaz.framework;
-                       refType = 0;
-                       sourceTree = "<absolute>";
-               };
-               6E90BC2905F7FB9000857F22 = {
-                       fileRef = 6E90BC2805F7FB9000857F22;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6E90BC3305F7FB9F00857F22 = {
-                       buildActionMask = 2147483647;
-                       dstPath = "";
-                       dstSubfolderSpec = 10;
-                       files = (
-                               6E90BC3A05F7FBFC00857F22,
-                       );
-                       isa = PBXCopyFilesBuildPhase;
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               6E90BC3A05F7FBFC00857F22 = {
-                       fileRef = 6E90BC2805F7FB9000857F22;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EAF23070527D7DB00A80003 = {
-                       children = (
-                               6EAF23080527D7FE00A80003,
-                               6EAF23090527D7FE00A80003,
-                               6EFB422D052F601400A80003,
-                               6EFB422E052F601400A80003,
-                       );
-                       isa = PBXGroup;
-                       name = "Miscellaneous Classes";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6EAF23080527D7FE00A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = ServerHolder.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6EAF23090527D7FE00A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = ServerHolder.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6EBCEEE60523E23700A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = ServerDelegate.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6ED3E46305192E2B00A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = MenuExtras.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6ED3E46405192E2B00A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = MenuExtras.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6ED3E46705192F0C00A80003 = {
-                       children = (
-                               6ED3E46305192E2B00A80003,
-                               6ED3E46405192E2B00A80003,
-                       );
-                       isa = PBXGroup;
-                       name = Categories;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6EE8122A0602610900F1CD3F = {
-                       children = (
-                               6EE8122B0602610900F1CD3F,
-                       );
-                       isa = PBXVariantGroup;
-                       name = Record.nib;
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6EE8122B0602610900F1CD3F = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = wrapper.nib;
-                       name = English;
-                       path = English.lproj/Record.nib;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6EE8122C0602610900F1CD3F = {
-                       fileRef = 6EE8122A0602610900F1CD3F;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBD9055A1730008BBE46 = {
-                       buildPhases = (
-                               6EF8EBDA055A1730008BBE46,
-                               6EF8EBEE055A1730008BBE46,
-                               6EF8EBF7055A1730008BBE46,
-                               6EF8EC05055A1730008BBE46,
-                               6E90BC3305F7FB9F00857F22,
-                               6E8DD52305FC4EA100D2C0EA,
-                       );
-                       buildRules = (
-                       );
-                       buildSettings = {
-                               DEPLOYMENT_LOCATION = NO;
-                               FRAMEWORK_SEARCH_PATHS = /Users/chaz/Projects/Chaz/build;
-                               GCC_C_LANGUAGE_STANDARD = "compiler-default";
-                               GCC_ENABLE_ASM_KEYWORD = YES;
-                               GCC_ENABLE_CPP_EXCEPTIONS = NO;
-                               GCC_OPTIMIZATION_LEVEL = 3;
-                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
-                               GCC_PREFIX_HEADER = The_Cheat_Prefix.pch;
-                               GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
-                               GCC_WARN_UNKNOWN_PRAGMAS = NO;
-                               HEADER_SEARCH_PATHS = "";
-                               INFOPLIST_FILE = "Info-The_Cheat.plist";
-                               INSTALL_PATH = "$(HOME)/Applications";
-                               LIBRARY_SEARCH_PATHS = "\"/Users/chaz/Projects/The Cheat\"";
-                               MACOSX_DEPLOYMENT_TARGET = 10.2;
-                               OTHER_CFLAGS = "";
-                               OTHER_LDFLAGS = "";
-                               PRODUCT_NAME = "The Cheat";
-                               SECTORDER_FLAGS = "";
-                               WARNING_CFLAGS = "-Wmost";
-                               WRAPPER_EXTENSION = app;
-                               ZERO_LINK = NO;
-                       };
-                       dependencies = (
-                       );
-                       isa = PBXNativeTarget;
-                       name = "The Cheat";
-                       productInstallPath = "$(HOME)/Applications";
-                       productName = "The Cheat";
-                       productReference = 6EF8EC09055A1730008BBE46;
-                       productType = "com.apple.product-type.application";
-               };
-               6EF8EBDA055A1730008BBE46 = {
-                       buildActionMask = 2147483647;
-                       files = (
-                               6EF8EBDB055A1730008BBE46,
-                               6EF8EBDC055A1730008BBE46,
-                               6EF8EBDD055A1730008BBE46,
-                               6EF8EBDE055A1730008BBE46,
-                               6EF8EBDF055A1730008BBE46,
-                               6EF8EBE0055A1730008BBE46,
-                               6EF8EBE1055A1730008BBE46,
-                               6EF8EBE2055A1730008BBE46,
-                               6EF8EBE3055A1730008BBE46,
-                               6EF8EBE4055A1730008BBE46,
-                               6EF8EBE5055A1730008BBE46,
-                               6EF8EBE6055A1730008BBE46,
-                               6EF8EBE7055A1730008BBE46,
-                               6EF8EBE8055A1730008BBE46,
-                               6EF8EBE9055A1730008BBE46,
-                               6EF8EBEA055A1730008BBE46,
-                               6EF8EBEB055A1730008BBE46,
-                               6EF8EBEC055A1730008BBE46,
-                               6EF8EBED055A1730008BBE46,
-                               6E51A9800573304C00506538,
-                               6E51A98A057330B900506538,
-                       );
-                       isa = PBXHeadersBuildPhase;
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               6EF8EBDB055A1730008BBE46 = {
-                       fileRef = 32DBCF750370BD2300C91783;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBDC055A1730008BBE46 = {
-                       fileRef = 2A37F4AEFDCFA73011CA2CEA;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBDD055A1730008BBE46 = {
-                       fileRef = 6E4E098C050BB21400A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBDE055A1730008BBE46 = {
-                       fileRef = 6E4E098F050BB21400A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBDF055A1730008BBE46 = {
-                       fileRef = 6E3F0D01050D4ACC00A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBE0055A1730008BBE46 = {
-                       fileRef = 6E0BDF7D0511568D00A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBE1055A1730008BBE46 = {
-                       fileRef = 6ED3E46305192E2B00A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBE2055A1730008BBE46 = {
-                       fileRef = 6E71F41B051BCCC600A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBE3055A1730008BBE46 = {
-                       fileRef = 6E146B11051FA42C00A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBE4055A1730008BBE46 = {
-                       fileRef = 6E0D40AC05223CCE00A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBE5055A1730008BBE46 = {
-                       fileRef = 6E0D40B4052243D500A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBE6055A1730008BBE46 = {
-                       fileRef = 6E0D40B80522449500A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBE7055A1730008BBE46 = {
-                       fileRef = 6E0D40C005224FD000A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBE8055A1730008BBE46 = {
-                       fileRef = 6E0D40C405225DA100A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBE9055A1730008BBE46 = {
-                       fileRef = 6E0D40CA0522815100A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBEA055A1730008BBE46 = {
-                       fileRef = 6E0D40CE0522820D00A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBEB055A1730008BBE46 = {
-                       fileRef = 6EBCEEE60523E23700A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBEC055A1730008BBE46 = {
-                       fileRef = 6EAF23080527D7FE00A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBED055A1730008BBE46 = {
-                       fileRef = 6EFB422D052F601400A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBEE055A1730008BBE46 = {
-                       buildActionMask = 2147483647;
-                       files = (
-                               6EF8EBF0055A1730008BBE46,
-                               6EF8EBF1055A1730008BBE46,
-                               6EF8EBF2055A1730008BBE46,
-                               6EF8EBF3055A1730008BBE46,
-                               6EF8EBF4055A1730008BBE46,
-                               6E51A97905732B9000506538,
-                               6E1E43710588275100526509,
-                               6E8DD52905FC4EB600D2C0EA,
-                               6EE8122C0602610900F1CD3F,
-                               6E789E4B0603A52B008F8B51,
-                       );
-                       isa = PBXResourcesBuildPhase;
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               6EF8EBF0055A1730008BBE46 = {
-                       fileRef = 2A37F4B6FDCFA73011CA2CEA;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBF1055A1730008BBE46 = {
-                       fileRef = 2A37F4B4FDCFA73011CA2CEA;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBF2055A1730008BBE46 = {
-                       fileRef = 089C165FFE840EACC02AAC07;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBF3055A1730008BBE46 = {
-                       fileRef = 6E0D40B005223D4E00A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBF4055A1730008BBE46 = {
-                       fileRef = 6E0D40BC052245E700A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBF7055A1730008BBE46 = {
-                       buildActionMask = 2147483647;
-                       files = (
-                               6EF8EBF8055A1730008BBE46,
-                               6EF8EBF9055A1730008BBE46,
-                               6EF8EBFA055A1730008BBE46,
-                               6EF8EBFB055A1730008BBE46,
-                               6EF8EBFC055A1730008BBE46,
-                               6EF8EBFD055A1730008BBE46,
-                               6EF8EBFE055A1730008BBE46,
-                               6EF8EBFF055A1730008BBE46,
-                               6EF8EC00055A1730008BBE46,
-                               6EF8EC01055A1730008BBE46,
-                               6EF8EC02055A1730008BBE46,
-                               6EF8EC03055A1730008BBE46,
-                               6EF8EC04055A1730008BBE46,
-                               6E51A9810573304C00506538,
-                               6E51A98B057330B900506538,
-                       );
-                       isa = PBXSourcesBuildPhase;
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               6EF8EBF8055A1730008BBE46 = {
-                       fileRef = 2A37F4ACFDCFA73011CA2CEA;
-                       isa = PBXBuildFile;
-                       settings = {
-                               ATTRIBUTES = (
-                               );
-                       };
-               };
-               6EF8EBF9055A1730008BBE46 = {
-                       fileRef = 2A37F4B0FDCFA73011CA2CEA;
-                       isa = PBXBuildFile;
-                       settings = {
-                               ATTRIBUTES = (
-                               );
-                       };
-               };
-               6EF8EBFA055A1730008BBE46 = {
-                       fileRef = 6E4E098D050BB21400A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBFB055A1730008BBE46 = {
-                       fileRef = 6E4E098E050BB21400A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBFC055A1730008BBE46 = {
-                       fileRef = 6E3F0D02050D4ACC00A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBFD055A1730008BBE46 = {
-                       fileRef = 6ED3E46405192E2B00A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBFE055A1730008BBE46 = {
-                       fileRef = 6E71F41C051BCCC600A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EBFF055A1730008BBE46 = {
-                       fileRef = 6E146B12051FA42C00A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EC00055A1730008BBE46 = {
-                       fileRef = 6E0D40AD05223CCE00A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EC01055A1730008BBE46 = {
-                       fileRef = 6E0D40B5052243D500A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EC02055A1730008BBE46 = {
-                       fileRef = 6E0D40B90522449500A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EC03055A1730008BBE46 = {
-                       fileRef = 6EAF23090527D7FE00A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EC04055A1730008BBE46 = {
-                       fileRef = 6EFB422E052F601400A80003;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EC05055A1730008BBE46 = {
-                       buildActionMask = 2147483647;
-                       files = (
-                               6EF8EC06055A1730008BBE46,
-                               6E90BC2905F7FB9000857F22,
-                       );
-                       isa = PBXFrameworksBuildPhase;
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               6EF8EC06055A1730008BBE46 = {
-                       fileRef = 1058C7A7FEA54F5311CA2CBB;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               6EF8EC08055A1730008BBE46 = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.plist.xml;
-                       path = "Info-The_Cheat.plist";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6EF8EC09055A1730008BBE46 = {
-                       explicitFileType = wrapper.application;
-                       includeInIndex = 0;
-                       isa = PBXFileReference;
-                       path = "The Cheat.app";
-                       refType = 3;
-                       sourceTree = BUILT_PRODUCTS_DIR;
-               };
-               6EFB422D052F601400A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = SearchResults.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               6EFB422E052F601400A80003 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = SearchResults.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-       };
-       rootObject = 2A37F4A9FDCFA73011CA2CEA;
-}
diff --git a/The Cheat.xcode/chaz.mode1 b/The Cheat.xcode/chaz.mode1
new file mode 100644 (file)
index 0000000..16c00a3
--- /dev/null
@@ -0,0 +1,1532 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>ActivePerspectiveName</key>
+       <string>Project</string>
+       <key>AllowedModules</key>
+       <array>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXSmartGroupTreeModule</string>
+                       <key>Name</key>
+                       <string>Groups and Files Outline View</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXNavigatorGroup</string>
+                       <key>Name</key>
+                       <string>Editor</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>XCTaskListModule</string>
+                       <key>Name</key>
+                       <string>Task List</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>XCDetailModule</string>
+                       <key>Name</key>
+                       <string>File and Smart Group Detail Viewer</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>1</string>
+                       <key>Module</key>
+                       <string>PBXBuildResultsModule</string>
+                       <key>Name</key>
+                       <string>Detailed Build Results Viewer</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>1</string>
+                       <key>Module</key>
+                       <string>PBXProjectFindModule</string>
+                       <key>Name</key>
+                       <string>Project Batch Find Tool</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXRunSessionModule</string>
+                       <key>Name</key>
+                       <string>Run Log</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXBookmarksModule</string>
+                       <key>Name</key>
+                       <string>Bookmarks Tool</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXClassBrowserModule</string>
+                       <key>Name</key>
+                       <string>Class Browser</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXCVSModule</string>
+                       <key>Name</key>
+                       <string>Source Code Control Tool</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXDebugBreakpointsModule</string>
+                       <key>Name</key>
+                       <string>Debug Breakpoints Tool</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>XCDockableInspector</string>
+                       <key>Name</key>
+                       <string>Inspector</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXOpenQuicklyModule</string>
+                       <key>Name</key>
+                       <string>Open Quickly Tool</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>1</string>
+                       <key>Module</key>
+                       <string>PBXDebugSessionModule</string>
+                       <key>Name</key>
+                       <string>Debugger</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>1</string>
+                       <key>Module</key>
+                       <string>PBXDebugCLIModule</string>
+                       <key>Name</key>
+                       <string>Debug Console</string>
+               </dict>
+       </array>
+       <key>Description</key>
+       <string>This workspace mimics that found in Xcode 1.2, with various minor improvements such as including attached editors to the build results window and the project find window.</string>
+       <key>DockingSystemVisible</key>
+       <false/>
+       <key>Extension</key>
+       <string>mode1</string>
+       <key>FirstTimeWindowDisplayed</key>
+       <false/>
+       <key>Identifier</key>
+       <string>com.apple.perspectives.project.mode1</string>
+       <key>MajorVersion</key>
+       <integer>31</integer>
+       <key>MinorVersion</key>
+       <integer>0</integer>
+       <key>Name</key>
+       <string>Default Workspace</string>
+       <key>Notifications</key>
+       <array/>
+       <key>OpenEditors</key>
+       <array/>
+       <key>Perspectives</key>
+       <array>
+               <dict>
+                       <key>ChosenToolbarItems</key>
+                       <array>
+                               <string>active-target-popup</string>
+                               <string>active-buildstyle-popup</string>
+                               <string>action</string>
+                               <string>NSToolbarFlexibleSpaceItem</string>
+                               <string>buildOrClean</string>
+                               <string>build-and-runOrDebug</string>
+                               <string>build-and-debug</string>
+                               <string>clean-target</string>
+                               <string>com.apple.ide.PBXToolbarStopButton</string>
+                               <string>get-info</string>
+                               <string>toggle-editor</string>
+                               <string>NSToolbarFlexibleSpaceItem</string>
+                               <string>com.apple.pbx.toolbar.searchfield</string>
+                       </array>
+                       <key>ControllerClassBaseName</key>
+                       <string></string>
+                       <key>IconName</key>
+                       <string>WindowOfProject</string>
+                       <key>Identifier</key>
+                       <string>perspective.project</string>
+                       <key>IsVertical</key>
+                       <false/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>BecomeActive</key>
+                                       <true/>
+                                       <key>ContentConfiguration</key>
+                                       <dict>
+                                               <key>PBXBottomSmartGroupGIDs</key>
+                                               <array>
+                                                       <string>1C37FBAC04509CD000000102</string>
+                                                       <string>1C37FAAC04509CD000000102</string>
+                                                       <string>1C08E77C0454961000C914BD</string>
+                                                       <string>1C37FABC05509CD000000102</string>
+                                                       <string>1C37FABC05539CD112110102</string>
+                                                       <string>E2644B35053B69B200211256</string>
+                                                       <string>1C37FABC04509CD000100104</string>
+                                                       <string>1CC0EA4004350EF90044410B</string>
+                                                       <string>1CC0EA4004350EF90041110B</string>
+                                               </array>
+                                               <key>PBXProjectModuleGUID</key>
+                                               <string>1CE0B1FE06471DED0097A5F4</string>
+                                               <key>PBXProjectModuleLabel</key>
+                                               <string>Files</string>
+                                               <key>PBXProjectStructureProvided</key>
+                                               <string>yes</string>
+                                               <key>PBXSmartGroupTreeModuleColumnData</key>
+                                               <dict>
+                                                       <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+                                                       <array>
+                                                               <real>220</real>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+                                                       <array>
+                                                               <string>MainColumn</string>
+                                                       </array>
+                                               </dict>
+                                               <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+                                               <dict>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+                                                       <array>
+                                                               <string>29B97314FDCFA39411CA2CEA</string>
+                                                               <string>080E96DDFE201D6D7F000001</string>
+                                                               <string>6ED807190641EC6E002888F7</string>
+                                                               <string>6E98A54A06A73E37006A576D</string>
+                                                               <string>6E38D68006C9F98E003BA9B4</string>
+                                                               <string>6ED97B900645E2EE00CBF037</string>
+                                                               <string>6ED806580641D343002888F7</string>
+                                                               <string>29B97315FDCFA39411CA2CEA</string>
+                                                               <string>29B97317FDCFA39411CA2CEA</string>
+                                                               <string>1C37FBAC04509CD000000102</string>
+                                                               <string>6EB9056107CBC5C700D8982B</string>
+                                                               <string>6EB9056207CBC5C700D8982B</string>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+                                                       <array>
+                                                               <array>
+                                                                       <integer>85</integer>
+                                                                       <integer>76</integer>
+                                                                       <integer>0</integer>
+                                                               </array>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+                                                       <string>{{0, 1172}, {220, 775}}</string>
+                                               </dict>
+                                               <key>PBXTopSmartGroupGIDs</key>
+                                               <array/>
+                                       </dict>
+                                       <key>GeometryConfiguration</key>
+                                       <dict>
+                                               <key>Frame</key>
+                                               <string>{{0, 0}, {237, 793}}</string>
+                                               <key>GroupTreeTableConfiguration</key>
+                                               <array>
+                                                       <string>MainColumn</string>
+                                                       <real>220</real>
+                                               </array>
+                                               <key>RubberWindowFrame</key>
+                                               <string>0 103 1281 835 0 0 1280 938 </string>
+                                       </dict>
+                                       <key>Module</key>
+                                       <string>PBXSmartGroupTreeModule</string>
+                                       <key>Proportion</key>
+                                       <string>237pt</string>
+                               </dict>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CE0B20306471E060097A5F4</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>InfoPlist.strings</string>
+                                                               <key>PBXSplitModuleInNavigatorKey</key>
+                                                               <dict>
+                                                                       <key>Split0</key>
+                                                                       <dict>
+                                                                               <key>PBXProjectModuleGUID</key>
+                                                                               <string>1CE0B20406471E060097A5F4</string>
+                                                                               <key>PBXProjectModuleLabel</key>
+                                                                               <string>InfoPlist.strings</string>
+                                                                               <key>bookmark</key>
+                                                                               <string>6EB9059E07CBC7C400D8982B</string>
+                                                                               <key>history</key>
+                                                                               <array>
+                                                                                       <string>6E38D42606C9BC4D003BA9B4</string>
+                                                                                       <string>6EAB446A06CAF1B700A4ABF0</string>
+                                                                                       <string>6EDB006D06D5216D00DBD1D5</string>
+                                                                                       <string>6EDB009906D5286C00DBD1D5</string>
+                                                                                       <string>6EDB021306D5AAD400DBD1D5</string>
+                                                                                       <string>6EDB05C806D96DA400DBD1D5</string>
+                                                                                       <string>6EDB06E406DA8A7900DBD1D5</string>
+                                                                                       <string>6EDB070D06DA910700DBD1D5</string>
+                                                                                       <string>6EDB072F06DA92D800DBD1D5</string>
+                                                                                       <string>6EDB073506DA950800DBD1D5</string>
+                                                                                       <string>6EDB079A06DA9CBB00DBD1D5</string>
+                                                                                       <string>6EDB079C06DA9CBB00DBD1D5</string>
+                                                                                       <string>6EDB07AD06DA9D9A00DBD1D5</string>
+                                                                                       <string>6EDB07E106DAA3F700DBD1D5</string>
+                                                                                       <string>6EEE8F0C06DE3A6600788128</string>
+                                                                                       <string>6EEEB31D06E3FF3600788128</string>
+                                                                                       <string>6E6FD6CC0762C1BB004FD845</string>
+                                                                                       <string>6E6FD7750762D0B4004FD845</string>
+                                                                                       <string>6E6FD78C0762D118004FD845</string>
+                                                                                       <string>6E6FD7B30762D466004FD845</string>
+                                                                                       <string>6E6FD9BB0764E81F004FD845</string>
+                                                                                       <string>6E6FDA050764F415004FD845</string>
+                                                                                       <string>6E6FDB1A0764FFD9004FD845</string>
+                                                                                       <string>6E6FDDB50766A1F4004FD845</string>
+                                                                                       <string>6E12D3B80767AE3C00A95DFE</string>
+                                                                                       <string>6E12D56F076A7C9500A95DFE</string>
+                                                                                       <string>6E12D5D8076ABBB000A95DFE</string>
+                                                                                       <string>6E12D609076AC69000A95DFE</string>
+                                                                                       <string>6E12D651076ACBFA00A95DFE</string>
+                                                                                       <string>6E81817A076E3D6800A5FBEB</string>
+                                                                                       <string>6EF2F224077B955F00C8B55A</string>
+                                                                                       <string>6E3DC5E6077CE2CA004C82C0</string>
+                                                                                       <string>6EA396C9077F4C2F002B0E69</string>
+                                                                                       <string>6EA396CA077F4C2F002B0E69</string>
+                                                                                       <string>6EA398C1077FA115002B0E69</string>
+                                                                                       <string>6EA39A27077FCC6D002B0E69</string>
+                                                                                       <string>6EA39A28077FCC6D002B0E69</string>
+                                                                                       <string>6E9BF3290781F17A008F0139</string>
+                                                                                       <string>6E9BF5E607836C01008F0139</string>
+                                                                                       <string>6E9BF6FD078394E7008F0139</string>
+                                                                                       <string>6E9BF84E0783CE4E008F0139</string>
+                                                                                       <string>6E9BFAFC0784CAF5008F0139</string>
+                                                                                       <string>6E9BFC340784DA01008F0139</string>
+                                                                                       <string>6EA251D80785EEBB00C839D1</string>
+                                                                                       <string>6EA252220785FE0700C839D1</string>
+                                                                                       <string>6EA2573B0787D3B000C839D1</string>
+                                                                                       <string>6EA257F60787E57B00C839D1</string>
+                                                                                       <string>6EA25928078820C200C839D1</string>
+                                                                                       <string>6EC064A3078BA17E00591D61</string>
+                                                                                       <string>6EC064D1078BC50500591D61</string>
+                                                                                       <string>6EC06501078BD61800591D61</string>
+                                                                                       <string>6EC0655C078BEF7B00591D61</string>
+                                                                                       <string>6EC065CF078BF85100591D61</string>
+                                                                                       <string>6EC065D0078BF85100591D61</string>
+                                                                                       <string>6E8B669307A2E6D7002A6BAF</string>
+                                                                                       <string>6E8B6D0E07A74D66002A6BAF</string>
+                                                                                       <string>6E83F2AF07B0059D00D9DACB</string>
+                                                                                       <string>6E83F2ED07B00A5100D9DACB</string>
+                                                                                       <string>6E83F3E107B0358C00D9DACB</string>
+                                                                                       <string>6E83F3F107B0398700D9DACB</string>
+                                                                                       <string>6E83F3F207B0398700D9DACB</string>
+                                                                                       <string>6E83F5BC07B3771F00D9DACB</string>
+                                                                                       <string>6EFE498707B7459800F67D2B</string>
+                                                                                       <string>6EFE49ED07B824F200F67D2B</string>
+                                                                                       <string>6EFE4B0307B8924D00F67D2B</string>
+                                                                                       <string>6EFE4B9107B9654300F67D2B</string>
+                                                                                       <string>6EFE4C0F07B9763800F67D2B</string>
+                                                                                       <string>6EFE4C6D07B982E300F67D2B</string>
+                                                                                       <string>6EFE4CC907B99A7C00F67D2B</string>
+                                                                                       <string>6EFE4CD407B99E0C00F67D2B</string>
+                                                                                       <string>6EFE4DFF07B9D39B00F67D2B</string>
+                                                                                       <string>6EFE4EAC07BABEBC00F67D2B</string>
+                                                                                       <string>6EFE4EC107BABF2500F67D2B</string>
+                                                                                       <string>6EFE4F5807BB021400F67D2B</string>
+                                                                                       <string>6EFE4FD907BB33BA00F67D2B</string>
+                                                                                       <string>6EFE4FDA07BB33BA00F67D2B</string>
+                                                                                       <string>6EFBA94007BDDFCE0052D697</string>
+                                                                                       <string>6EFBA94B07BDE4980052D697</string>
+                                                                                       <string>6EFBA94C07BDE4980052D697</string>
+                                                                                       <string>6EFBA95B07BDE5770052D697</string>
+                                                                                       <string>6EFBA97607BDEC830052D697</string>
+                                                                                       <string>6EFBAB0507BEEDA90052D697</string>
+                                                                                       <string>6EFBAB7C07BFC4200052D697</string>
+                                                                                       <string>6EFBABE707C0693F0052D697</string>
+                                                                                       <string>6EFBACBA07C082D90052D697</string>
+                                                                                       <string>6EFBACF507C087650052D697</string>
+                                                                                       <string>6EFBAD1C07C08A070052D697</string>
+                                                                                       <string>6EFBADB907C14A7D0052D697</string>
+                                                                                       <string>6EFBADE507C162350052D697</string>
+                                                                                       <string>6EFBAEE707C1CBD40052D697</string>
+                                                                                       <string>6EFBAF1007C1D0D90052D697</string>
+                                                                                       <string>6EFBAF1207C1D0D90052D697</string>
+                                                                                       <string>6EFBAF3A07C1D5950052D697</string>
+                                                                                       <string>6EFBAF4907C1D6440052D697</string>
+                                                                                       <string>6EFBAF6E07C1D81C0052D697</string>
+                                                                                       <string>6EFBB01907C295BB0052D697</string>
+                                                                                       <string>6EFBB04707C298530052D697</string>
+                                                                                       <string>6EFBB1FC07C2D1A30052D697</string>
+                                                                                       <string>6EFBB20407C2D35A0052D697</string>
+                                                                                       <string>6EFBB20507C2D35A0052D697</string>
+                                                                                       <string>6EFBB24E07C2DBF90052D697</string>
+                                                                                       <string>6EFBB27107C2DFA10052D697</string>
+                                                                                       <string>6EFBB2CC07C2EAE90052D697</string>
+                                                                                       <string>6EFBB40507C415970052D697</string>
+                                                                                       <string>6EFBB46007C41FCA0052D697</string>
+                                                                                       <string>6EFBB46107C41FCA0052D697</string>
+                                                                                       <string>6EB3527F07C56742000347B9</string>
+                                                                                       <string>6EB352A707C56E94000347B9</string>
+                                                                                       <string>6EB352C207C574C9000347B9</string>
+                                                                                       <string>6EB352CF07C594F7000347B9</string>
+                                                                                       <string>6EB3531907C5AA1C000347B9</string>
+                                                                                       <string>6EB3532B07C5AAB8000347B9</string>
+                                                                                       <string>6EB3532C07C5AAB8000347B9</string>
+                                                                                       <string>6EB3539807C5C71B000347B9</string>
+                                                                                       <string>6EB353AA07C5C84D000347B9</string>
+                                                                                       <string>6EB3549607C7DE47000347B9</string>
+                                                                                       <string>6EB354EA07C7F537000347B9</string>
+                                                                                       <string>6EB354F007C7F637000347B9</string>
+                                                                                       <string>6EB354F107C7F637000347B9</string>
+                                                                                       <string>6EB3551A07C7FBBD000347B9</string>
+                                                                                       <string>6EB3554B07C8029A000347B9</string>
+                                                                                       <string>6EB355D807C80DED000347B9</string>
+                                                                                       <string>6EB3569207C8208E000347B9</string>
+                                                                                       <string>6EB3572707C83197000347B9</string>
+                                                                                       <string>6EB3572807C83197000347B9</string>
+                                                                                       <string>6EB3573E07C832B4000347B9</string>
+                                                                                       <string>6EB3575307C837D6000347B9</string>
+                                                                                       <string>6EB3575E07C838EC000347B9</string>
+                                                                                       <string>6EB357CC07C83ECA000347B9</string>
+                                                                                       <string>6EB357CD07C83ECA000347B9</string>
+                                                                                       <string>6EB3582F07C84168000347B9</string>
+                                                                                       <string>6EB3584707C84621000347B9</string>
+                                                                                       <string>6EB358B107C873F2000347B9</string>
+                                                                                       <string>6EB358FD07C87DD5000347B9</string>
+                                                                                       <string>6EB3598807C967BE000347B9</string>
+                                                                                       <string>6EB359AE07C96AD6000347B9</string>
+                                                                                       <string>6EB359AF07C96AD6000347B9</string>
+                                                                                       <string>6EB359CD07C99112000347B9</string>
+                                                                                       <string>6EB35A1107C9C033000347B9</string>
+                                                                                       <string>6EB35A1207C9C033000347B9</string>
+                                                                                       <string>6EB35A1B07C9C141000347B9</string>
+                                                                                       <string>6EB35A1C07C9C141000347B9</string>
+                                                                                       <string>6EB35ABB07CA624E000347B9</string>
+                                                                                       <string>6EB35B3907CA6C8C000347B9</string>
+                                                                                       <string>6EB35B3E07CA6C8C000347B9</string>
+                                                                                       <string>6EB35B9807CA7141000347B9</string>
+                                                                                       <string>6EB35BAF07CA7311000347B9</string>
+                                                                                       <string>6EB35BF507CABCBB000347B9</string>
+                                                                                       <string>6EB35C0107CABE47000347B9</string>
+                                                                                       <string>6EB35C2207CAC0C8000347B9</string>
+                                                                                       <string>6EB35C7507CAC91F000347B9</string>
+                                                                                       <string>6EB35C9D07CB8C2B000347B9</string>
+                                                                                       <string>6EB35C9E07CB8C2B000347B9</string>
+                                                                                       <string>6EB35CA607CB94A2000347B9</string>
+                                                                                       <string>6EB35CAE07CBA6CC000347B9</string>
+                                                                                       <string>6EB35CAF07CBA6CC000347B9</string>
+                                                                                       <string>6EB35CB007CBA6CC000347B9</string>
+                                                                                       <string>6EB35CB107CBA6CC000347B9</string>
+                                                                                       <string>6EB35CB207CBA6CC000347B9</string>
+                                                                                       <string>6EB35CB307CBA6CC000347B9</string>
+                                                                                       <string>6EB35CB407CBA6CC000347B9</string>
+                                                                                       <string>6EB35CB507CBA6CC000347B9</string>
+                                                                                       <string>6EB35CD407CBAC0F000347B9</string>
+                                                                                       <string>6EB35CDD07CBAD23000347B9</string>
+                                                                                       <string>6EB35CDE07CBAD23000347B9</string>
+                                                                                       <string>6EB9054707CBC34300D8982B</string>
+                                                                                       <string>6EB9054807CBC34300D8982B</string>
+                                                                                       <string>6EB9054907CBC34300D8982B</string>
+                                                                                       <string>6EB9054A07CBC34300D8982B</string>
+                                                                                       <string>6EB9054B07CBC34300D8982B</string>
+                                                                                       <string>6EB9056407CBC5E600D8982B</string>
+                                                                                       <string>6EB9058407CBC6F100D8982B</string>
+                                                                                       <string>6EB9059907CBC7C400D8982B</string>
+                                                                                       <string>6EB9059A07CBC7C400D8982B</string>
+                                                                                       <string>6EB9058607CBC6F100D8982B</string>
+                                                                               </array>
+                                                                               <key>prevStack</key>
+                                                                               <array>
+                                                                                       <string>6E3D7D1906C445A000A73B29</string>
+                                                                                       <string>6E3D7D3506C4498500A73B29</string>
+                                                                                       <string>6E38D3BD06C9B16B003BA9B4</string>
+                                                                                       <string>6E38D41106C9BA2D003BA9B4</string>
+                                                                                       <string>6E38D41206C9BA2D003BA9B4</string>
+                                                                                       <string>6E38D41406C9BA2D003BA9B4</string>
+                                                                                       <string>6E38D41706C9BA2D003BA9B4</string>
+                                                                                       <string>6E38D42C06C9BC4D003BA9B4</string>
+                                                                                       <string>6E38D62906C9F7CD003BA9B4</string>
+                                                                                       <string>6E38D68906C9FA18003BA9B4</string>
+                                                                                       <string>6EAB447106CAF1B700A4ABF0</string>
+                                                                                       <string>6EAB451006CB3DFC00A4ABF0</string>
+                                                                                       <string>6EAB465806CC01EA00A4ABF0</string>
+                                                                                       <string>6E10940606D4125F00E343E0</string>
+                                                                                       <string>6E10953F06D459A100E343E0</string>
+                                                                                       <string>6EEE8F0D06DE3A6600788128</string>
+                                                                                       <string>6EEE972906E14E9600788128</string>
+                                                                                       <string>6EEE972A06E14E9600788128</string>
+                                                                                       <string>6E6B645507120022002B77D9</string>
+                                                                                       <string>6E6B64AA071202FF002B77D9</string>
+                                                                                       <string>6E6B64AE071202FF002B77D9</string>
+                                                                                       <string>6E6B64AF071202FF002B77D9</string>
+                                                                                       <string>6E6B64B0071202FF002B77D9</string>
+                                                                                       <string>6E6B64B4071202FF002B77D9</string>
+                                                                                       <string>6E6B64C6071202FF002B77D9</string>
+                                                                                       <string>6E6B64C8071202FF002B77D9</string>
+                                                                                       <string>6E6B64E3071202FF002B77D9</string>
+                                                                                       <string>6E6B652A07120A52002B77D9</string>
+                                                                                       <string>6E6FD78E0762D118004FD845</string>
+                                                                                       <string>6E6FD7BA0762D466004FD845</string>
+                                                                                       <string>6E6FDA0A0764F415004FD845</string>
+                                                                                       <string>6E6FDAB70764F9FB004FD845</string>
+                                                                                       <string>6E6FDAFD0764FD0D004FD845</string>
+                                                                                       <string>6E6FDC4E07658970004FD845</string>
+                                                                                       <string>6E6FDC5307658970004FD845</string>
+                                                                                       <string>6E12D4A0076A616E00A95DFE</string>
+                                                                                       <string>6E818184076E3F8C00A5FBEB</string>
+                                                                                       <string>6EF2EFB90777C11B00C8B55A</string>
+                                                                                       <string>6EF2F0A5077B3C0C00C8B55A</string>
+                                                                                       <string>6EF2F227077B955F00C8B55A</string>
+                                                                                       <string>6EF2F228077B955F00C8B55A</string>
+                                                                                       <string>6E9BF32F0781F17A008F0139</string>
+                                                                                       <string>6E9BF3300781F17A008F0139</string>
+                                                                                       <string>6E9BF3C60782053A008F0139</string>
+                                                                                       <string>6E9BF4CB07828C86008F0139</string>
+                                                                                       <string>6E9BF63407836C01008F0139</string>
+                                                                                       <string>6E9BF6CB07838C56008F0139</string>
+                                                                                       <string>6E9BF708078394E7008F0139</string>
+                                                                                       <string>6E9BFC4C0784DDCF008F0139</string>
+                                                                                       <string>6EA252AC078606DA00C839D1</string>
+                                                                                       <string>6EA254210786265900C839D1</string>
+                                                                                       <string>6EA254220786265900C839D1</string>
+                                                                                       <string>6EA2560007876BD300C839D1</string>
+                                                                                       <string>6EA258560787F09200C839D1</string>
+                                                                                       <string>6EA258D50787FA1400C839D1</string>
+                                                                                       <string>6EA258D80787FA1400C839D1</string>
+                                                                                       <string>6EA258E20787FA3000C839D1</string>
+                                                                                       <string>6EC064A8078BA17E00591D61</string>
+                                                                                       <string>6EC064D7078BC50500591D61</string>
+                                                                                       <string>6EC06522078BDC7B00591D61</string>
+                                                                                       <string>6EC06565078BEF7B00591D61</string>
+                                                                                       <string>6EC0656D078BEF7B00591D61</string>
+                                                                                       <string>6EC06606078BFBFB00591D61</string>
+                                                                                       <string>6E83F2F607B00A5100D9DACB</string>
+                                                                                       <string>6E83F62507B548C400D9DACB</string>
+                                                                                       <string>6EFE4B0607B8924D00F67D2B</string>
+                                                                                       <string>6EFE4CD707B99E0C00F67D2B</string>
+                                                                                       <string>6EFE4EB407BABEBC00F67D2B</string>
+                                                                                       <string>6EFE4F6207BB021400F67D2B</string>
+                                                                                       <string>6EFE4F6C07BB021400F67D2B</string>
+                                                                                       <string>6EFE4F7B07BB07E900F67D2B</string>
+                                                                                       <string>6EFE4F9D07BB2D7F00F67D2B</string>
+                                                                                       <string>6EFE4FDE07BB33BA00F67D2B</string>
+                                                                                       <string>6EFBA94E07BDE4980052D697</string>
+                                                                                       <string>6EFBA95707BDE5370052D697</string>
+                                                                                       <string>6EFBA95E07BDE5770052D697</string>
+                                                                                       <string>6EFBA96907BDEA150052D697</string>
+                                                                                       <string>6EFBABEA07C0693F0052D697</string>
+                                                                                       <string>6EFBACAC07C082180052D697</string>
+                                                                                       <string>6EFBAD0D07C089110052D697</string>
+                                                                                       <string>6EFBAE2907C16A5F0052D697</string>
+                                                                                       <string>6EFBAEB307C1C79E0052D697</string>
+                                                                                       <string>6EFBAF8007C1D8E80052D697</string>
+                                                                                       <string>6EFBB03107C297D00052D697</string>
+                                                                                       <string>6EFBB1FF07C2D1A30052D697</string>
+                                                                                       <string>6EFBB20C07C2D35A0052D697</string>
+                                                                                       <string>6EFBB20D07C2D35A0052D697</string>
+                                                                                       <string>6EFBB28207C2E3940052D697</string>
+                                                                                       <string>6EFBB3DB07C411B10052D697</string>
+                                                                                       <string>6EB3528007C56742000347B9</string>
+                                                                                       <string>6EB3529007C56783000347B9</string>
+                                                                                       <string>6EB3529107C56783000347B9</string>
+                                                                                       <string>6EB352A807C56E94000347B9</string>
+                                                                                       <string>6EB3552007C7FBBD000347B9</string>
+                                                                                       <string>6EB355B907C80BEB000347B9</string>
+                                                                                       <string>6EB3576E07C83A91000347B9</string>
+                                                                                       <string>6EB357A807C83CE3000347B9</string>
+                                                                                       <string>6EB357AA07C83CE3000347B9</string>
+                                                                                       <string>6EB357D007C83ECA000347B9</string>
+                                                                                       <string>6EB357D207C83ECA000347B9</string>
+                                                                                       <string>6EB3585807C84621000347B9</string>
+                                                                                       <string>6EB3599C07C96968000347B9</string>
+                                                                                       <string>6EB35A1E07C9C141000347B9</string>
+                                                                                       <string>6EB35AAC07CA6027000347B9</string>
+                                                                                       <string>6EB35B4107CA6C8C000347B9</string>
+                                                                                       <string>6EB35B4207CA6C8C000347B9</string>
+                                                                                       <string>6EB9054D07CBC34300D8982B</string>
+                                                                                       <string>6EB9054E07CBC34300D8982B</string>
+                                                                                       <string>6EB9054F07CBC34300D8982B</string>
+                                                                                       <string>6EB9055007CBC34300D8982B</string>
+                                                                                       <string>6EB9055107CBC34300D8982B</string>
+                                                                                       <string>6EB9055207CBC34300D8982B</string>
+                                                                                       <string>6EB9055307CBC34300D8982B</string>
+                                                                                       <string>6EB9055407CBC34300D8982B</string>
+                                                                                       <string>6EB9055507CBC34300D8982B</string>
+                                                                                       <string>6EB9056907CBC5E600D8982B</string>
+                                                                                       <string>6EB9056A07CBC5E600D8982B</string>
+                                                                                       <string>6EB9056C07CBC5E600D8982B</string>
+                                                                                       <string>6EB9056D07CBC5E600D8982B</string>
+                                                                                       <string>6EB9057407CBC67800D8982B</string>
+                                                                                       <string>6EB9057507CBC67800D8982B</string>
+                                                                                       <string>6EB9057607CBC67800D8982B</string>
+                                                                                       <string>6EB9057707CBC67800D8982B</string>
+                                                                                       <string>6EB9058807CBC6F100D8982B</string>
+                                                                                       <string>6EB9058907CBC6F100D8982B</string>
+                                                                                       <string>6EB9058B07CBC6F100D8982B</string>
+                                                                                       <string>6EB9058C07CBC6F100D8982B</string>
+                                                                                       <string>6EB9058D07CBC6F100D8982B</string>
+                                                                                       <string>6EB9058E07CBC6F100D8982B</string>
+                                                                                       <string>6EB9058F07CBC6F100D8982B</string>
+                                                                                       <string>6EB9059007CBC6F100D8982B</string>
+                                                                                       <string>6EB9059107CBC6F100D8982B</string>
+                                                                                       <string>6EB9059507CBC72D00D8982B</string>
+                                                                                       <string>6EB9059B07CBC7C400D8982B</string>
+                                                                                       <string>6EB9059C07CBC7C400D8982B</string>
+                                                                               </array>
+                                                                       </dict>
+                                                                       <key>SplitCount</key>
+                                                                       <string>1</string>
+                                                               </dict>
+                                                               <key>StatusBarVisibility</key>
+                                                               <true/>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {1038, 710}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>0 103 1281 835 0 0 1280 938 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXNavigatorGroup</string>
+                                                       <key>Proportion</key>
+                                                       <string>710pt</string>
+                                               </dict>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CE0B20506471E060097A5F4</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Errors &amp; Warnings</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 717}, {1038, 76}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>0 103 1281 835 0 0 1280 938 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>XCDetailModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>76pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>1038pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Project</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>XCModuleDock</string>
+                               <string>PBXSmartGroupTreeModule</string>
+                               <string>XCModuleDock</string>
+                               <string>PBXNavigatorGroup</string>
+                               <string>XCDetailModule</string>
+                       </array>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>6EB9054407CBC1E500D8982B</string>
+                               <string>1CE0B1FE06471DED0097A5F4</string>
+                               <string>6EB9054507CBC1E500D8982B</string>
+                               <string>1CE0B20306471E060097A5F4</string>
+                               <string>1CE0B20506471E060097A5F4</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.default</string>
+               </dict>
+       </array>
+       <key>PerspectivesBarVisible</key>
+       <false/>
+       <key>StatusbarIsVisible</key>
+       <true/>
+       <key>TimeStamp</key>
+       <real>0.0</real>
+       <key>ToolbarDisplayMode</key>
+       <integer>1</integer>
+       <key>ToolbarIsVisible</key>
+       <true/>
+       <key>ToolbarSizeMode</key>
+       <integer>1</integer>
+       <key>Type</key>
+       <string>Perspectives</string>
+       <key>UpdateMessage</key>
+       <string></string>
+       <key>WindowJustification</key>
+       <integer>5</integer>
+       <key>WindowOrderList</key>
+       <array>
+               <string>1C0AD2B3069F1EA900FABCE6</string>
+               <string>/Users/chaz/The Cheat/The Cheat/The Cheat.xcode</string>
+       </array>
+       <key>WindowString</key>
+       <string>0 103 1281 835 0 0 1280 938 </string>
+       <key>WindowTools</key>
+       <array>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.build</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CD0528F0623707200166675</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>GeneralPrefs.m</string>
+                                                               <key>PBXSplitModuleInNavigatorKey</key>
+                                                               <dict>
+                                                                       <key>Split0</key>
+                                                                       <dict>
+                                                                               <key>PBXProjectModuleGUID</key>
+                                                                               <string>1CD052900623707200166675</string>
+                                                                               <key>PBXProjectModuleLabel</key>
+                                                                               <string>GeneralPrefs.m</string>
+                                                                               <key>bookmark</key>
+                                                                               <string>6EB35D0707CBB39D000347B9</string>
+                                                                               <key>history</key>
+                                                                               <array>
+                                                                                       <string>6EFE497707B7428D00F67D2B</string>
+                                                                                       <string>6EFE497807B7428D00F67D2B</string>
+                                                                                       <string>6EFE49FE07B8254100F67D2B</string>
+                                                                                       <string>6EFE4A3207B82EF300F67D2B</string>
+                                                                                       <string>6EFE4CC407B999CB00F67D2B</string>
+                                                                                       <string>6EFE4EBB07BABEE200F67D2B</string>
+                                                                                       <string>6EFE4F8307BB296600F67D2B</string>
+                                                                                       <string>6EFBA9F407BDFEF30052D697</string>
+                                                                                       <string>6EFBAA6707BE11080052D697</string>
+                                                                                       <string>6EFBAAC807BEE6F60052D697</string>
+                                                                                       <string>6EFBAE7007C1C04D0052D697</string>
+                                                                                       <string>6EFBAFF007C2920A0052D697</string>
+                                                                                       <string>6EFBB00707C2928F0052D697</string>
+                                                                                       <string>6EFBB02807C297B60052D697</string>
+                                                                                       <string>6EFBB10307C2B7DF0052D697</string>
+                                                                                       <string>6EFBB23407C2D5D10052D697</string>
+                                                                                       <string>6EFBB3FD07C415600052D697</string>
+                                                                                       <string>6EB356A707C820D0000347B9</string>
+                                                                                       <string>6EB3570D07C82FCE000347B9</string>
+                                                                                       <string>6EB3574307C832B4000347B9</string>
+                                                                                       <string>6EB358CA07C8753F000347B9</string>
+                                                                                       <string>6EB35AE407CA66B9000347B9</string>
+                                                                                       <string>6EB35B8207CA7034000347B9</string>
+                                                                               </array>
+                                                                               <key>prevStack</key>
+                                                                               <array>
+                                                                                       <string>6EFE4D7B07B9C4BA00F67D2B</string>
+                                                                                       <string>6EFE4DDB07B9CFA000F67D2B</string>
+                                                                                       <string>6EFE4E6A07BAAEB600F67D2B</string>
+                                                                                       <string>6EFE4E9007BABD7700F67D2B</string>
+                                                                                       <string>6EFE4E9107BABD7700F67D2B</string>
+                                                                                       <string>6EFE4EBD07BABEE200F67D2B</string>
+                                                                                       <string>6EFE4F3107BAEB1800F67D2B</string>
+                                                                                       <string>6EFE4F7107BB039900F67D2B</string>
+                                                                                       <string>6EFBB02A07C297B60052D697</string>
+                                                                                       <string>6EFBB0F607C2B24C0052D697</string>
+                                                                                       <string>6EFBB10507C2B7DF0052D697</string>
+                                                                                       <string>6EFBB3FF07C415600052D697</string>
+                                                                                       <string>6EB3542907C6C3FD000347B9</string>
+                                                                                       <string>6EB356A907C820D0000347B9</string>
+                                                                                       <string>6EB3571007C82FCE000347B9</string>
+                                                                                       <string>6EB3574507C832B4000347B9</string>
+                                                                                       <string>6EB358CC07C8753F000347B9</string>
+                                                                                       <string>6EB35AE607CA66B9000347B9</string>
+                                                                               </array>
+                                                                       </dict>
+                                                                       <key>SplitCount</key>
+                                                                       <string>1</string>
+                                                               </dict>
+                                                               <key>StatusBarVisibility</key>
+                                                               <true/>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {1281, 501}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>0 103 1281 835 0 0 1280 938 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXNavigatorGroup</string>
+                                                       <key>Proportion</key>
+                                                       <string>501pt</string>
+                                               </dict>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>XCMainBuildResultsModuleGUID</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Build</string>
+                                                               <key>XCBuildResultsTrigger_Collapse</key>
+                                                               <integer>1021</integer>
+                                                               <key>XCBuildResultsTrigger_Open</key>
+                                                               <integer>1011</integer>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 508}, {1281, 285}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>0 103 1281 835 0 0 1280 938 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXBuildResultsModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>285pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>793pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Build Results</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXBuildResultsModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>6E3D7D1506C4459300A73B29</string>
+                               <string>6EB358CE07C8753F000347B9</string>
+                               <string>1CD0528F0623707200166675</string>
+                               <string>XCMainBuildResultsModuleGUID</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.build</string>
+                       <key>WindowString</key>
+                       <string>0 103 1281 835 0 0 1280 938 </string>
+                       <key>WindowToolGUID</key>
+                       <string>6E3D7D1506C4459300A73B29</string>
+                       <key>WindowToolIsVisible</key>
+                       <false/>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.debugger</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>Debugger</key>
+                                                               <dict>
+                                                                       <key>HorizontalSplitView</key>
+                                                                       <dict>
+                                                                               <key>_collapsingFrameDimension</key>
+                                                                               <real>0.0</real>
+                                                                               <key>_indexOfCollapsedView</key>
+                                                                               <integer>0</integer>
+                                                                               <key>_percentageOfCollapsedView</key>
+                                                                               <real>0.0</real>
+                                                                               <key>isCollapsed</key>
+                                                                               <string>yes</string>
+                                                                               <key>sizes</key>
+                                                                               <array>
+                                                                                       <string>{{0, 0}, {347, 121}}</string>
+                                                                                       <string>{{0, 121}, {347, 654}}</string>
+                                                                               </array>
+                                                                       </dict>
+                                                                       <key>VerticalSplitView</key>
+                                                                       <dict>
+                                                                               <key>_collapsingFrameDimension</key>
+                                                                               <real>0.0</real>
+                                                                               <key>_indexOfCollapsedView</key>
+                                                                               <integer>0</integer>
+                                                                               <key>_percentageOfCollapsedView</key>
+                                                                               <real>0.0</real>
+                                                                               <key>isCollapsed</key>
+                                                                               <string>yes</string>
+                                                                               <key>sizes</key>
+                                                                               <array>
+                                                                                       <string>{{0, 0}, {347, 775}}</string>
+                                                                                       <string>{{347, 0}, {897, 775}}</string>
+                                                                               </array>
+                                                                       </dict>
+                                                               </dict>
+                                                               <key>LauncherConfigVersion</key>
+                                                               <string>8</string>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1C162984064C10D400B95A72</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Debug - GLUTExamples (Underwater)</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>DebugConsoleDrawerSize</key>
+                                                               <string>{100, 120}</string>
+                                                               <key>DebugConsoleVisible</key>
+                                                               <string>None</string>
+                                                               <key>DebugConsoleWindowFrame</key>
+                                                               <string>{{200, 200}, {500, 300}}</string>
+                                                               <key>DebugSTDIOWindowFrame</key>
+                                                               <string>{{200, 200}, {500, 300}}</string>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {1244, 775}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>24 121 1244 817 0 0 1280 938 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXDebugSessionModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>775pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>775pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Debugger</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXDebugSessionModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1CD10A99069EF8BA00B06720</string>
+                               <string>6EB3586107C84642000347B9</string>
+                               <string>1C162984064C10D400B95A72</string>
+                               <string>6EB3586207C84642000347B9</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.debug</string>
+                       <key>WindowString</key>
+                       <string>24 121 1244 817 0 0 1280 938 </string>
+                       <key>WindowToolGUID</key>
+                       <string>1CD10A99069EF8BA00B06720</string>
+                       <key>WindowToolIsVisible</key>
+                       <false/>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.find</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>Dock</key>
+                                                       <array>
+                                                               <dict>
+                                                                       <key>ContentConfiguration</key>
+                                                                       <dict>
+                                                                               <key>PBXProjectModuleGUID</key>
+                                                                               <string>1CDD528C0622207200134675</string>
+                                                                               <key>PBXProjectModuleLabel</key>
+                                                                               <string>BetterTableView.m</string>
+                                                                               <key>PBXSplitModuleInNavigatorKey</key>
+                                                                               <dict>
+                                                                                       <key>Split0</key>
+                                                                                       <dict>
+                                                                                               <key>PBXProjectModuleGUID</key>
+                                                                                               <string>1CD0528D0623707200166675</string>
+                                                                                               <key>PBXProjectModuleLabel</key>
+                                                                                               <string>BetterTableView.m</string>
+                                                                                               <key>bookmark</key>
+                                                                                               <string>6EB357E307C83ECA000347B9</string>
+                                                                                               <key>history</key>
+                                                                                               <array>
+                                                                                                       <string>6EFBAE8707C1C2A30052D697</string>
+                                                                                                       <string>6EFBB0C007C2B0180052D697</string>
+                                                                                                       <string>6EFBB0C107C2B0180052D697</string>
+                                                                                                       <string>6EB352FC07C5A6CD000347B9</string>
+                                                                                                       <string>6EB352FD07C5A6CD000347B9</string>
+                                                                                                       <string>6EB3530D07C5A705000347B9</string>
+                                                                                                       <string>6EB3557B07C80748000347B9</string>
+                                                                                                       <string>6EB3557C07C80748000347B9</string>
+                                                                                                       <string>6EB3557D07C80748000347B9</string>
+                                                                                               </array>
+                                                                                               <key>prevStack</key>
+                                                                                               <array>
+                                                                                                       <string>6EFBAE8907C1C2A30052D697</string>
+                                                                                                       <string>6EFBB0C307C2B0180052D697</string>
+                                                                                                       <string>6EFBB0C407C2B0180052D697</string>
+                                                                                                       <string>6EB352FF07C5A6CD000347B9</string>
+                                                                                                       <string>6EB3530007C5A6CD000347B9</string>
+                                                                                                       <string>6EB3530F07C5A705000347B9</string>
+                                                                                                       <string>6EB3531007C5A705000347B9</string>
+                                                                                                       <string>6EB3557E07C80748000347B9</string>
+                                                                                                       <string>6EB3557F07C80748000347B9</string>
+                                                                                               </array>
+                                                                                       </dict>
+                                                                                       <key>SplitCount</key>
+                                                                                       <string>1</string>
+                                                                               </dict>
+                                                                               <key>StatusBarVisibility</key>
+                                                                               <true/>
+                                                                       </dict>
+                                                                       <key>GeometryConfiguration</key>
+                                                                       <dict>
+                                                                               <key>Frame</key>
+                                                                               <string>{{0, 0}, {779, 306}}</string>
+                                                                               <key>RubberWindowFrame</key>
+                                                                               <string>441 96 779 670 0 0 1280 938 </string>
+                                                                       </dict>
+                                                                       <key>Module</key>
+                                                                       <string>PBXNavigatorGroup</string>
+                                                                       <key>Proportion</key>
+                                                                       <string>779pt</string>
+                                                               </dict>
+                                                       </array>
+                                                       <key>Proportion</key>
+                                                       <string>306pt</string>
+                                               </dict>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <true/>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CD0528E0623707200166675</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Project Find</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 313}, {779, 315}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>441 96 779 670 0 0 1280 938 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXProjectFindModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>315pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>628pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Project Find</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXProjectFindModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1C530D57069F1CE1000CFCEE</string>
+                               <string>6EB352A007C56D29000347B9</string>
+                               <string>6EB352A107C56D29000347B9</string>
+                               <string>1CDD528C0622207200134675</string>
+                               <string>1CD0528E0623707200166675</string>
+                       </array>
+                       <key>WindowString</key>
+                       <string>441 96 779 670 0 0 1280 938 </string>
+                       <key>WindowToolGUID</key>
+                       <string>1C530D57069F1CE1000CFCEE</string>
+                       <key>WindowToolIsVisible</key>
+                       <false/>
+               </dict>
+               <dict>
+                       <key>Identifier</key>
+                       <string>MENUSEPARATOR</string>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.debuggerConsole</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1C78EAAC065D492600B07095</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Debugger Console</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {689, 376}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>524 119 689 418 0 0 1280 938 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXDebugCLIModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>376pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>376pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Debugger Console</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXDebugCLIModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>6EAB469206CC062500A4ABF0</string>
+                               <string>6EB3586307C84642000347B9</string>
+                               <string>1C78EAAC065D492600B07095</string>
+                       </array>
+                       <key>WindowString</key>
+                       <string>524 119 689 418 0 0 1280 938 </string>
+                       <key>WindowToolGUID</key>
+                       <string>6EAB469206CC062500A4ABF0</string>
+                       <key>WindowToolIsVisible</key>
+                       <false/>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.run</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>LauncherConfigVersion</key>
+                                                               <string>3</string>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CD0528B0623707200166675</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Run</string>
+                                                               <key>Runner</key>
+                                                               <dict>
+                                                                       <key>HorizontalSplitView</key>
+                                                                       <dict>
+                                                                               <key>_collapsingFrameDimension</key>
+                                                                               <real>0.0</real>
+                                                                               <key>_indexOfCollapsedView</key>
+                                                                               <integer>0</integer>
+                                                                               <key>_percentageOfCollapsedView</key>
+                                                                               <real>0.0</real>
+                                                                               <key>isCollapsed</key>
+                                                                               <string>yes</string>
+                                                                               <key>sizes</key>
+                                                                               <array>
+                                                                                       <string>{{0, 0}, {366, 167}}</string>
+                                                                                       <string>{{0, 176}, {366, 267}}</string>
+                                                                               </array>
+                                                                       </dict>
+                                                                       <key>VerticalSplitView</key>
+                                                                       <dict>
+                                                                               <key>_collapsingFrameDimension</key>
+                                                                               <real>0.0</real>
+                                                                               <key>_indexOfCollapsedView</key>
+                                                                               <integer>0</integer>
+                                                                               <key>_percentageOfCollapsedView</key>
+                                                                               <real>0.0</real>
+                                                                               <key>isCollapsed</key>
+                                                                               <string>yes</string>
+                                                                               <key>sizes</key>
+                                                                               <array>
+                                                                                       <string>{{0, 0}, {405, 443}}</string>
+                                                                                       <string>{{414, 0}, {514, 443}}</string>
+                                                                               </array>
+                                                                       </dict>
+                                                               </dict>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {766, 795}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>273 295 766 643 0 0 1280 938 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXRunSessionModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>795pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>601pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Run Log</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXRunSessionModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1C0AD2B3069F1EA900FABCE6</string>
+                               <string>6EB9055707CBC34300D8982B</string>
+                               <string>1CD0528B0623707200166675</string>
+                               <string>6EB9055807CBC34300D8982B</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.run</string>
+                       <key>WindowString</key>
+                       <string>273 295 766 643 0 0 1280 938 </string>
+                       <key>WindowToolGUID</key>
+                       <string>1C0AD2B3069F1EA900FABCE6</string>
+                       <key>WindowToolIsVisible</key>
+                       <false/>
+               </dict>
+               <dict>
+                       <key>Identifier</key>
+                       <string>windowTool.scm</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1C78EAB2065D492600B07095</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>&lt;No Editor&gt;</string>
+                                                               <key>PBXSplitModuleInNavigatorKey</key>
+                                                               <dict>
+                                                                       <key>Split0</key>
+                                                                       <dict>
+                                                                               <key>PBXProjectModuleGUID</key>
+                                                                               <string>1C78EAB3065D492600B07095</string>
+                                                                       </dict>
+                                                                       <key>SplitCount</key>
+                                                                       <string>1</string>
+                                                               </dict>
+                                                               <key>StatusBarVisibility</key>
+                                                               <true/>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {452, 0}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>743 379 452 308 0 0 1280 1002 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXNavigatorGroup</string>
+                                                       <key>Proportion</key>
+                                                       <string>0pt</string>
+                                               </dict>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <true/>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CD052920623707200166675</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>SCM</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>ConsoleFrame</key>
+                                                               <string>{{0, 259}, {452, 0}}</string>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 7}, {452, 259}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>743 379 452 308 0 0 1280 1002 </string>
+                                                               <key>TableConfiguration</key>
+                                                               <array>
+                                                                       <string>Status</string>
+                                                                       <real>30</real>
+                                                                       <string>FileName</string>
+                                                                       <real>199</real>
+                                                                       <string>Path</string>
+                                                                       <real>197.09500122070312</real>
+                                                               </array>
+                                                               <key>TableFrame</key>
+                                                               <string>{{0, 0}, {452, 250}}</string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXCVSModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>259pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>266pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>SCM</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXCVSModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1C78EAB4065D492600B07095</string>
+                               <string>1C78EAB5065D492600B07095</string>
+                               <string>1C78EAB2065D492600B07095</string>
+                               <string>1CD052920623707200166675</string>
+                       </array>
+                       <key>WindowString</key>
+                       <string>743 379 452 308 0 0 1280 1002 </string>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.breakpoints</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <true/>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CD052930623707200166675</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Breakpoints</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>BreakpointsTreeTableConfiguration</key>
+                                                               <array>
+                                                                       <string>enabledColumn</string>
+                                                                       <real>16</real>
+                                                                       <string>breakpointColumn</string>
+                                                                       <real>201.5830078125</real>
+                                                               </array>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {240, 195}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>135 699 240 216 0 0 1280 938 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXDebugBreakpointsModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>195pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>195pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Breakpoints</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXDebugBreakpointsModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <false/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1C0AD2AD069F1E9B00FABCE6</string>
+                               <string>6EF2EF460777B6FC00C8B55A</string>
+                               <string>1CD052930623707200166675</string>
+                       </array>
+                       <key>WindowString</key>
+                       <string>135 699 240 216 0 0 1280 938 </string>
+                       <key>WindowToolGUID</key>
+                       <string>1C0AD2AD069F1E9B00FABCE6</string>
+                       <key>WindowToolIsVisible</key>
+                       <false/>
+               </dict>
+               <dict>
+                       <key>Identifier</key>
+                       <string>windowTool.bookmarks</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>Module</key>
+                                                       <string>PBXBookmarksModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>166pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>166pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Bookmarks</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXBookmarksModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <false/>
+                       <key>WindowString</key>
+                       <string>538 42 401 187 0 0 1280 1002 </string>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.classBrowser</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>OptionsSetName</key>
+                                                               <string>Hierarchy, all classes</string>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CA6456E063B45B4001379D8</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Class Browser - NSObject</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>ClassesFrame</key>
+                                                               <string>{{0, 0}, {374, 96}}</string>
+                                                               <key>ClassesTreeTableConfiguration</key>
+                                                               <array>
+                                                                       <string>PBXClassNameColumnIdentifier</string>
+                                                                       <real>208</real>
+                                                                       <string>PBXClassBookColumnIdentifier</string>
+                                                                       <real>22</real>
+                                                               </array>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {630, 331}}</string>
+                                                               <key>MembersFrame</key>
+                                                               <string>{{0, 105}, {374, 226}}</string>
+                                                               <key>MembersTreeTableConfiguration</key>
+                                                               <array>
+                                                                       <string>PBXMemberTypeIconColumnIdentifier</string>
+                                                                       <real>22</real>
+                                                                       <string>PBXMemberNameColumnIdentifier</string>
+                                                                       <real>216</real>
+                                                                       <string>PBXMemberTypeColumnIdentifier</string>
+                                                                       <real>97</real>
+                                                                       <string>PBXMemberBookColumnIdentifier</string>
+                                                                       <real>22</real>
+                                                               </array>
+                                                               <key>PBXModuleWindowStatusBarHidden2</key>
+                                                               <true/>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>21 563 630 352 0 0 1280 938 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXClassBrowserModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>331pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>331pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Class Browser</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXClassBrowserModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <false/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1C0AD2AF069F1E9B00FABCE6</string>
+                               <string>6EA251B50785EA9000C839D1</string>
+                               <string>1CA6456E063B45B4001379D8</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.classbrowser</string>
+                       <key>WindowString</key>
+                       <string>21 563 630 352 0 0 1280 938 </string>
+                       <key>WindowToolGUID</key>
+                       <string>1C0AD2AF069F1E9B00FABCE6</string>
+                       <key>WindowToolIsVisible</key>
+                       <false/>
+               </dict>
+       </array>
+</dict>
+</plist>
diff --git a/The Cheat.xcode/chaz.pbxuser b/The Cheat.xcode/chaz.pbxuser
new file mode 100644 (file)
index 0000000..9c937d0
--- /dev/null
@@ -0,0 +1,6104 @@
+// !$*UTF8*$!
+{
+       29B97313FDCFA39411CA2CEA = {
+               activeBuildStyle = 4A9504CDFFE6A4B311CA0CBA;
+               activeExecutable = 6ED806180641D21A002888F7;
+               activeTarget = 8D1107260486CEB800E47090;
+               addToTargets = (
+                       8D1107260486CEB800E47090,
+               );
+               breakpoints = (
+                       6EB35A0A07C9BEB0000347B9,
+               );
+               codeSenseManager = 6ED806220641D21D002888F7;
+               executables = (
+                       6ED806180641D21A002888F7,
+               );
+               perUserDictionary = {
+                       PBXConfiguration.PBXFileTableDataSource3.PBXErrorsWarningsDataSource = {
+                               PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+                               PBXFileTableDataSourceColumnSortingKey = PBXErrorsWarningsDataSource_LocationID;
+                               PBXFileTableDataSourceColumnWidthsKey = (
+                                       20,
+                                       652.8799,
+                                       348.2085,
+                               );
+                               PBXFileTableDataSourceColumnsKey = (
+                                       PBXErrorsWarningsDataSource_TypeID,
+                                       PBXErrorsWarningsDataSource_MessageID,
+                                       PBXErrorsWarningsDataSource_LocationID,
+                               );
+                       };
+                       PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = {
+                               PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+                               PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID;
+                               PBXFileTableDataSourceColumnWidthsKey = (
+                                       22,
+                                       1000,
+                               );
+                               PBXFileTableDataSourceColumnsKey = (
+                                       PBXExecutablesDataSource_ActiveFlagID,
+                                       PBXExecutablesDataSource_NameID,
+                               );
+                       };
+                       PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
+                               PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+                               PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+                               PBXFileTableDataSourceColumnWidthsKey = (
+                                       20,
+                                       719,
+                                       20,
+                                       128,
+                                       43,
+                                       43,
+                                       20,
+                               );
+                               PBXFileTableDataSourceColumnsKey = (
+                                       PBXFileDataSource_FiletypeID,
+                                       PBXFileDataSource_Filename_ColumnID,
+                                       PBXFileDataSource_Built_ColumnID,
+                                       PBXFileDataSource_ObjectSize_ColumnID,
+                                       PBXFileDataSource_Errors_ColumnID,
+                                       PBXFileDataSource_Warnings_ColumnID,
+                                       PBXFileDataSource_Target_ColumnID,
+                               );
+                       };
+                       PBXConfiguration.PBXFileTableDataSource3.PBXFindDataSource = {
+                               PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+                               PBXFileTableDataSourceColumnSortingKey = PBXFindDataSource_LocationID;
+                               PBXFileTableDataSourceColumnWidthsKey = (
+                                       504.2974,
+                                       506.2085,
+                               );
+                               PBXFileTableDataSourceColumnsKey = (
+                                       PBXFindDataSource_MessageID,
+                                       PBXFindDataSource_LocationID,
+                               );
+                       };
+                       PBXConfiguration.PBXFileTableDataSource3.XCSCMDataSource = {
+                               PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+                               PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+                               PBXFileTableDataSourceColumnWidthsKey = (
+                                       20,
+                                       20,
+                                       711,
+                                       20,
+                                       110,
+                                       43,
+                                       43,
+                                       20,
+                               );
+                               PBXFileTableDataSourceColumnsKey = (
+                                       PBXFileDataSource_SCM_ColumnID,
+                                       PBXFileDataSource_FiletypeID,
+                                       PBXFileDataSource_Filename_ColumnID,
+                                       PBXFileDataSource_Built_ColumnID,
+                                       PBXFileDataSource_ObjectSize_ColumnID,
+                                       PBXFileDataSource_Errors_ColumnID,
+                                       PBXFileDataSource_Warnings_ColumnID,
+                                       PBXFileDataSource_Target_ColumnID,
+                               );
+                       };
+                       PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = {
+                               PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+                               PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+                               PBXFileTableDataSourceColumnWidthsKey = (
+                                       20,
+                                       609,
+                                       129,
+                                       20,
+                                       129,
+                                       43,
+                                       43,
+                               );
+                               PBXFileTableDataSourceColumnsKey = (
+                                       PBXFileDataSource_FiletypeID,
+                                       PBXFileDataSource_Filename_ColumnID,
+                                       PBXTargetDataSource_PrimaryAttribute,
+                                       PBXFileDataSource_Built_ColumnID,
+                                       PBXFileDataSource_ObjectSize_ColumnID,
+                                       PBXFileDataSource_Errors_ColumnID,
+                                       PBXFileDataSource_Warnings_ColumnID,
+                               );
+                       };
+                       PBXPerProjectTemplateStateSaveDate = 130793949;
+                       PBXPrepackagedSmartGroups_v2 = (
+                               {
+                                       PBXTransientLocationAtTop = bottom;
+                                       absolutePathToBundle = "";
+                                       activationKey = OldTargetSmartGroup;
+                                       clz = PBXTargetSmartGroup;
+                                       description = "Displays all targets of the project.";
+                                       globalID = 1C37FABC04509CD000000102;
+                                       name = Targets;
+                                       preferences = {
+                                               image = Targets;
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = bottom;
+                                       absolutePathToBundle = "";
+                                       clz = PBXTargetSmartGroup2;
+                                       description = "Displays all targets of the project as well as nested build phases.";
+                                       globalID = 1C37FBAC04509CD000000102;
+                                       name = Targets;
+                                       preferences = {
+                                               image = Targets;
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = bottom;
+                                       absolutePathToBundle = "";
+                                       clz = PBXExecutablesSmartGroup;
+                                       description = "Displays all executables of the project.";
+                                       globalID = 1C37FAAC04509CD000000102;
+                                       name = Executables;
+                                       preferences = {
+                                               image = Executable;
+                                       };
+                               },
+                               {
+                                       " PBXTransientLocationAtTop " = bottom;
+                                       absolutePathToBundle = "";
+                                       clz = PBXErrorsWarningsSmartGroup;
+                                       description = "Displays files with errors or warnings.";
+                                       globalID = 1C08E77C0454961000C914BD;
+                                       name = "Errors and Warnings";
+                                       preferences = {
+                                               fnmatch = "";
+                                               image = WarningsErrors;
+                                               recursive = 1;
+                                               regex = "";
+                                               root = "<PROJECT>";
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = bottom;
+                                       absolutePathToBundle = "";
+                                       clz = PBXFilenameSmartGroup;
+                                       description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter.";
+                                       globalID = 1CC0EA4004350EF90044410B;
+                                       name = "Implementation Files";
+                                       preferences = {
+                                               canSave = 1;
+                                               fnmatch = "";
+                                               image = SmartFolder;
+                                               isLeaf = 0;
+                                               recursive = 1;
+                                               regex = "?*\\.[mcMC]";
+                                               root = "<PROJECT>";
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = bottom;
+                                       absolutePathToBundle = "";
+                                       clz = PBXFilenameSmartGroup;
+                                       description = "This group displays Interface Builder NIB Files.";
+                                       globalID = 1CC0EA4004350EF90041110B;
+                                       name = "NIB Files";
+                                       preferences = {
+                                               canSave = 1;
+                                               fnmatch = "*.nib";
+                                               image = SmartFolder;
+                                               isLeaf = 0;
+                                               recursive = 1;
+                                               regex = "";
+                                               root = "<PROJECT>";
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = no;
+                                       absolutePathToBundle = "";
+                                       clz = PBXFindSmartGroup;
+                                       description = "Displays Find Results.";
+                                       globalID = 1C37FABC05509CD000000102;
+                                       name = "Find Results";
+                                       preferences = {
+                                               image = spyglass;
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = no;
+                                       absolutePathToBundle = "";
+                                       clz = PBXBookmarksSmartGroup;
+                                       description = "Displays Project Bookmarks.";
+                                       globalID = 1C37FABC05539CD112110102;
+                                       name = Bookmarks;
+                                       preferences = {
+                                               image = Bookmarks;
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = bottom;
+                                       absolutePathToBundle = "";
+                                       clz = XCSCMSmartGroup;
+                                       description = "Displays files with interesting SCM status.";
+                                       globalID = E2644B35053B69B200211256;
+                                       name = SCM;
+                                       preferences = {
+                                               image = PBXRepository;
+                                               isLeaf = 0;
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = bottom;
+                                       absolutePathToBundle = "";
+                                       clz = PBXSymbolsSmartGroup;
+                                       description = "Displays all symbols for the project.";
+                                       globalID = 1C37FABC04509CD000100104;
+                                       name = "Project Symbols";
+                                       preferences = {
+                                               image = ProjectSymbols;
+                                               isLeaf = 1;
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = bottom;
+                                       absolutePathToBundle = "";
+                                       clz = PBXFilenameSmartGroup;
+                                       description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter.";
+                                       globalID = PBXTemplateMarker;
+                                       name = "Simple Filter SmartGroup";
+                                       preferences = {
+                                               canSave = 1;
+                                               fnmatch = "*.nib";
+                                               image = SmartFolder;
+                                               isLeaf = 0;
+                                               recursive = 1;
+                                               regex = "";
+                                               root = "<PROJECT>";
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = bottom;
+                                       absolutePathToBundle = "";
+                                       clz = PBXFilenameSmartGroup;
+                                       description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter.";
+                                       globalID = PBXTemplateMarker;
+                                       name = "Simple Regular Expression SmartGroup";
+                                       preferences = {
+                                               canSave = 1;
+                                               fnmatch = "";
+                                               image = SmartFolder;
+                                               isLeaf = 0;
+                                               recursive = 1;
+                                               regex = "?*\\.[mcMC]";
+                                               root = "<PROJECT>";
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = bottom;
+                                       clz = XDDesignSmartGroup;
+                                       description = "Displays Xdesign models";
+                                       globalID = 2E4A936305E6979E00701470;
+                                       name = Design;
+                                       preferences = {
+                                               image = Design;
+                                               isLeaf = 0;
+                                       };
+                               },
+                       );
+                       PBXWorkspaceContents = (
+                               {
+                                       PBXProjectWorkspaceModule_StateKey_Rev39 = {
+                                               PBXProjectWorkspaceModule_DEGV_Geometry = {
+                                                       _collapsingFrameDimension = 0;
+                                                       _indexOfCollapsedView = 0;
+                                                       _percentageOfCollapsedView = 0;
+                                                       isCollapsed = yes;
+                                                       sizes = (
+                                                               "{{0, 0}, {1064, 159}}",
+                                                               "{{0, 159}, {1064, 652}}",
+                                                       );
+                                               };
+                                               PBXProjectWorkspaceModule_DataSourceSelectionKey_Rev6 = {
+                                                       BoundsStr = "{{0, 0}, {1049, 142}}";
+                                                       Rows = (
+                                                       );
+                                                       VisibleRectStr = "{{0, 0}, {1049, 142}}";
+                                               };
+                                               PBXProjectWorkspaceModule_EditorOpen = true;
+                                               PBXProjectWorkspaceModule_EmbeddedNavigatorGroup = {
+                                                       PBXSplitModuleInNavigatorKey = {
+                                                               Split0 = {
+                                                                       bookmark = 6E138D8306C308BC001C688F;
+                                                                       history = (
+                                                                               6ED8074806423640002888F7,
+                                                                               6E63974C06434C0500BD3765,
+                                                                               6E63975006434C0500BD3765,
+                                                                               6ECDE0B5064452BF00B1DD8A,
+                                                                               6ED97BBD0646F82000CBF037,
+                                                                               6ED97BBE0646F82000CBF037,
+                                                                               6ED97BBF0646F82000CBF037,
+                                                                               6ED97BC00646F82000CBF037,
+                                                                               6ED97BC10646F82000CBF037,
+                                                                               6E71580C0648B7A800763517,
+                                                                               6E71580D0648B7A800763517,
+                                                                               6E71580E0648B7A800763517,
+                                                                               6E7158180648B7A800763517,
+                                                                               6EEA565C0673FEB1004A32F3,
+                                                                               6EB1D6A80674C02E00D17024,
+                                                                               6EB1D835067509C200D17024,
+                                                                               6EB1D836067509C200D17024,
+                                                                               6EB1D837067509C200D17024,
+                                                                               6E0E2A32068809AA00DA28BC,
+                                                                               6E0E2A33068809AA00DA28BC,
+                                                                               6E0E2A35068809AA00DA28BC,
+                                                                               6E0E2A38068809AA00DA28BC,
+                                                                               6EFFEF420691F9F100A30A6B,
+                                                                               6EFFEF4C0691F9F100A30A6B,
+                                                                               6EFFEF4E0691F9F100A30A6B,
+                                                                               6EFFEF530691F9F100A30A6B,
+                                                                               6EFFEFD906938D7B00A30A6B,
+                                                                               6EACCC980693D1F300A2F51D,
+                                                                               6E79C6F7069E17870072A42A,
+                                                                               6E79C6F8069E17870072A42A,
+                                                                               6E79C6FA069E17870072A42A,
+                                                                               6E79C6FB069E17870072A42A,
+                                                                               6E7614D106A6004A0051C301,
+                                                                               6E7614D306A6004A0051C301,
+                                                                               6E98A57006A7891F006A576D,
+                                                                               6EC3C2E006A9EAB2003E9C6A,
+                                                                               6EC3C2E306A9EAB2003E9C6A,
+                                                                               6EC3C2E406A9EAB2003E9C6A,
+                                                                               6EC3C2E806A9EAB2003E9C6A,
+                                                                               6EC3C2EF06A9EAB2003E9C6A,
+                                                                               6EC3C2F306A9EAB2003E9C6A,
+                                                                               6EC3C2F906A9EAB2003E9C6A,
+                                                                               6EC3C3B106AA1408003E9C6A,
+                                                                               6EC3C3B406AA1408003E9C6A,
+                                                                               6EC3C3B706AA1408003E9C6A,
+                                                                               6EEBBF2806B6F32D00519EA3,
+                                                                               6EEBBF2906B6F32D00519EA3,
+                                                                               6EEBBF2D06B6F32D00519EA3,
+                                                                               6EEBBF2F06B6F32D00519EA3,
+                                                                               6EEBBF3406B6F32D00519EA3,
+                                                                               6E31A17506B724D300E40AB3,
+                                                                               6E31A17606B724D300E40AB3,
+                                                                               6E31A17B06B724D300E40AB3,
+                                                                               6E31A18006B724D300E40AB3,
+                                                                               6E31A18106B724D300E40AB3,
+                                                                               6E31A1D206B74CBB00E40AB3,
+                                                                               6E795F6306B854DA0053C250,
+                                                                               6E795F6406B854DA0053C250,
+                                                                               6EEA097006BF83D300770544,
+                                                                               6EEA097406BF83D300770544,
+                                                                               6EEA097706BF83D300770544,
+                                                                               6EEA09E106BFDBED00770544,
+                                                                               6EEA09E206BFDBED00770544,
+                                                                               6EEA09E306BFDBED00770544,
+                                                                               6EEA09E406BFDBED00770544,
+                                                                               6EEA09E606BFDBED00770544,
+                                                                               6EEA09E706BFDBED00770544,
+                                                                               6EEA09E806BFDBED00770544,
+                                                                               6EEA09EA06BFDBED00770544,
+                                                                               6EEA09EC06BFDBED00770544,
+                                                                               6EEA09EE06BFDBED00770544,
+                                                                               6EEA09EF06BFDBED00770544,
+                                                                               6E138B0606C17081001C688F,
+                                                                               6E138B0706C17081001C688F,
+                                                                               6E138B0806C17081001C688F,
+                                                                               6E138B0A06C17081001C688F,
+                                                                               6E138B0C06C17081001C688F,
+                                                                               6E138B0D06C17081001C688F,
+                                                                               6E138B0F06C17081001C688F,
+                                                                               6E138B1606C17081001C688F,
+                                                                               6E138B1706C17081001C688F,
+                                                                               6E138B1806C17081001C688F,
+                                                                               6E138B1906C17081001C688F,
+                                                                               6E138B1A06C17081001C688F,
+                                                                               6E138BC006C1851D001C688F,
+                                                                               6E138BC206C1851D001C688F,
+                                                                               6E138BC406C1851D001C688F,
+                                                                               6E138C8006C2240E001C688F,
+                                                                               6E138C8106C2240E001C688F,
+                                                                               6E138C8206C2240E001C688F,
+                                                                               6E138C8406C2240E001C688F,
+                                                                               6E138C8506C2240E001C688F,
+                                                                               6E138C8606C2240E001C688F,
+                                                                               6E138C8706C2240E001C688F,
+                                                                               6E138C8806C2240E001C688F,
+                                                                               6E138C8A06C2240E001C688F,
+                                                                               6E138C8B06C2240E001C688F,
+                                                                               6E138C8C06C2240E001C688F,
+                                                                               6E138C8D06C2240E001C688F,
+                                                                               6E138C8F06C2240E001C688F,
+                                                                               6E138C9006C2240E001C688F,
+                                                                               6E138C9106C2240E001C688F,
+                                                                               6E138C9206C2240E001C688F,
+                                                                               6E138C9306C2240E001C688F,
+                                                                               6E138C9406C2240E001C688F,
+                                                                               6E138C9506C2240E001C688F,
+                                                                               6E138C9606C2240E001C688F,
+                                                                               6E138C9706C2240E001C688F,
+                                                                               6E138C9806C2240E001C688F,
+                                                                               6E138C9906C2240E001C688F,
+                                                                               6E138C9B06C2240E001C688F,
+                                                                               6E138C9D06C2240E001C688F,
+                                                                               6E138C9E06C2240E001C688F,
+                                                                               6E138C9F06C2240E001C688F,
+                                                                               6E138CA006C2240E001C688F,
+                                                                               6E138CA106C2240E001C688F,
+                                                                               6E138D4C06C308BC001C688F,
+                                                                               6E138D4D06C308BC001C688F,
+                                                                               6E138D4E06C308BC001C688F,
+                                                                               6E138D4F06C308BC001C688F,
+                                                                               6E138D5006C308BC001C688F,
+                                                                               6E138D5106C308BC001C688F,
+                                                                               6E138D5206C308BC001C688F,
+                                                                               6E138D5306C308BC001C688F,
+                                                                               6E138D5406C308BC001C688F,
+                                                                       );
+                                                                       prevStack = (
+                                                                               6ED806E50641DF2F002888F7,
+                                                                               6ED8074C06423640002888F7,
+                                                                               6ED8074D06423640002888F7,
+                                                                               6ED8074E06423640002888F7,
+                                                                               6ED8074F06423640002888F7,
+                                                                               6ED8075106423640002888F7,
+                                                                               6ED8075606423640002888F7,
+                                                                               6E63975706434C0500BD3765,
+                                                                               6E63975806434C0500BD3765,
+                                                                               6E63975906434C0500BD3765,
+                                                                               6E6397990643638300BD3765,
+                                                                               6ECDE0BA064452BF00B1DD8A,
+                                                                               6ED97BD40646F82000CBF037,
+                                                                               6ED97BD50646F82000CBF037,
+                                                                               6ED97BD90646F82000CBF037,
+                                                                               6ED97BDA0646F82000CBF037,
+                                                                               6ED97BDB0646F82000CBF037,
+                                                                               6ED97BDC0646F82000CBF037,
+                                                                               6ED97BDD0646F82000CBF037,
+                                                                               6ED97BDE0646F82000CBF037,
+                                                                               6ED97BEA0646F82000CBF037,
+                                                                               6E7158380648B7A800763517,
+                                                                               6EEA56700673FEB1004A32F3,
+                                                                               6EEA56710673FEB1004A32F3,
+                                                                               6EEA56750673FEB1004A32F3,
+                                                                               6EB1D6F20674C02E00D17024,
+                                                                               6E0E2A3B068809AA00DA28BC,
+                                                                               6EFFEF550691F9F100A30A6B,
+                                                                               6EFFEF850691F9F100A30A6B,
+                                                                               6EFFEFA00691F9F100A30A6B,
+                                                                               6EFFEFB80691F9F100A30A6B,
+                                                                               6EFFEFEE06938D7B00A30A6B,
+                                                                               6EB94A030693AB32009B1DA8,
+                                                                               6EACCC9C0693D1F300A2F51D,
+                                                                               6E79C709069E17870072A42A,
+                                                                               6E79C70C069E17870072A42A,
+                                                                               6E79C70D069E17870072A42A,
+                                                                               6E7614DA06A6004A0051C301,
+                                                                               6E98A55D06A744A7006A576D,
+                                                                               6E98A58006A7891F006A576D,
+                                                                               6EC3C2FD06A9EAB2003E9C6A,
+                                                                               6EC3C30406A9EAB2003E9C6A,
+                                                                               6EC3C30606A9EAB2003E9C6A,
+                                                                               6EC3C33A06A9EAB2003E9C6A,
+                                                                               6EC3C36306A9EAB2003E9C6A,
+                                                                               6EC3C3CA06AA1408003E9C6A,
+                                                                               6E72B25106ACBAC600951D50,
+                                                                               6E72B25A06ACBAC600951D50,
+                                                                               6EEBBF5706B6F32D00519EA3,
+                                                                               6EEBBF5806B6F32D00519EA3,
+                                                                               6EEBBF6006B6F32D00519EA3,
+                                                                               6EEBBF6506B6F32D00519EA3,
+                                                                               6E31A18606B724D300E40AB3,
+                                                                               6E31A18A06B724D300E40AB3,
+                                                                               6E31A19006B724D300E40AB3,
+                                                                               6E31A19C06B724D300E40AB3,
+                                                                               6E31A1A306B724D300E40AB3,
+                                                                               6E31A1AA06B724D300E40AB3,
+                                                                               6E31A1E406B74CBB00E40AB3,
+                                                                               6E795F6806B854DA0053C250,
+                                                                               6E795F6906B854DA0053C250,
+                                                                               6EEA098406BF83D300770544,
+                                                                               6EEA098506BF83D300770544,
+                                                                               6EEA098606BF83D300770544,
+                                                                               6EEA098906BF83D300770544,
+                                                                               6EEA0A0206BFDBED00770544,
+                                                                               6EEA0A0706BFDBED00770544,
+                                                                               6EEA0A2B06BFDBED00770544,
+                                                                               6E138AD006C0913C001C688F,
+                                                                               6E138AD306C0913C001C688F,
+                                                                               6E138AD706C0913C001C688F,
+                                                                               6E138ADA06C0913C001C688F,
+                                                                               6E138B1E06C17081001C688F,
+                                                                               6E138B1F06C17081001C688F,
+                                                                               6E138B2006C17081001C688F,
+                                                                               6E138B2106C17081001C688F,
+                                                                               6E138B2206C17081001C688F,
+                                                                               6E138B2406C17081001C688F,
+                                                                               6E138B2606C17081001C688F,
+                                                                               6E138B2E06C17081001C688F,
+                                                                               6E138B2F06C17081001C688F,
+                                                                               6E138B3006C17081001C688F,
+                                                                               6E138B3106C17081001C688F,
+                                                                               6E138B3206C17081001C688F,
+                                                                               6E138B3306C17081001C688F,
+                                                                               6E138B3406C17081001C688F,
+                                                                               6E138B3506C17081001C688F,
+                                                                               6E138B3606C17081001C688F,
+                                                                               6E138B3706C17081001C688F,
+                                                                               6E138B3806C17081001C688F,
+                                                                               6E138B3906C17081001C688F,
+                                                                               6E138B3A06C17081001C688F,
+                                                                               6E138B3B06C17081001C688F,
+                                                                               6E138B3C06C17081001C688F,
+                                                                               6E138B3D06C17081001C688F,
+                                                                               6E138B3E06C17081001C688F,
+                                                                               6E138B3F06C17081001C688F,
+                                                                               6E138B4006C17081001C688F,
+                                                                               6E138B4106C17081001C688F,
+                                                                               6E138B4206C17081001C688F,
+                                                                               6E138B4306C17081001C688F,
+                                                                               6E138B4506C17081001C688F,
+                                                                               6E138B4906C17081001C688F,
+                                                                               6E138B5006C17081001C688F,
+                                                                               6E138B5206C17081001C688F,
+                                                                               6E138B5306C17081001C688F,
+                                                                               6E138B5406C17081001C688F,
+                                                                               6E138B5B06C17081001C688F,
+                                                                               6E138B5D06C17081001C688F,
+                                                                               6E138B6006C17081001C688F,
+                                                                               6E138B6A06C17081001C688F,
+                                                                               6E138B6D06C17081001C688F,
+                                                                               6E138B6F06C17081001C688F,
+                                                                               6E138B7106C17081001C688F,
+                                                                               6E138B7306C17081001C688F,
+                                                                               6E138B7506C17081001C688F,
+                                                                               6E138B7706C17081001C688F,
+                                                                               6E138B7906C17081001C688F,
+                                                                               6E138B7D06C17081001C688F,
+                                                                               6E138B8206C17081001C688F,
+                                                                               6E138B8306C17081001C688F,
+                                                                               6E138B8406C17081001C688F,
+                                                                               6E138B8506C17081001C688F,
+                                                                               6E138B8606C17081001C688F,
+                                                                               6E138B8706C17081001C688F,
+                                                                               6E138B8806C17081001C688F,
+                                                                               6E138B8906C17081001C688F,
+                                                                               6E138B8A06C17081001C688F,
+                                                                               6E138B8B06C17081001C688F,
+                                                                               6E138B8C06C17081001C688F,
+                                                                               6E138B8D06C17081001C688F,
+                                                                               6E138BCC06C1851D001C688F,
+                                                                               6E138BCF06C1851D001C688F,
+                                                                               6E138BD006C1851D001C688F,
+                                                                               6E138BD306C1851D001C688F,
+                                                                               6E138BD406C1851D001C688F,
+                                                                               6E138BDA06C1851D001C688F,
+                                                                               6E138BDE06C1851D001C688F,
+                                                                               6E138BE006C1851D001C688F,
+                                                                               6E138BE206C1851D001C688F,
+                                                                               6E138BE506C1851D001C688F,
+                                                                               6E138BE706C1851D001C688F,
+                                                                               6E138BE906C1851D001C688F,
+                                                                               6E138BEB06C1851D001C688F,
+                                                                               6E138BEE06C1851D001C688F,
+                                                                               6E138CA306C2240E001C688F,
+                                                                               6E138CA406C2240E001C688F,
+                                                                               6E138CA506C2240E001C688F,
+                                                                               6E138CA606C2240E001C688F,
+                                                                               6E138CA706C2240E001C688F,
+                                                                               6E138CA806C2240E001C688F,
+                                                                               6E138CA906C2240E001C688F,
+                                                                               6E138CAA06C2240E001C688F,
+                                                                               6E138CAB06C2240E001C688F,
+                                                                               6E138CAC06C2240E001C688F,
+                                                                               6E138CAD06C2240E001C688F,
+                                                                               6E138CAE06C2240E001C688F,
+                                                                               6E138CAF06C2240E001C688F,
+                                                                               6E138CB006C2240E001C688F,
+                                                                               6E138CB106C2240E001C688F,
+                                                                               6E138CB206C2240E001C688F,
+                                                                               6E138CB306C2240E001C688F,
+                                                                               6E138CB406C2240E001C688F,
+                                                                               6E138CB506C2240E001C688F,
+                                                                               6E138CB606C2240E001C688F,
+                                                                               6E138CB706C2240E001C688F,
+                                                                               6E138CB806C2240E001C688F,
+                                                                               6E138CB906C2240E001C688F,
+                                                                               6E138CBA06C2240E001C688F,
+                                                                               6E138CBB06C2240E001C688F,
+                                                                               6E138CBC06C2240E001C688F,
+                                                                               6E138CBD06C2240E001C688F,
+                                                                               6E138CBE06C2240E001C688F,
+                                                                               6E138CBF06C2240E001C688F,
+                                                                               6E138CC006C2240E001C688F,
+                                                                               6E138CC106C2240E001C688F,
+                                                                               6E138CC206C2240E001C688F,
+                                                                               6E138CC306C2240E001C688F,
+                                                                               6E138CC406C2240E001C688F,
+                                                                               6E138CC506C2240E001C688F,
+                                                                               6E138CC606C2240E001C688F,
+                                                                               6E138CC706C2240E001C688F,
+                                                                               6E138CC806C2240E001C688F,
+                                                                               6E138CC906C2240E001C688F,
+                                                                               6E138CCA06C2240E001C688F,
+                                                                               6E138CCB06C2240E001C688F,
+                                                                               6E138CCC06C2240E001C688F,
+                                                                               6E138CCD06C2240E001C688F,
+                                                                               6E138CCE06C2240E001C688F,
+                                                                               6E138CCF06C2240E001C688F,
+                                                                               6E138CD006C2240E001C688F,
+                                                                               6E138CD106C2240E001C688F,
+                                                                               6E138CD206C2240E001C688F,
+                                                                               6E138CD406C2240E001C688F,
+                                                                               6E138CD506C2240E001C688F,
+                                                                               6E138CD606C2240E001C688F,
+                                                                               6E138CD706C2240E001C688F,
+                                                                               6E138CD806C2240E001C688F,
+                                                                               6E138CD906C2240E001C688F,
+                                                                               6E138CDA06C2240E001C688F,
+                                                                               6E138CDB06C2240E001C688F,
+                                                                               6E138CDC06C2240E001C688F,
+                                                                               6E138CDD06C2240E001C688F,
+                                                                               6E138CDE06C2240E001C688F,
+                                                                               6E138CDF06C2240E001C688F,
+                                                                               6E138CE106C2240E001C688F,
+                                                                               6E138CE206C2240E001C688F,
+                                                                               6E138CE406C2240E001C688F,
+                                                                               6E138CE506C2240E001C688F,
+                                                                               6E138CE606C2240E001C688F,
+                                                                               6E138CE806C2240E001C688F,
+                                                                               6E138CEA06C2240E001C688F,
+                                                                               6E138CEB06C2240E001C688F,
+                                                                               6E138CED06C2240E001C688F,
+                                                                               6E138CEE06C2240E001C688F,
+                                                                               6E138CEF06C2240E001C688F,
+                                                                               6E138CF006C2240E001C688F,
+                                                                               6E138CF106C2240E001C688F,
+                                                                               6E138CF306C2240E001C688F,
+                                                                               6E138CF406C2240E001C688F,
+                                                                               6E138CF506C2240E001C688F,
+                                                                               6E138CFA06C2240E001C688F,
+                                                                               6E138CFB06C2240E001C688F,
+                                                                               6E138CFC06C2240E001C688F,
+                                                                               6E138CFD06C2240E001C688F,
+                                                                               6E138CFE06C2240E001C688F,
+                                                                               6E138CFF06C2240E001C688F,
+                                                                               6E138D0006C2240E001C688F,
+                                                                               6E138D0106C2240E001C688F,
+                                                                               6E138D0206C2240E001C688F,
+                                                                               6E138D0306C2240E001C688F,
+                                                                               6E138D0406C2240E001C688F,
+                                                                               6E138D0506C2240E001C688F,
+                                                                               6E138D0606C2240E001C688F,
+                                                                               6E138D0706C2240E001C688F,
+                                                                               6E138D0806C2240E001C688F,
+                                                                               6E138D0906C2240E001C688F,
+                                                                               6E138D0A06C2240E001C688F,
+                                                                               6E138D0C06C2240E001C688F,
+                                                                               6E138D0D06C2240E001C688F,
+                                                                               6E138D0E06C2240E001C688F,
+                                                                               6E138D0F06C2240E001C688F,
+                                                                               6E138D1006C2240E001C688F,
+                                                                               6E138D1106C2240E001C688F,
+                                                                               6E138D1206C2240E001C688F,
+                                                                               6E138D1306C2240E001C688F,
+                                                                               6E138D1406C2240E001C688F,
+                                                                               6E138D1606C2240E001C688F,
+                                                                               6E138D1706C2240E001C688F,
+                                                                               6E138D1806C2240E001C688F,
+                                                                               6E138D1906C2240E001C688F,
+                                                                               6E138D1B06C2240E001C688F,
+                                                                               6E138D1E06C2240E001C688F,
+                                                                               6E138D1F06C2240E001C688F,
+                                                                               6E138D2006C2240E001C688F,
+                                                                               6E138D2106C2240E001C688F,
+                                                                               6E138D2206C2240E001C688F,
+                                                                               6E138D2306C2240E001C688F,
+                                                                               6E138D2406C2240E001C688F,
+                                                                               6E138D2506C2240E001C688F,
+                                                                               6E138D2606C2240E001C688F,
+                                                                               6E138D2706C2240E001C688F,
+                                                                               6E138D2A06C2240E001C688F,
+                                                                               6E138D2C06C2240E001C688F,
+                                                                               6E138D2D06C2240E001C688F,
+                                                                               6E138D2F06C2240E001C688F,
+                                                                               6E138D3006C2240E001C688F,
+                                                                               6E138D3106C2240E001C688F,
+                                                                               6E138D5506C308BC001C688F,
+                                                                               6E138D5606C308BC001C688F,
+                                                                               6E138D5706C308BC001C688F,
+                                                                               6E138D5806C308BC001C688F,
+                                                                               6E138D5906C308BC001C688F,
+                                                                               6E138D5A06C308BC001C688F,
+                                                                               6E138D5B06C308BC001C688F,
+                                                                               6E138D5C06C308BC001C688F,
+                                                                               6E138D5D06C308BC001C688F,
+                                                                               6E138D5E06C308BC001C688F,
+                                                                               6E138D5F06C308BC001C688F,
+                                                                               6E138D6006C308BC001C688F,
+                                                                               6E138D6106C308BC001C688F,
+                                                                               6E138D6206C308BC001C688F,
+                                                                               6E138D6306C308BC001C688F,
+                                                                               6E138D6406C308BC001C688F,
+                                                                               6E138D6506C308BC001C688F,
+                                                                               6E138D6606C308BC001C688F,
+                                                                               6E138D6706C308BC001C688F,
+                                                                               6E138D6806C308BC001C688F,
+                                                                               6E138D6906C308BC001C688F,
+                                                                               6E138D6A06C308BC001C688F,
+                                                                               6E138D6B06C308BC001C688F,
+                                                                               6E138D6C06C308BC001C688F,
+                                                                               6E138D6D06C308BC001C688F,
+                                                                               6E138D6E06C308BC001C688F,
+                                                                               6E138D6F06C308BC001C688F,
+                                                                               6E138D7006C308BC001C688F,
+                                                                               6E138D7106C308BC001C688F,
+                                                                               6E138D7206C308BC001C688F,
+                                                                               6E138D7306C308BC001C688F,
+                                                                               6E138D7406C308BC001C688F,
+                                                                               6E138D7506C308BC001C688F,
+                                                                               6E138D7606C308BC001C688F,
+                                                                               6E138D7706C308BC001C688F,
+                                                                               6E138D7806C308BC001C688F,
+                                                                               6E138D7906C308BC001C688F,
+                                                                               6E138D7A06C308BC001C688F,
+                                                                               6E138D7B06C308BC001C688F,
+                                                                               6E138D7C06C308BC001C688F,
+                                                                               6E138D7D06C308BC001C688F,
+                                                                               6E138D7E06C308BC001C688F,
+                                                                               6E138D7F06C308BC001C688F,
+                                                                               6E138D8006C308BC001C688F,
+                                                                               6E138D8106C308BC001C688F,
+                                                                               6E138D8206C308BC001C688F,
+                                                                       );
+                                                               };
+                                                               SplitCount = 1;
+                                                       };
+                                               };
+                                               PBXProjectWorkspaceModule_GeometryKey_Rev15 = {
+                                                       PBXProjectWorkspaceModule_SGTM_Geometry = {
+                                                               _collapsingFrameDimension = 0;
+                                                               _indexOfCollapsedView = 0;
+                                                               _percentageOfCollapsedView = 0;
+                                                               sizes = (
+                                                                       "{{0, 0}, {216, 811}}",
+                                                                       "{{216, 0}, {1064, 811}}",
+                                                               );
+                                                       };
+                                               };
+                                               PBXProjectWorkspaceModule_OldDetailFrame = "{{0, 0}, {1064, 159}}";
+                                               PBXProjectWorkspaceModule_OldEditorFrame = "{{0, 159}, {1064, 652}}";
+                                               PBXProjectWorkspaceModule_OldSuperviewFrame = "{{216, 0}, {1064, 811}}";
+                                               PBXProjectWorkspaceModule_SGTM = {
+                                                       PBXBottomSmartGroupGIDs = (
+                                                               1C37FBAC04509CD000000102,
+                                                               1C37FAAC04509CD000000102,
+                                                               1C08E77C0454961000C914BD,
+                                                               1CC0EA4004350EF90044410B,
+                                                               1CC0EA4004350EF90041110B,
+                                                               1C37FABC05509CD000000102,
+                                                               1C37FABC05539CD112110102,
+                                                               E2644B35053B69B200211256,
+                                                               1C37FABC04509CD000100104,
+                                                       );
+                                                       PBXSmartGroupTreeModuleColumnData = {
+                                                               PBXSmartGroupTreeModuleColumnWidthsKey = (
+                                                                       199,
+                                                               );
+                                                               PBXSmartGroupTreeModuleColumnsKey_v4 = (
+                                                                       MainColumn,
+                                                               );
+                                                       };
+                                                       PBXSmartGroupTreeModuleOutlineStateKey_v7 = {
+                                                               PBXSmartGroupTreeModuleOutlineStateExpansionKey = (
+                                                                       29B97314FDCFA39411CA2CEA,
+                                                                       080E96DDFE201D6D7F000001,
+                                                                       6E98A54A06A73E37006A576D,
+                                                                       6ED806580641D343002888F7,
+                                                                       6ED806700641D3AC002888F7,
+                                                                       29B97315FDCFA39411CA2CEA,
+                                                                       29B97317FDCFA39411CA2CEA,
+                                                                       1C37FBAC04509CD000000102,
+                                                               );
+                                                               PBXSmartGroupTreeModuleOutlineStateSelectionKey = (
+                                                                       (
+                                                                               56,
+                                                                       ),
+                                                               );
+                                                               PBXSmartGroupTreeModuleOutlineStateVisibleRectKey = "{{0, 278}, {199, 793}}";
+                                                       };
+                                                       PBXTopSmartGroupGIDs = (
+                                                       );
+                                               };
+                                       };
+                               },
+                       );
+                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXBuildResultsModule" = {
+                       };
+                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXDebugCLIModule" = {
+                       };
+                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXDebugSessionModule" = {
+                               Debugger = {
+                                       HorizontalSplitView = {
+                                               _collapsingFrameDimension = 0;
+                                               _indexOfCollapsedView = 0;
+                                               _percentageOfCollapsedView = 0;
+                                               isCollapsed = yes;
+                                               sizes = (
+                                                       "{{0, 0}, {287, 502}}",
+                                                       "{{0, 502}, {287, 163}}",
+                                               );
+                                       };
+                                       VerticalSplitView = {
+                                               _collapsingFrameDimension = 0;
+                                               _indexOfCollapsedView = 0;
+                                               _percentageOfCollapsedView = 0;
+                                               isCollapsed = yes;
+                                               sizes = (
+                                                       "{{0, 0}, {287, 665}}",
+                                                       "{{287, 0}, {993, 665}}",
+                                               );
+                                       };
+                               };
+                               LauncherConfigVersion = 8;
+                       };
+                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXNavigatorGroup" = {
+                               PBXSplitModuleInNavigatorKey = {
+                                       SplitCount = 1;
+                               };
+                       };
+                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXProjectFindModule" = {
+                       };
+                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXProjectWorkspaceModule" = {
+                               PBXProjectWorkspaceModule_StateKey_Rev39 = {
+                                       PBXProjectWorkspaceModule_DEGV_Geometry = {
+                                               _collapsingFrameDimension = 0;
+                                               _indexOfCollapsedView = 0;
+                                               _percentageOfCollapsedView = 0;
+                                               isCollapsed = yes;
+                                               sizes = (
+                                                       "{{0, 0}, {1064, 159}}",
+                                                       "{{0, 159}, {1064, 652}}",
+                                               );
+                                       };
+                                       PBXProjectWorkspaceModule_DataSourceSelectionKey_Rev6 = {
+                                               BoundsStr = "{{0, 0}, {1049, 142}}";
+                                               Rows = (
+                                                       0,
+                                               );
+                                               VisibleRectStr = "{{0, 0}, {1049, 142}}";
+                                       };
+                                       PBXProjectWorkspaceModule_EditorOpen = true;
+                                       PBXProjectWorkspaceModule_EmbeddedNavigatorGroup = {
+                                               PBXSplitModuleInNavigatorKey = {
+                                                       Split0 = {
+                                                               bookmark = 6E138D3906C22413001C688F;
+                                                               history = (
+                                                                       6ED8074806423640002888F7,
+                                                                       6E63974C06434C0500BD3765,
+                                                                       6E63975006434C0500BD3765,
+                                                                       6ECDE0B5064452BF00B1DD8A,
+                                                                       6ED97BBD0646F82000CBF037,
+                                                                       6ED97BBE0646F82000CBF037,
+                                                                       6ED97BBF0646F82000CBF037,
+                                                                       6ED97BC00646F82000CBF037,
+                                                                       6ED97BC10646F82000CBF037,
+                                                                       6E71580C0648B7A800763517,
+                                                                       6E71580D0648B7A800763517,
+                                                                       6E71580E0648B7A800763517,
+                                                                       6E7158180648B7A800763517,
+                                                                       6EEA565C0673FEB1004A32F3,
+                                                                       6EB1D6A80674C02E00D17024,
+                                                                       6EB1D835067509C200D17024,
+                                                                       6EB1D836067509C200D17024,
+                                                                       6EB1D837067509C200D17024,
+                                                                       6E0E2A32068809AA00DA28BC,
+                                                                       6E0E2A33068809AA00DA28BC,
+                                                                       6E0E2A35068809AA00DA28BC,
+                                                                       6E0E2A38068809AA00DA28BC,
+                                                                       6EFFEF420691F9F100A30A6B,
+                                                                       6EFFEF4C0691F9F100A30A6B,
+                                                                       6EFFEF4E0691F9F100A30A6B,
+                                                                       6EFFEF530691F9F100A30A6B,
+                                                                       6EFFEFD906938D7B00A30A6B,
+                                                                       6EACCC980693D1F300A2F51D,
+                                                                       6E79C6F7069E17870072A42A,
+                                                                       6E79C6F8069E17870072A42A,
+                                                                       6E79C6FA069E17870072A42A,
+                                                                       6E79C6FB069E17870072A42A,
+                                                                       6E7614D106A6004A0051C301,
+                                                                       6E7614D306A6004A0051C301,
+                                                                       6E98A57006A7891F006A576D,
+                                                                       6EC3C2E006A9EAB2003E9C6A,
+                                                                       6EC3C2E306A9EAB2003E9C6A,
+                                                                       6EC3C2E406A9EAB2003E9C6A,
+                                                                       6EC3C2E806A9EAB2003E9C6A,
+                                                                       6EC3C2EF06A9EAB2003E9C6A,
+                                                                       6EC3C2F306A9EAB2003E9C6A,
+                                                                       6EC3C2F406A9EAB2003E9C6A,
+                                                                       6EC3C2F906A9EAB2003E9C6A,
+                                                                       6EC3C3B106AA1408003E9C6A,
+                                                                       6EC3C3B406AA1408003E9C6A,
+                                                                       6EC3C3B706AA1408003E9C6A,
+                                                                       6EEBBF2806B6F32D00519EA3,
+                                                                       6EEBBF2906B6F32D00519EA3,
+                                                                       6EEBBF2D06B6F32D00519EA3,
+                                                                       6EEBBF2F06B6F32D00519EA3,
+                                                                       6EEBBF3406B6F32D00519EA3,
+                                                                       6E31A17506B724D300E40AB3,
+                                                                       6E31A17606B724D300E40AB3,
+                                                                       6E31A17B06B724D300E40AB3,
+                                                                       6E31A18006B724D300E40AB3,
+                                                                       6E31A18106B724D300E40AB3,
+                                                                       6E31A1D206B74CBB00E40AB3,
+                                                                       6E795F6306B854DA0053C250,
+                                                                       6E795F6406B854DA0053C250,
+                                                                       6EEA097006BF83D300770544,
+                                                                       6EEA097406BF83D300770544,
+                                                                       6EEA097706BF83D300770544,
+                                                                       6EEA09E106BFDBED00770544,
+                                                                       6EEA09E206BFDBED00770544,
+                                                                       6EEA09E306BFDBED00770544,
+                                                                       6EEA09E406BFDBED00770544,
+                                                                       6EEA09E606BFDBED00770544,
+                                                                       6EEA09E706BFDBED00770544,
+                                                                       6EEA09E806BFDBED00770544,
+                                                                       6EEA09EA06BFDBED00770544,
+                                                                       6EEA09EC06BFDBED00770544,
+                                                                       6EEA09EE06BFDBED00770544,
+                                                                       6EEA09EF06BFDBED00770544,
+                                                                       6E138B0606C17081001C688F,
+                                                                       6E138B0706C17081001C688F,
+                                                                       6E138B0806C17081001C688F,
+                                                                       6E138B0A06C17081001C688F,
+                                                                       6E138B0C06C17081001C688F,
+                                                                       6E138B0D06C17081001C688F,
+                                                                       6E138B0F06C17081001C688F,
+                                                                       6E138B1206C17081001C688F,
+                                                                       6E138B1606C17081001C688F,
+                                                                       6E138B1706C17081001C688F,
+                                                                       6E138B1806C17081001C688F,
+                                                                       6E138B1906C17081001C688F,
+                                                                       6E138B1A06C17081001C688F,
+                                                                       6E138BBE06C1851D001C688F,
+                                                                       6E138BC006C1851D001C688F,
+                                                                       6E138BC206C1851D001C688F,
+                                                                       6E138BC406C1851D001C688F,
+                                                                       6E138C8006C2240E001C688F,
+                                                                       6E138C8106C2240E001C688F,
+                                                                       6E138C8206C2240E001C688F,
+                                                                       6E138C8306C2240E001C688F,
+                                                                       6E138C8406C2240E001C688F,
+                                                                       6E138C8506C2240E001C688F,
+                                                                       6E138C8606C2240E001C688F,
+                                                                       6E138C8706C2240E001C688F,
+                                                                       6E138C8806C2240E001C688F,
+                                                                       6E138C8906C2240E001C688F,
+                                                                       6E138C8A06C2240E001C688F,
+                                                                       6E138C8B06C2240E001C688F,
+                                                                       6E138C8C06C2240E001C688F,
+                                                                       6E138C8D06C2240E001C688F,
+                                                                       6E138C8E06C2240E001C688F,
+                                                                       6E138C8F06C2240E001C688F,
+                                                                       6E138C9006C2240E001C688F,
+                                                                       6E138C9106C2240E001C688F,
+                                                                       6E138C9206C2240E001C688F,
+                                                                       6E138C9306C2240E001C688F,
+                                                                       6E138C9406C2240E001C688F,
+                                                                       6E138C9506C2240E001C688F,
+                                                                       6E138C9606C2240E001C688F,
+                                                                       6E138C9706C2240E001C688F,
+                                                                       6E138C9806C2240E001C688F,
+                                                                       6E138C9906C2240E001C688F,
+                                                                       6E138C9A06C2240E001C688F,
+                                                                       6E138C9B06C2240E001C688F,
+                                                                       6E138C9C06C2240E001C688F,
+                                                                       6E138C9D06C2240E001C688F,
+                                                                       6E138C9E06C2240E001C688F,
+                                                                       6E138C9F06C2240E001C688F,
+                                                                       6E138CA006C2240E001C688F,
+                                                                       6E138CA106C2240E001C688F,
+                                                                       6E138CA206C2240E001C688F,
+                                                               );
+                                                               nextStack = (
+                                                                       6E138D3206C2240E001C688F,
+                                                               );
+                                                               prevStack = (
+                                                                       6ED806E50641DF2F002888F7,
+                                                                       6ED8074C06423640002888F7,
+                                                                       6ED8074D06423640002888F7,
+                                                                       6ED8074E06423640002888F7,
+                                                                       6ED8074F06423640002888F7,
+                                                                       6ED8075106423640002888F7,
+                                                                       6ED8075606423640002888F7,
+                                                                       6E63975706434C0500BD3765,
+                                                                       6E63975806434C0500BD3765,
+                                                                       6E63975906434C0500BD3765,
+                                                                       6E6397990643638300BD3765,
+                                                                       6ECDE0BA064452BF00B1DD8A,
+                                                                       6ED97BD40646F82000CBF037,
+                                                                       6ED97BD50646F82000CBF037,
+                                                                       6ED97BD90646F82000CBF037,
+                                                                       6ED97BDA0646F82000CBF037,
+                                                                       6ED97BDB0646F82000CBF037,
+                                                                       6ED97BDC0646F82000CBF037,
+                                                                       6ED97BDD0646F82000CBF037,
+                                                                       6ED97BDE0646F82000CBF037,
+                                                                       6ED97BEA0646F82000CBF037,
+                                                                       6E7158380648B7A800763517,
+                                                                       6EEA56700673FEB1004A32F3,
+                                                                       6EEA56710673FEB1004A32F3,
+                                                                       6EEA56750673FEB1004A32F3,
+                                                                       6EB1D6F20674C02E00D17024,
+                                                                       6E0E2A3B068809AA00DA28BC,
+                                                                       6EFFEF550691F9F100A30A6B,
+                                                                       6EFFEF850691F9F100A30A6B,
+                                                                       6EFFEFA00691F9F100A30A6B,
+                                                                       6EFFEFB80691F9F100A30A6B,
+                                                                       6EFFEFEE06938D7B00A30A6B,
+                                                                       6EB94A030693AB32009B1DA8,
+                                                                       6EACCC9C0693D1F300A2F51D,
+                                                                       6E79C709069E17870072A42A,
+                                                                       6E79C70C069E17870072A42A,
+                                                                       6E79C70D069E17870072A42A,
+                                                                       6E7614DA06A6004A0051C301,
+                                                                       6E98A55D06A744A7006A576D,
+                                                                       6E98A58006A7891F006A576D,
+                                                                       6EC3C2FD06A9EAB2003E9C6A,
+                                                                       6EC3C30406A9EAB2003E9C6A,
+                                                                       6EC3C30606A9EAB2003E9C6A,
+                                                                       6EC3C33A06A9EAB2003E9C6A,
+                                                                       6EC3C36306A9EAB2003E9C6A,
+                                                                       6EC3C3CA06AA1408003E9C6A,
+                                                                       6EC3C3CD06AA1408003E9C6A,
+                                                                       6E72B25106ACBAC600951D50,
+                                                                       6E72B25A06ACBAC600951D50,
+                                                                       6EEBBF5706B6F32D00519EA3,
+                                                                       6EEBBF5806B6F32D00519EA3,
+                                                                       6EEBBF6006B6F32D00519EA3,
+                                                                       6EEBBF6506B6F32D00519EA3,
+                                                                       6E31A18606B724D300E40AB3,
+                                                                       6E31A18A06B724D300E40AB3,
+                                                                       6E31A19006B724D300E40AB3,
+                                                                       6E31A19C06B724D300E40AB3,
+                                                                       6E31A1A306B724D300E40AB3,
+                                                                       6E31A1AA06B724D300E40AB3,
+                                                                       6E31A1E406B74CBB00E40AB3,
+                                                                       6E795F6806B854DA0053C250,
+                                                                       6E795F6906B854DA0053C250,
+                                                                       6EEA098406BF83D300770544,
+                                                                       6EEA098506BF83D300770544,
+                                                                       6EEA098606BF83D300770544,
+                                                                       6EEA098906BF83D300770544,
+                                                                       6EEA0A0206BFDBED00770544,
+                                                                       6EEA0A0706BFDBED00770544,
+                                                                       6EEA0A2B06BFDBED00770544,
+                                                                       6E138AD006C0913C001C688F,
+                                                                       6E138AD306C0913C001C688F,
+                                                                       6E138AD706C0913C001C688F,
+                                                                       6E138ADA06C0913C001C688F,
+                                                                       6E138B1E06C17081001C688F,
+                                                                       6E138B1F06C17081001C688F,
+                                                                       6E138B2006C17081001C688F,
+                                                                       6E138B2106C17081001C688F,
+                                                                       6E138B2206C17081001C688F,
+                                                                       6E138B2406C17081001C688F,
+                                                                       6E138B2606C17081001C688F,
+                                                                       6E138B2E06C17081001C688F,
+                                                                       6E138B2F06C17081001C688F,
+                                                                       6E138B3006C17081001C688F,
+                                                                       6E138B3106C17081001C688F,
+                                                                       6E138B3206C17081001C688F,
+                                                                       6E138B3306C17081001C688F,
+                                                                       6E138B3406C17081001C688F,
+                                                                       6E138B3506C17081001C688F,
+                                                                       6E138B3606C17081001C688F,
+                                                                       6E138B3706C17081001C688F,
+                                                                       6E138B3806C17081001C688F,
+                                                                       6E138B3906C17081001C688F,
+                                                                       6E138B3A06C17081001C688F,
+                                                                       6E138B3B06C17081001C688F,
+                                                                       6E138B3C06C17081001C688F,
+                                                                       6E138B3D06C17081001C688F,
+                                                                       6E138B3E06C17081001C688F,
+                                                                       6E138B3F06C17081001C688F,
+                                                                       6E138B4006C17081001C688F,
+                                                                       6E138B4106C17081001C688F,
+                                                                       6E138B4206C17081001C688F,
+                                                                       6E138B4306C17081001C688F,
+                                                                       6E138B4506C17081001C688F,
+                                                                       6E138B4906C17081001C688F,
+                                                                       6E138B5006C17081001C688F,
+                                                                       6E138B5206C17081001C688F,
+                                                                       6E138B5306C17081001C688F,
+                                                                       6E138B5406C17081001C688F,
+                                                                       6E138B5B06C17081001C688F,
+                                                                       6E138B5D06C17081001C688F,
+                                                                       6E138B6006C17081001C688F,
+                                                                       6E138B6A06C17081001C688F,
+                                                                       6E138B6D06C17081001C688F,
+                                                                       6E138B6F06C17081001C688F,
+                                                                       6E138B7106C17081001C688F,
+                                                                       6E138B7306C17081001C688F,
+                                                                       6E138B7506C17081001C688F,
+                                                                       6E138B7706C17081001C688F,
+                                                                       6E138B7906C17081001C688F,
+                                                                       6E138B7D06C17081001C688F,
+                                                                       6E138B7E06C17081001C688F,
+                                                                       6E138B8006C17081001C688F,
+                                                                       6E138B8206C17081001C688F,
+                                                                       6E138B8306C17081001C688F,
+                                                                       6E138B8406C17081001C688F,
+                                                                       6E138B8506C17081001C688F,
+                                                                       6E138B8606C17081001C688F,
+                                                                       6E138B8706C17081001C688F,
+                                                                       6E138B8806C17081001C688F,
+                                                                       6E138B8906C17081001C688F,
+                                                                       6E138B8A06C17081001C688F,
+                                                                       6E138B8B06C17081001C688F,
+                                                                       6E138B8C06C17081001C688F,
+                                                                       6E138B8D06C17081001C688F,
+                                                                       6E138BCC06C1851D001C688F,
+                                                                       6E138BCF06C1851D001C688F,
+                                                                       6E138BD006C1851D001C688F,
+                                                                       6E138BD306C1851D001C688F,
+                                                                       6E138BD406C1851D001C688F,
+                                                                       6E138BDA06C1851D001C688F,
+                                                                       6E138BDE06C1851D001C688F,
+                                                                       6E138BE006C1851D001C688F,
+                                                                       6E138BE206C1851D001C688F,
+                                                                       6E138BE506C1851D001C688F,
+                                                                       6E138BE706C1851D001C688F,
+                                                                       6E138BE906C1851D001C688F,
+                                                                       6E138BEB06C1851D001C688F,
+                                                                       6E138BEE06C1851D001C688F,
+                                                                       6E138CA306C2240E001C688F,
+                                                                       6E138CA406C2240E001C688F,
+                                                                       6E138CA506C2240E001C688F,
+                                                                       6E138CA606C2240E001C688F,
+                                                                       6E138CA706C2240E001C688F,
+                                                                       6E138CA806C2240E001C688F,
+                                                                       6E138CA906C2240E001C688F,
+                                                                       6E138CAA06C2240E001C688F,
+                                                                       6E138CAB06C2240E001C688F,
+                                                                       6E138CAC06C2240E001C688F,
+                                                                       6E138CAD06C2240E001C688F,
+                                                                       6E138CAE06C2240E001C688F,
+                                                                       6E138CAF06C2240E001C688F,
+                                                                       6E138CB006C2240E001C688F,
+                                                                       6E138CB106C2240E001C688F,
+                                                                       6E138CB206C2240E001C688F,
+                                                                       6E138CB306C2240E001C688F,
+                                                                       6E138CB406C2240E001C688F,
+                                                                       6E138CB506C2240E001C688F,
+                                                                       6E138CB606C2240E001C688F,
+                                                                       6E138CB706C2240E001C688F,
+                                                                       6E138CB806C2240E001C688F,
+                                                                       6E138CB906C2240E001C688F,
+                                                                       6E138CBA06C2240E001C688F,
+                                                                       6E138CBB06C2240E001C688F,
+                                                                       6E138CBC06C2240E001C688F,
+                                                                       6E138CBD06C2240E001C688F,
+                                                                       6E138CBE06C2240E001C688F,
+                                                                       6E138CBF06C2240E001C688F,
+                                                                       6E138CC006C2240E001C688F,
+                                                                       6E138CC106C2240E001C688F,
+                                                                       6E138CC206C2240E001C688F,
+                                                                       6E138CC306C2240E001C688F,
+                                                                       6E138CC406C2240E001C688F,
+                                                                       6E138CC506C2240E001C688F,
+                                                                       6E138CC606C2240E001C688F,
+                                                                       6E138CC706C2240E001C688F,
+                                                                       6E138CC806C2240E001C688F,
+                                                                       6E138CC906C2240E001C688F,
+                                                                       6E138CCA06C2240E001C688F,
+                                                                       6E138CCB06C2240E001C688F,
+                                                                       6E138CCC06C2240E001C688F,
+                                                                       6E138CCD06C2240E001C688F,
+                                                                       6E138CCE06C2240E001C688F,
+                                                                       6E138CCF06C2240E001C688F,
+                                                                       6E138CD006C2240E001C688F,
+                                                                       6E138CD106C2240E001C688F,
+                                                                       6E138CD206C2240E001C688F,
+                                                                       6E138CD306C2240E001C688F,
+                                                                       6E138CD406C2240E001C688F,
+                                                                       6E138CD506C2240E001C688F,
+                                                                       6E138CD606C2240E001C688F,
+                                                                       6E138CD706C2240E001C688F,
+                                                                       6E138CD806C2240E001C688F,
+                                                                       6E138CD906C2240E001C688F,
+                                                                       6E138CDA06C2240E001C688F,
+                                                                       6E138CDB06C2240E001C688F,
+                                                                       6E138CDC06C2240E001C688F,
+                                                                       6E138CDD06C2240E001C688F,
+                                                                       6E138CDE06C2240E001C688F,
+                                                                       6E138CDF06C2240E001C688F,
+                                                                       6E138CE006C2240E001C688F,
+                                                                       6E138CE106C2240E001C688F,
+                                                                       6E138CE206C2240E001C688F,
+                                                                       6E138CE306C2240E001C688F,
+                                                                       6E138CE406C2240E001C688F,
+                                                                       6E138CE506C2240E001C688F,
+                                                                       6E138CE606C2240E001C688F,
+                                                                       6E138CE706C2240E001C688F,
+                                                                       6E138CE806C2240E001C688F,
+                                                                       6E138CE906C2240E001C688F,
+                                                                       6E138CEA06C2240E001C688F,
+                                                                       6E138CEB06C2240E001C688F,
+                                                                       6E138CEC06C2240E001C688F,
+                                                                       6E138CED06C2240E001C688F,
+                                                                       6E138CEE06C2240E001C688F,
+                                                                       6E138CEF06C2240E001C688F,
+                                                                       6E138CF006C2240E001C688F,
+                                                                       6E138CF106C2240E001C688F,
+                                                                       6E138CF206C2240E001C688F,
+                                                                       6E138CF306C2240E001C688F,
+                                                                       6E138CF406C2240E001C688F,
+                                                                       6E138CF506C2240E001C688F,
+                                                                       6E138CF606C2240E001C688F,
+                                                                       6E138CF706C2240E001C688F,
+                                                                       6E138CF806C2240E001C688F,
+                                                                       6E138CF906C2240E001C688F,
+                                                                       6E138CFA06C2240E001C688F,
+                                                                       6E138CFB06C2240E001C688F,
+                                                                       6E138CFC06C2240E001C688F,
+                                                                       6E138CFD06C2240E001C688F,
+                                                                       6E138CFE06C2240E001C688F,
+                                                                       6E138CFF06C2240E001C688F,
+                                                                       6E138D0006C2240E001C688F,
+                                                                       6E138D0106C2240E001C688F,
+                                                                       6E138D0206C2240E001C688F,
+                                                                       6E138D0306C2240E001C688F,
+                                                                       6E138D0406C2240E001C688F,
+                                                                       6E138D0506C2240E001C688F,
+                                                                       6E138D0606C2240E001C688F,
+                                                                       6E138D0706C2240E001C688F,
+                                                                       6E138D0806C2240E001C688F,
+                                                                       6E138D0906C2240E001C688F,
+                                                                       6E138D0A06C2240E001C688F,
+                                                                       6E138D0B06C2240E001C688F,
+                                                                       6E138D0C06C2240E001C688F,
+                                                                       6E138D0D06C2240E001C688F,
+                                                                       6E138D0E06C2240E001C688F,
+                                                                       6E138D0F06C2240E001C688F,
+                                                                       6E138D1006C2240E001C688F,
+                                                                       6E138D1106C2240E001C688F,
+                                                                       6E138D1206C2240E001C688F,
+                                                                       6E138D1306C2240E001C688F,
+                                                                       6E138D1406C2240E001C688F,
+                                                                       6E138D1506C2240E001C688F,
+                                                                       6E138D1606C2240E001C688F,
+                                                                       6E138D1706C2240E001C688F,
+                                                                       6E138D1806C2240E001C688F,
+                                                                       6E138D1906C2240E001C688F,
+                                                                       6E138D1A06C2240E001C688F,
+                                                                       6E138D1B06C2240E001C688F,
+                                                                       6E138D1C06C2240E001C688F,
+                                                                       6E138D1D06C2240E001C688F,
+                                                                       6E138D1E06C2240E001C688F,
+                                                                       6E138D1F06C2240E001C688F,
+                                                                       6E138D2006C2240E001C688F,
+                                                                       6E138D2106C2240E001C688F,
+                                                                       6E138D2206C2240E001C688F,
+                                                                       6E138D2306C2240E001C688F,
+                                                                       6E138D2406C2240E001C688F,
+                                                                       6E138D2506C2240E001C688F,
+                                                                       6E138D2606C2240E001C688F,
+                                                                       6E138D2706C2240E001C688F,
+                                                                       6E138D2806C2240E001C688F,
+                                                                       6E138D2906C2240E001C688F,
+                                                                       6E138D2A06C2240E001C688F,
+                                                                       6E138D2B06C2240E001C688F,
+                                                                       6E138D2C06C2240E001C688F,
+                                                                       6E138D2D06C2240E001C688F,
+                                                                       6E138D2E06C2240E001C688F,
+                                                                       6E138D2F06C2240E001C688F,
+                                                                       6E138D3006C2240E001C688F,
+                                                                       6E138D3106C2240E001C688F,
+                                                               );
+                                                       };
+                                                       SplitCount = 1;
+                                               };
+                                       };
+                                       PBXProjectWorkspaceModule_GeometryKey_Rev15 = {
+                                               PBXProjectWorkspaceModule_SGTM_Geometry = {
+                                                       _collapsingFrameDimension = 0;
+                                                       _indexOfCollapsedView = 0;
+                                                       _percentageOfCollapsedView = 0;
+                                                       sizes = (
+                                                               "{{0, 0}, {216, 811}}",
+                                                               "{{216, 0}, {1064, 811}}",
+                                                       );
+                                               };
+                                       };
+                                       PBXProjectWorkspaceModule_OldDetailFrame = "{{0, 0}, {1064, 159}}";
+                                       PBXProjectWorkspaceModule_OldEditorFrame = "{{0, 159}, {1064, 652}}";
+                                       PBXProjectWorkspaceModule_OldSuperviewFrame = "{{216, 0}, {1064, 811}}";
+                                       PBXProjectWorkspaceModule_SGTM = {
+                                               PBXBottomSmartGroupGIDs = (
+                                                       1C37FBAC04509CD000000102,
+                                                       1C37FAAC04509CD000000102,
+                                                       1C08E77C0454961000C914BD,
+                                                       1CC0EA4004350EF90044410B,
+                                                       1CC0EA4004350EF90041110B,
+                                                       1C37FABC05509CD000000102,
+                                                       1C37FABC05539CD112110102,
+                                                       E2644B35053B69B200211256,
+                                                       1C37FABC04509CD000100104,
+                                               );
+                                               PBXSmartGroupTreeModuleColumnData = {
+                                                       PBXSmartGroupTreeModuleColumnWidthsKey = (
+                                                               199,
+                                                       );
+                                                       PBXSmartGroupTreeModuleColumnsKey_v4 = (
+                                                               MainColumn,
+                                                       );
+                                               };
+                                               PBXSmartGroupTreeModuleOutlineStateKey_v7 = {
+                                                       PBXSmartGroupTreeModuleOutlineStateExpansionKey = (
+                                                               29B97314FDCFA39411CA2CEA,
+                                                               080E96DDFE201D6D7F000001,
+                                                               6E98A54A06A73E37006A576D,
+                                                               6E7157BC0647004B00763517,
+                                                               6ED806580641D343002888F7,
+                                                               6ED806700641D3AC002888F7,
+                                                               29B97315FDCFA39411CA2CEA,
+                                                               29B97317FDCFA39411CA2CEA,
+                                                               1C37FBAC04509CD000000102,
+                                                       );
+                                                       PBXSmartGroupTreeModuleOutlineStateSelectionKey = (
+                                                               (
+                                                                       14,
+                                                                       9,
+                                                                       0,
+                                                               ),
+                                                       );
+                                                       PBXSmartGroupTreeModuleOutlineStateVisibleRectKey = "{{0, 0}, {199, 793}}";
+                                               };
+                                               PBXTopSmartGroupGIDs = (
+                                               );
+                                       };
+                               };
+                       };
+                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXRunSessionModule" = {
+                               LauncherConfigVersion = 3;
+                               Runner = {
+                                       HorizontalSplitView = {
+                                               _collapsingFrameDimension = 0;
+                                               _indexOfCollapsedView = 0;
+                                               _percentageOfCollapsedView = 0;
+                                               isCollapsed = yes;
+                                               sizes = (
+                                                       "{{0, 0}, {491, 167}}",
+                                                       "{{0, 176}, {491, 267}}",
+                                               );
+                                       };
+                                       VerticalSplitView = {
+                                               _collapsingFrameDimension = 0;
+                                               _indexOfCollapsedView = 0;
+                                               _percentageOfCollapsedView = 0;
+                                               isCollapsed = yes;
+                                               sizes = (
+                                                       "{{0, 0}, {405, 443}}",
+                                                       "{{414, 0}, {514, 443}}",
+                                               );
+                                       };
+                               };
+                       };
+                       PBXWorkspaceGeometries = (
+                               {
+                                       Frame = "{{0, 0}, {1280, 811}}";
+                                       PBXProjectWorkspaceModule_GeometryKey_Rev15 = {
+                                               PBXProjectWorkspaceModule_RunWindowVisible = true;
+                                       };
+                                       RubberWindowFrame = "0 85 1280 853 0 0 1280 938 ";
+                               },
+                       );
+                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXBuildResultsModule" = {
+                               Frame = "{{0, 0}, {480, 217}}";
+                               PBXModuleWindowStatusBarHidden = YES;
+                               RubberWindowFrame = "400 543 480 238 0 0 1280 938 ";
+                       };
+                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXDebugCLIModule" = {
+                               Frame = "{{0, 0}, {400, 201}}";
+                               PBXModuleWindowStatusBarHidden = YES;
+                               RubberWindowFrame = "50 910 400 222 0 0 1280 938 ";
+                       };
+                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXDebugSessionModule" = {
+                               DebugConsoleDrawerSize = "{100, 120}";
+                               DebugConsoleVisible = Drawer;
+                               DebugConsoleWindowFrame = "{{200, 200}, {500, 300}}";
+                               DebugSTDIOWindowFrame = "{{200, 200}, {500, 300}}";
+                               Frame = "{{0, 0}, {1280, 665}}";
+                               RubberWindowFrame = "0 231 1280 707 0 0 1280 938 ";
+                       };
+                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXNavigatorGroup" = {
+                               Frame = "{{0, 0}, {750, 481}}";
+                               PBXModuleWindowStatusBarHidden = YES;
+                               RubberWindowFrame = "15 431 750 502 0 0 1280 938 ";
+                       };
+                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXProjectFindModule" = {
+                               Frame = "{{0, 0}, {1280, 851}}";
+                               RubberWindowFrame = "0 45 1280 893 0 0 1280 938 ";
+                       };
+                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXProjectWorkspaceModule" = {
+                               Frame = "{{0, 0}, {1280, 811}}";
+                               PBXProjectWorkspaceModule_GeometryKey_Rev15 = {
+                                       PBXProjectWorkspaceModule_RunWindowVisible = true;
+                               };
+                               RubberWindowFrame = "0 85 1280 853 0 0 1280 938 ";
+                       };
+                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXRunSessionModule" = {
+                               Frame = "{{0, 0}, {745, 443}}";
+                               PBXModuleWindowStatusBarHidden = YES;
+                               RubberWindowFrame = "607 121 745 464 0 0 1280 938 ";
+                       };
+                       PBXWorkspaceStateSaveDate = 130793949;
+               };
+               perUserProjectItems = {
+                       6E10940606D4125F00E343E0 = 6E10940606D4125F00E343E0;
+                       6E10953F06D459A100E343E0 = 6E10953F06D459A100E343E0;
+                       6E12D3B80767AE3C00A95DFE = 6E12D3B80767AE3C00A95DFE;
+                       6E12D4A0076A616E00A95DFE = 6E12D4A0076A616E00A95DFE;
+                       6E12D56F076A7C9500A95DFE = 6E12D56F076A7C9500A95DFE;
+                       6E12D5D8076ABBB000A95DFE = 6E12D5D8076ABBB000A95DFE;
+                       6E12D609076AC69000A95DFE = 6E12D609076AC69000A95DFE;
+                       6E12D651076ACBFA00A95DFE = 6E12D651076ACBFA00A95DFE;
+                       6E38D3BD06C9B16B003BA9B4 = 6E38D3BD06C9B16B003BA9B4;
+                       6E38D41106C9BA2D003BA9B4 = 6E38D41106C9BA2D003BA9B4;
+                       6E38D41206C9BA2D003BA9B4 = 6E38D41206C9BA2D003BA9B4;
+                       6E38D41406C9BA2D003BA9B4 = 6E38D41406C9BA2D003BA9B4;
+                       6E38D41706C9BA2D003BA9B4 = 6E38D41706C9BA2D003BA9B4;
+                       6E38D42606C9BC4D003BA9B4 = 6E38D42606C9BC4D003BA9B4;
+                       6E38D42C06C9BC4D003BA9B4 = 6E38D42C06C9BC4D003BA9B4;
+                       6E38D62906C9F7CD003BA9B4 = 6E38D62906C9F7CD003BA9B4;
+                       6E38D68906C9FA18003BA9B4 = 6E38D68906C9FA18003BA9B4;
+                       6E3D7D1906C445A000A73B29 = 6E3D7D1906C445A000A73B29;
+                       6E3D7D3506C4498500A73B29 = 6E3D7D3506C4498500A73B29;
+                       6E3DC5E6077CE2CA004C82C0 = 6E3DC5E6077CE2CA004C82C0;
+                       6E6B645507120022002B77D9 = 6E6B645507120022002B77D9;
+                       6E6B64AA071202FF002B77D9 = 6E6B64AA071202FF002B77D9;
+                       6E6B64AE071202FF002B77D9 = 6E6B64AE071202FF002B77D9;
+                       6E6B64AF071202FF002B77D9 = 6E6B64AF071202FF002B77D9;
+                       6E6B64B0071202FF002B77D9 = 6E6B64B0071202FF002B77D9;
+                       6E6B64B4071202FF002B77D9 = 6E6B64B4071202FF002B77D9;
+                       6E6B64C6071202FF002B77D9 = 6E6B64C6071202FF002B77D9;
+                       6E6B64C8071202FF002B77D9 = 6E6B64C8071202FF002B77D9;
+                       6E6B64E3071202FF002B77D9 = 6E6B64E3071202FF002B77D9;
+                       6E6B652A07120A52002B77D9 = 6E6B652A07120A52002B77D9;
+                       6E6FD6CC0762C1BB004FD845 = 6E6FD6CC0762C1BB004FD845;
+                       6E6FD7750762D0B4004FD845 = 6E6FD7750762D0B4004FD845;
+                       6E6FD78C0762D118004FD845 = 6E6FD78C0762D118004FD845;
+                       6E6FD78E0762D118004FD845 = 6E6FD78E0762D118004FD845;
+                       6E6FD7B30762D466004FD845 = 6E6FD7B30762D466004FD845;
+                       6E6FD7BA0762D466004FD845 = 6E6FD7BA0762D466004FD845;
+                       6E6FD9BB0764E81F004FD845 = 6E6FD9BB0764E81F004FD845;
+                       6E6FDA050764F415004FD845 = 6E6FDA050764F415004FD845;
+                       6E6FDA0A0764F415004FD845 = 6E6FDA0A0764F415004FD845;
+                       6E6FDAB70764F9FB004FD845 = 6E6FDAB70764F9FB004FD845;
+                       6E6FDAFD0764FD0D004FD845 = 6E6FDAFD0764FD0D004FD845;
+                       6E6FDB1A0764FFD9004FD845 = 6E6FDB1A0764FFD9004FD845;
+                       6E6FDC4E07658970004FD845 = 6E6FDC4E07658970004FD845;
+                       6E6FDC5307658970004FD845 = 6E6FDC5307658970004FD845;
+                       6E6FDDB50766A1F4004FD845 = 6E6FDDB50766A1F4004FD845;
+                       6E81817A076E3D6800A5FBEB = 6E81817A076E3D6800A5FBEB;
+                       6E818184076E3F8C00A5FBEB = 6E818184076E3F8C00A5FBEB;
+                       6E83F2AF07B0059D00D9DACB = 6E83F2AF07B0059D00D9DACB;
+                       6E83F2ED07B00A5100D9DACB = 6E83F2ED07B00A5100D9DACB;
+                       6E83F2F607B00A5100D9DACB = 6E83F2F607B00A5100D9DACB;
+                       6E83F3E107B0358C00D9DACB = 6E83F3E107B0358C00D9DACB;
+                       6E83F3F107B0398700D9DACB = 6E83F3F107B0398700D9DACB;
+                       6E83F3F207B0398700D9DACB = 6E83F3F207B0398700D9DACB;
+                       6E83F5BC07B3771F00D9DACB = 6E83F5BC07B3771F00D9DACB;
+                       6E83F62507B548C400D9DACB = 6E83F62507B548C400D9DACB;
+                       6E8B669307A2E6D7002A6BAF = 6E8B669307A2E6D7002A6BAF;
+                       6E8B6D0E07A74D66002A6BAF = 6E8B6D0E07A74D66002A6BAF;
+                       6E9BF3290781F17A008F0139 = 6E9BF3290781F17A008F0139;
+                       6E9BF32F0781F17A008F0139 = 6E9BF32F0781F17A008F0139;
+                       6E9BF3300781F17A008F0139 = 6E9BF3300781F17A008F0139;
+                       6E9BF3C60782053A008F0139 = 6E9BF3C60782053A008F0139;
+                       6E9BF4CB07828C86008F0139 = 6E9BF4CB07828C86008F0139;
+                       6E9BF5E607836C01008F0139 = 6E9BF5E607836C01008F0139;
+                       6E9BF63407836C01008F0139 = 6E9BF63407836C01008F0139;
+                       6E9BF6CB07838C56008F0139 = 6E9BF6CB07838C56008F0139;
+                       6E9BF6FD078394E7008F0139 = 6E9BF6FD078394E7008F0139;
+                       6E9BF708078394E7008F0139 = 6E9BF708078394E7008F0139;
+                       6E9BF84E0783CE4E008F0139 = 6E9BF84E0783CE4E008F0139;
+                       6E9BFAFC0784CAF5008F0139 = 6E9BFAFC0784CAF5008F0139;
+                       6E9BFC340784DA01008F0139 = 6E9BFC340784DA01008F0139;
+                       6E9BFC4C0784DDCF008F0139 = 6E9BFC4C0784DDCF008F0139;
+                       6EA251D80785EEBB00C839D1 = 6EA251D80785EEBB00C839D1;
+                       6EA252220785FE0700C839D1 = 6EA252220785FE0700C839D1;
+                       6EA252AC078606DA00C839D1 = 6EA252AC078606DA00C839D1;
+                       6EA254210786265900C839D1 = 6EA254210786265900C839D1;
+                       6EA254220786265900C839D1 = 6EA254220786265900C839D1;
+                       6EA2560007876BD300C839D1 = 6EA2560007876BD300C839D1;
+                       6EA2573B0787D3B000C839D1 = 6EA2573B0787D3B000C839D1;
+                       6EA257F60787E57B00C839D1 = 6EA257F60787E57B00C839D1;
+                       6EA258560787F09200C839D1 = 6EA258560787F09200C839D1;
+                       6EA258D50787FA1400C839D1 = 6EA258D50787FA1400C839D1;
+                       6EA258D80787FA1400C839D1 = 6EA258D80787FA1400C839D1;
+                       6EA258E20787FA3000C839D1 = 6EA258E20787FA3000C839D1;
+                       6EA25928078820C200C839D1 = 6EA25928078820C200C839D1;
+                       6EA396C9077F4C2F002B0E69 = 6EA396C9077F4C2F002B0E69;
+                       6EA396CA077F4C2F002B0E69 = 6EA396CA077F4C2F002B0E69;
+                       6EA398C1077FA115002B0E69 = 6EA398C1077FA115002B0E69;
+                       6EA39A27077FCC6D002B0E69 = 6EA39A27077FCC6D002B0E69;
+                       6EA39A28077FCC6D002B0E69 = 6EA39A28077FCC6D002B0E69;
+                       6EAB446A06CAF1B700A4ABF0 = 6EAB446A06CAF1B700A4ABF0;
+                       6EAB447106CAF1B700A4ABF0 = 6EAB447106CAF1B700A4ABF0;
+                       6EAB451006CB3DFC00A4ABF0 = 6EAB451006CB3DFC00A4ABF0;
+                       6EAB465806CC01EA00A4ABF0 = 6EAB465806CC01EA00A4ABF0;
+                       6EB3527F07C56742000347B9 = 6EB3527F07C56742000347B9;
+                       6EB3528007C56742000347B9 = 6EB3528007C56742000347B9;
+                       6EB3529007C56783000347B9 = 6EB3529007C56783000347B9;
+                       6EB3529107C56783000347B9 = 6EB3529107C56783000347B9;
+                       6EB352A707C56E94000347B9 = 6EB352A707C56E94000347B9;
+                       6EB352A807C56E94000347B9 = 6EB352A807C56E94000347B9;
+                       6EB352C207C574C9000347B9 = 6EB352C207C574C9000347B9;
+                       6EB352CF07C594F7000347B9 = 6EB352CF07C594F7000347B9;
+                       6EB3531907C5AA1C000347B9 = 6EB3531907C5AA1C000347B9;
+                       6EB3532B07C5AAB8000347B9 = 6EB3532B07C5AAB8000347B9;
+                       6EB3532C07C5AAB8000347B9 = 6EB3532C07C5AAB8000347B9;
+                       6EB3539807C5C71B000347B9 = 6EB3539807C5C71B000347B9;
+                       6EB353AA07C5C84D000347B9 = 6EB353AA07C5C84D000347B9;
+                       6EB3549607C7DE47000347B9 = 6EB3549607C7DE47000347B9;
+                       6EB354EA07C7F537000347B9 = 6EB354EA07C7F537000347B9;
+                       6EB354F007C7F637000347B9 = 6EB354F007C7F637000347B9;
+                       6EB354F107C7F637000347B9 = 6EB354F107C7F637000347B9;
+                       6EB3551A07C7FBBD000347B9 = 6EB3551A07C7FBBD000347B9;
+                       6EB3552007C7FBBD000347B9 = 6EB3552007C7FBBD000347B9;
+                       6EB3554B07C8029A000347B9 = 6EB3554B07C8029A000347B9;
+                       6EB355B907C80BEB000347B9 = 6EB355B907C80BEB000347B9;
+                       6EB355D807C80DED000347B9 = 6EB355D807C80DED000347B9;
+                       6EB3569207C8208E000347B9 = 6EB3569207C8208E000347B9;
+                       6EB3572707C83197000347B9 = 6EB3572707C83197000347B9;
+                       6EB3572807C83197000347B9 = 6EB3572807C83197000347B9;
+                       6EB3573E07C832B4000347B9 = 6EB3573E07C832B4000347B9;
+                       6EB3575307C837D6000347B9 = 6EB3575307C837D6000347B9;
+                       6EB3575E07C838EC000347B9 = 6EB3575E07C838EC000347B9;
+                       6EB3576E07C83A91000347B9 = 6EB3576E07C83A91000347B9;
+                       6EB357A807C83CE3000347B9 = 6EB357A807C83CE3000347B9;
+                       6EB357AA07C83CE3000347B9 = 6EB357AA07C83CE3000347B9;
+                       6EB357CC07C83ECA000347B9 = 6EB357CC07C83ECA000347B9;
+                       6EB357CD07C83ECA000347B9 = 6EB357CD07C83ECA000347B9;
+                       6EB357D007C83ECA000347B9 = 6EB357D007C83ECA000347B9;
+                       6EB357D207C83ECA000347B9 = 6EB357D207C83ECA000347B9;
+                       6EB3582F07C84168000347B9 = 6EB3582F07C84168000347B9;
+                       6EB3584707C84621000347B9 = 6EB3584707C84621000347B9;
+                       6EB3585807C84621000347B9 = 6EB3585807C84621000347B9;
+                       6EB358B107C873F2000347B9 = 6EB358B107C873F2000347B9;
+                       6EB358FD07C87DD5000347B9 = 6EB358FD07C87DD5000347B9;
+                       6EB3598807C967BE000347B9 = 6EB3598807C967BE000347B9;
+                       6EB3599C07C96968000347B9 = 6EB3599C07C96968000347B9;
+                       6EB359AE07C96AD6000347B9 = 6EB359AE07C96AD6000347B9;
+                       6EB359AF07C96AD6000347B9 = 6EB359AF07C96AD6000347B9;
+                       6EB359CD07C99112000347B9 = 6EB359CD07C99112000347B9;
+                       6EB35A1107C9C033000347B9 = 6EB35A1107C9C033000347B9;
+                       6EB35A1207C9C033000347B9 = 6EB35A1207C9C033000347B9;
+                       6EB35A1B07C9C141000347B9 = 6EB35A1B07C9C141000347B9;
+                       6EB35A1C07C9C141000347B9 = 6EB35A1C07C9C141000347B9;
+                       6EB35A1E07C9C141000347B9 = 6EB35A1E07C9C141000347B9;
+                       6EB35AAC07CA6027000347B9 = 6EB35AAC07CA6027000347B9;
+                       6EB35ABB07CA624E000347B9 = 6EB35ABB07CA624E000347B9;
+                       6EB35B3907CA6C8C000347B9 = 6EB35B3907CA6C8C000347B9;
+                       6EB35B3E07CA6C8C000347B9 = 6EB35B3E07CA6C8C000347B9;
+                       6EB35B4107CA6C8C000347B9 = 6EB35B4107CA6C8C000347B9;
+                       6EB35B4207CA6C8C000347B9 = 6EB35B4207CA6C8C000347B9;
+                       6EB35B9807CA7141000347B9 = 6EB35B9807CA7141000347B9;
+                       6EB35BAF07CA7311000347B9 = 6EB35BAF07CA7311000347B9;
+                       6EB35BF507CABCBB000347B9 = 6EB35BF507CABCBB000347B9;
+                       6EB35C0107CABE47000347B9 = 6EB35C0107CABE47000347B9;
+                       6EB35C2207CAC0C8000347B9 = 6EB35C2207CAC0C8000347B9;
+                       6EB35C7507CAC91F000347B9 = 6EB35C7507CAC91F000347B9;
+                       6EB35C9D07CB8C2B000347B9 = 6EB35C9D07CB8C2B000347B9;
+                       6EB35C9E07CB8C2B000347B9 = 6EB35C9E07CB8C2B000347B9;
+                       6EB35CA607CB94A2000347B9 = 6EB35CA607CB94A2000347B9;
+                       6EB35CAE07CBA6CC000347B9 = 6EB35CAE07CBA6CC000347B9;
+                       6EB35CAF07CBA6CC000347B9 = 6EB35CAF07CBA6CC000347B9;
+                       6EB35CB007CBA6CC000347B9 = 6EB35CB007CBA6CC000347B9;
+                       6EB35CB107CBA6CC000347B9 = 6EB35CB107CBA6CC000347B9;
+                       6EB35CB207CBA6CC000347B9 = 6EB35CB207CBA6CC000347B9;
+                       6EB35CB307CBA6CC000347B9 = 6EB35CB307CBA6CC000347B9;
+                       6EB35CB407CBA6CC000347B9 = 6EB35CB407CBA6CC000347B9;
+                       6EB35CB507CBA6CC000347B9 = 6EB35CB507CBA6CC000347B9;
+                       6EB35CD407CBAC0F000347B9 = 6EB35CD407CBAC0F000347B9;
+                       6EB35CDD07CBAD23000347B9 = 6EB35CDD07CBAD23000347B9;
+                       6EB35CDE07CBAD23000347B9 = 6EB35CDE07CBAD23000347B9;
+                       6EB9054707CBC34300D8982B = 6EB9054707CBC34300D8982B;
+                       6EB9054807CBC34300D8982B = 6EB9054807CBC34300D8982B;
+                       6EB9054907CBC34300D8982B = 6EB9054907CBC34300D8982B;
+                       6EB9054A07CBC34300D8982B = 6EB9054A07CBC34300D8982B;
+                       6EB9054B07CBC34300D8982B = 6EB9054B07CBC34300D8982B;
+                       6EB9054D07CBC34300D8982B = 6EB9054D07CBC34300D8982B;
+                       6EB9054E07CBC34300D8982B = 6EB9054E07CBC34300D8982B;
+                       6EB9054F07CBC34300D8982B = 6EB9054F07CBC34300D8982B;
+                       6EB9055007CBC34300D8982B = 6EB9055007CBC34300D8982B;
+                       6EB9055107CBC34300D8982B = 6EB9055107CBC34300D8982B;
+                       6EB9055207CBC34300D8982B = 6EB9055207CBC34300D8982B;
+                       6EB9055307CBC34300D8982B = 6EB9055307CBC34300D8982B;
+                       6EB9055407CBC34300D8982B = 6EB9055407CBC34300D8982B;
+                       6EB9055507CBC34300D8982B = 6EB9055507CBC34300D8982B;
+                       6EB9056407CBC5E600D8982B = 6EB9056407CBC5E600D8982B;
+                       6EB9056907CBC5E600D8982B = 6EB9056907CBC5E600D8982B;
+                       6EB9056A07CBC5E600D8982B = 6EB9056A07CBC5E600D8982B;
+                       6EB9056C07CBC5E600D8982B = 6EB9056C07CBC5E600D8982B;
+                       6EB9056D07CBC5E600D8982B = 6EB9056D07CBC5E600D8982B;
+                       6EB9057407CBC67800D8982B = 6EB9057407CBC67800D8982B;
+                       6EB9057507CBC67800D8982B = 6EB9057507CBC67800D8982B;
+                       6EB9057607CBC67800D8982B = 6EB9057607CBC67800D8982B;
+                       6EB9057707CBC67800D8982B = 6EB9057707CBC67800D8982B;
+                       6EB9058407CBC6F100D8982B = 6EB9058407CBC6F100D8982B;
+                       6EB9058607CBC6F100D8982B = 6EB9058607CBC6F100D8982B;
+                       6EB9058807CBC6F100D8982B = 6EB9058807CBC6F100D8982B;
+                       6EB9058907CBC6F100D8982B = 6EB9058907CBC6F100D8982B;
+                       6EB9058B07CBC6F100D8982B = 6EB9058B07CBC6F100D8982B;
+                       6EB9058C07CBC6F100D8982B = 6EB9058C07CBC6F100D8982B;
+                       6EB9058D07CBC6F100D8982B = 6EB9058D07CBC6F100D8982B;
+                       6EB9058E07CBC6F100D8982B = 6EB9058E07CBC6F100D8982B;
+                       6EB9058F07CBC6F100D8982B = 6EB9058F07CBC6F100D8982B;
+                       6EB9059007CBC6F100D8982B = 6EB9059007CBC6F100D8982B;
+                       6EB9059107CBC6F100D8982B = 6EB9059107CBC6F100D8982B;
+                       6EB9059507CBC72D00D8982B = 6EB9059507CBC72D00D8982B;
+                       6EB9059907CBC7C400D8982B = 6EB9059907CBC7C400D8982B;
+                       6EB9059A07CBC7C400D8982B = 6EB9059A07CBC7C400D8982B;
+                       6EB9059B07CBC7C400D8982B = 6EB9059B07CBC7C400D8982B;
+                       6EB9059C07CBC7C400D8982B = 6EB9059C07CBC7C400D8982B;
+                       6EB9059E07CBC7C400D8982B = 6EB9059E07CBC7C400D8982B;
+                       6EC064A3078BA17E00591D61 = 6EC064A3078BA17E00591D61;
+                       6EC064A8078BA17E00591D61 = 6EC064A8078BA17E00591D61;
+                       6EC064D1078BC50500591D61 = 6EC064D1078BC50500591D61;
+                       6EC064D7078BC50500591D61 = 6EC064D7078BC50500591D61;
+                       6EC06501078BD61800591D61 = 6EC06501078BD61800591D61;
+                       6EC06522078BDC7B00591D61 = 6EC06522078BDC7B00591D61;
+                       6EC0655C078BEF7B00591D61 = 6EC0655C078BEF7B00591D61;
+                       6EC06565078BEF7B00591D61 = 6EC06565078BEF7B00591D61;
+                       6EC0656D078BEF7B00591D61 = 6EC0656D078BEF7B00591D61;
+                       6EC065CF078BF85100591D61 = 6EC065CF078BF85100591D61;
+                       6EC065D0078BF85100591D61 = 6EC065D0078BF85100591D61;
+                       6EC06606078BFBFB00591D61 = 6EC06606078BFBFB00591D61;
+                       6EDB006D06D5216D00DBD1D5 = 6EDB006D06D5216D00DBD1D5;
+                       6EDB009906D5286C00DBD1D5 = 6EDB009906D5286C00DBD1D5;
+                       6EDB021306D5AAD400DBD1D5 = 6EDB021306D5AAD400DBD1D5;
+                       6EDB05C806D96DA400DBD1D5 = 6EDB05C806D96DA400DBD1D5;
+                       6EDB06E406DA8A7900DBD1D5 = 6EDB06E406DA8A7900DBD1D5;
+                       6EDB070D06DA910700DBD1D5 = 6EDB070D06DA910700DBD1D5;
+                       6EDB072F06DA92D800DBD1D5 = 6EDB072F06DA92D800DBD1D5;
+                       6EDB073506DA950800DBD1D5 = 6EDB073506DA950800DBD1D5;
+                       6EDB079A06DA9CBB00DBD1D5 = 6EDB079A06DA9CBB00DBD1D5;
+                       6EDB079C06DA9CBB00DBD1D5 = 6EDB079C06DA9CBB00DBD1D5;
+                       6EDB07AD06DA9D9A00DBD1D5 = 6EDB07AD06DA9D9A00DBD1D5;
+                       6EDB07E106DAA3F700DBD1D5 = 6EDB07E106DAA3F700DBD1D5;
+                       6EEE8F0C06DE3A6600788128 = 6EEE8F0C06DE3A6600788128;
+                       6EEE8F0D06DE3A6600788128 = 6EEE8F0D06DE3A6600788128;
+                       6EEE972906E14E9600788128 = 6EEE972906E14E9600788128;
+                       6EEE972A06E14E9600788128 = 6EEE972A06E14E9600788128;
+                       6EEEB31D06E3FF3600788128 = 6EEEB31D06E3FF3600788128;
+                       6EF2EFB90777C11B00C8B55A = 6EF2EFB90777C11B00C8B55A;
+                       6EF2F0A5077B3C0C00C8B55A = 6EF2F0A5077B3C0C00C8B55A;
+                       6EF2F224077B955F00C8B55A = 6EF2F224077B955F00C8B55A;
+                       6EF2F227077B955F00C8B55A = 6EF2F227077B955F00C8B55A;
+                       6EF2F228077B955F00C8B55A = 6EF2F228077B955F00C8B55A;
+                       6EFBA94007BDDFCE0052D697 = 6EFBA94007BDDFCE0052D697;
+                       6EFBA94B07BDE4980052D697 = 6EFBA94B07BDE4980052D697;
+                       6EFBA94C07BDE4980052D697 = 6EFBA94C07BDE4980052D697;
+                       6EFBA94E07BDE4980052D697 = 6EFBA94E07BDE4980052D697;
+                       6EFBA95707BDE5370052D697 = 6EFBA95707BDE5370052D697;
+                       6EFBA95B07BDE5770052D697 = 6EFBA95B07BDE5770052D697;
+                       6EFBA95E07BDE5770052D697 = 6EFBA95E07BDE5770052D697;
+                       6EFBA96907BDEA150052D697 = 6EFBA96907BDEA150052D697;
+                       6EFBA97607BDEC830052D697 = 6EFBA97607BDEC830052D697;
+                       6EFBAB0507BEEDA90052D697 = 6EFBAB0507BEEDA90052D697;
+                       6EFBAB7C07BFC4200052D697 = 6EFBAB7C07BFC4200052D697;
+                       6EFBABE707C0693F0052D697 = 6EFBABE707C0693F0052D697;
+                       6EFBABEA07C0693F0052D697 = 6EFBABEA07C0693F0052D697;
+                       6EFBACAC07C082180052D697 = 6EFBACAC07C082180052D697;
+                       6EFBACBA07C082D90052D697 = 6EFBACBA07C082D90052D697;
+                       6EFBACF507C087650052D697 = 6EFBACF507C087650052D697;
+                       6EFBAD0D07C089110052D697 = 6EFBAD0D07C089110052D697;
+                       6EFBAD1C07C08A070052D697 = 6EFBAD1C07C08A070052D697;
+                       6EFBADB907C14A7D0052D697 = 6EFBADB907C14A7D0052D697;
+                       6EFBADE507C162350052D697 = 6EFBADE507C162350052D697;
+                       6EFBAE2907C16A5F0052D697 = 6EFBAE2907C16A5F0052D697;
+                       6EFBAEB307C1C79E0052D697 = 6EFBAEB307C1C79E0052D697;
+                       6EFBAEE707C1CBD40052D697 = 6EFBAEE707C1CBD40052D697;
+                       6EFBAF1007C1D0D90052D697 = 6EFBAF1007C1D0D90052D697;
+                       6EFBAF1207C1D0D90052D697 = 6EFBAF1207C1D0D90052D697;
+                       6EFBAF3A07C1D5950052D697 = 6EFBAF3A07C1D5950052D697;
+                       6EFBAF4907C1D6440052D697 = 6EFBAF4907C1D6440052D697;
+                       6EFBAF6E07C1D81C0052D697 = 6EFBAF6E07C1D81C0052D697;
+                       6EFBAF8007C1D8E80052D697 = 6EFBAF8007C1D8E80052D697;
+                       6EFBB01907C295BB0052D697 = 6EFBB01907C295BB0052D697;
+                       6EFBB03107C297D00052D697 = 6EFBB03107C297D00052D697;
+                       6EFBB04707C298530052D697 = 6EFBB04707C298530052D697;
+                       6EFBB1FC07C2D1A30052D697 = 6EFBB1FC07C2D1A30052D697;
+                       6EFBB1FF07C2D1A30052D697 = 6EFBB1FF07C2D1A30052D697;
+                       6EFBB20407C2D35A0052D697 = 6EFBB20407C2D35A0052D697;
+                       6EFBB20507C2D35A0052D697 = 6EFBB20507C2D35A0052D697;
+                       6EFBB20C07C2D35A0052D697 = 6EFBB20C07C2D35A0052D697;
+                       6EFBB20D07C2D35A0052D697 = 6EFBB20D07C2D35A0052D697;
+                       6EFBB24E07C2DBF90052D697 = 6EFBB24E07C2DBF90052D697;
+                       6EFBB27107C2DFA10052D697 = 6EFBB27107C2DFA10052D697;
+                       6EFBB28207C2E3940052D697 = 6EFBB28207C2E3940052D697;
+                       6EFBB2CC07C2EAE90052D697 = 6EFBB2CC07C2EAE90052D697;
+                       6EFBB3DB07C411B10052D697 = 6EFBB3DB07C411B10052D697;
+                       6EFBB40507C415970052D697 = 6EFBB40507C415970052D697;
+                       6EFBB46007C41FCA0052D697 = 6EFBB46007C41FCA0052D697;
+                       6EFBB46107C41FCA0052D697 = 6EFBB46107C41FCA0052D697;
+                       6EFE498707B7459800F67D2B = 6EFE498707B7459800F67D2B;
+                       6EFE49ED07B824F200F67D2B = 6EFE49ED07B824F200F67D2B;
+                       6EFE4B0307B8924D00F67D2B = 6EFE4B0307B8924D00F67D2B;
+                       6EFE4B0607B8924D00F67D2B = 6EFE4B0607B8924D00F67D2B;
+                       6EFE4B9107B9654300F67D2B = 6EFE4B9107B9654300F67D2B;
+                       6EFE4C0F07B9763800F67D2B = 6EFE4C0F07B9763800F67D2B;
+                       6EFE4C6D07B982E300F67D2B = 6EFE4C6D07B982E300F67D2B;
+                       6EFE4CC907B99A7C00F67D2B = 6EFE4CC907B99A7C00F67D2B;
+                       6EFE4CD407B99E0C00F67D2B = 6EFE4CD407B99E0C00F67D2B;
+                       6EFE4CD707B99E0C00F67D2B = 6EFE4CD707B99E0C00F67D2B;
+                       6EFE4DFF07B9D39B00F67D2B = 6EFE4DFF07B9D39B00F67D2B;
+                       6EFE4EAC07BABEBC00F67D2B = 6EFE4EAC07BABEBC00F67D2B;
+                       6EFE4EB407BABEBC00F67D2B = 6EFE4EB407BABEBC00F67D2B;
+                       6EFE4EC107BABF2500F67D2B = 6EFE4EC107BABF2500F67D2B;
+                       6EFE4F5807BB021400F67D2B = 6EFE4F5807BB021400F67D2B;
+                       6EFE4F6207BB021400F67D2B = 6EFE4F6207BB021400F67D2B;
+                       6EFE4F6C07BB021400F67D2B = 6EFE4F6C07BB021400F67D2B;
+                       6EFE4F7B07BB07E900F67D2B = 6EFE4F7B07BB07E900F67D2B;
+                       6EFE4F9D07BB2D7F00F67D2B = 6EFE4F9D07BB2D7F00F67D2B;
+                       6EFE4FD907BB33BA00F67D2B = 6EFE4FD907BB33BA00F67D2B;
+                       6EFE4FDA07BB33BA00F67D2B = 6EFE4FDA07BB33BA00F67D2B;
+                       6EFE4FDE07BB33BA00F67D2B = 6EFE4FDE07BB33BA00F67D2B;
+               };
+               sourceControlManager = 6ED806210641D21D002888F7;
+               userBuildSettings = {
+               };
+       };
+       32CA4F630368D1EE00C91783 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1003, 649}}";
+                       sepNavSelRange = "{149, 0}";
+                       sepNavVisRect = "{{0, 0}, {1003, 649}}";
+               };
+       };
+       6E10940606D4125F00E343E0 = {
+               fRef = 6ED8067A0641D41B002888F7;
+               isa = PBXTextBookmark;
+               name = "cheat_global.m: TCListenPortPref";
+               rLen = 0;
+               rLoc = 1753;
+               rType = 0;
+               vrLen = 1256;
+               vrLoc = 554;
+       };
+       6E10944406D4202100E343E0 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSProgressIndicator.h;
+               path = /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSProgressIndicator.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E10953F06D459A100E343E0 = {
+               fRef = 6E72B20E06AA5B0E00951D50;
+               isa = PBXTextBookmark;
+               name = "CheatData.m: 109";
+               rLen = 0;
+               rLoc = 3127;
+               rType = 0;
+               vrLen = 474;
+               vrLoc = 1752;
+       };
+       6E1095D506D463BB00E343E0 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = vm_types.h;
+               path = /usr/include/mach/vm_types.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E10960A06D4673700E343E0 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = vm_map.h;
+               path = /usr/include/mach/vm_map.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E12D3B80767AE3C00A95DFE = {
+               fRef = 6EDB009806D5282200DBD1D5;
+               isa = PBXTextBookmark;
+               name = "#define KERN_SUCCESS\t\t\t0\n";
+               rLen = 25;
+               rLoc = 2315;
+               rType = 0;
+               vrLen = 1146;
+               vrLoc = 4285;
+       };
+       6E12D4A0076A616E00A95DFE = {
+               fRef = 6E6FD69B0762B626004FD845;
+               isa = PBXTextBookmark;
+               name = "ThreadedTask.h: 130";
+               rLen = 0;
+               rLoc = 6520;
+               rType = 0;
+               vrLen = 1811;
+               vrLoc = 4296;
+       };
+       6E12D56F076A7C9500A95DFE = {
+               fRef = 6EAB44EB06CB378F00A4ABF0;
+               isa = PBXTextBookmark;
+               name = "= ";
+               rLen = 2;
+               rLoc = 981;
+               rType = 0;
+               vrLen = 1237;
+               vrLoc = 669;
+       };
+       6E12D5D7076ABBA600A95DFE = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSGeometry.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSGeometry.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E12D5D8076ABBB000A95DFE = {
+               fRef = 6E12D5D7076ABBA600A95DFE;
+               isa = PBXTextBookmark;
+               name = "FOUNDATION_STATIC_INLINE NSRect NSMakeRect(float x, float y, float w, float h) {\n";
+               rLen = 81;
+               rLoc = 1125;
+               rType = 0;
+               vrLen = 918;
+               vrLoc = 726;
+       };
+       6E12D5FD076AC55100A95DFE = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = stdio.h;
+               path = /usr/include/stdio.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E12D607076AC68300A95DFE = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = Sound.h;
+               path = /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/CarbonSound.framework/Versions/A/Headers/Sound.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E12D609076AC69000A95DFE = {
+               fRef = 6E12D607076AC68300A95DFE;
+               isa = PBXTextBookmark;
+               name = "Sound.h: 996";
+               rLen = 0;
+               rLoc = 46804;
+               rType = 0;
+               vrLen = 2818;
+               vrLoc = 45363;
+       };
+       6E12D651076ACBFA00A95DFE = {
+               fRef = 6E6FDCDB076592B8004FD845;
+               isa = PBXTextBookmark;
+               name = "- (BOOL)writeToFile:(NSString *)path;\t\n";
+               rLen = 39;
+               rLoc = 3397;
+               rType = 0;
+               vrLen = 1369;
+               vrLoc = 2445;
+       };
+       6E12D6B4076AFD5900A95DFE = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSTimer.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSTimer.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E138BF606C18765001C688F = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 756}}";
+                       sepNavSelRange = "{1435, 0}";
+                       sepNavVisRect = "{{0, 0}, {1018, 756}}";
+               };
+       };
+       6E138BF706C18765001C688F = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 3119}}";
+                       sepNavSelRange = "{2767, 29}";
+                       sepNavVisRect = "{{0, 1310}, {1018, 756}}";
+               };
+       };
+       6E138C3006C1C140001C688F = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1017, 655}}";
+                       sepNavSelRange = "{865, 0}";
+                       sepNavVisRect = "{{0, 0}, {1017, 617}}";
+               };
+       };
+       6E138C3106C1C140001C688F = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 2127}}";
+                       sepNavSelRange = "{1865, 47}";
+                       sepNavVisRect = "{{0, 964}, {1018, 649}}";
+               };
+       };
+       6E138D3C06C22416001C688F = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSCoder.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSCoder.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E138D8906C308C0001C688F = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSObject.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSObject.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E31A14306B71EBA00E40AB3 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 1072}}";
+                       sepNavSelRange = "{1097, 0}";
+                       sepNavVisRect = "{{0, 272}, {1018, 649}}";
+               };
+       };
+       6E31A14406B71EBA00E40AB3 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1014, 7551}}";
+                       sepNavSelRange = "{3683, 0}";
+                       sepNavVisRect = "{{0, 1763}, {991, 678}}";
+               };
+       };
+       6E31A16B06B723CB00E40AB3 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 1103}}";
+                       sepNavSelRange = "{1065, 10}";
+                       sepNavVisRect = "{{0, 310}, {1018, 756}}";
+               };
+       };
+       6E31A16C06B723CB00E40AB3 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 12063}}";
+                       sepNavSelRange = "{17666, 0}";
+                       sepNavVisRect = "{{0, 9996}, {1018, 756}}";
+               };
+       };
+       6E31A1B806B7286300E40AB3 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 671}}";
+                       sepNavSelRange = "{1113, 0}";
+                       sepNavVisRect = "{{0, 12}, {1018, 649}}";
+                       sepNavWindowFrame = "{{38, 354}, {750, 558}}";
+               };
+       };
+       6E31A1B906B7286300E40AB3 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 6031}}";
+                       sepNavSelRange = "{2035, 0}";
+                       sepNavVisRect = "{{0, 801}, {1018, 756}}";
+               };
+       };
+       6E38D32F06C99E71003BA9B4 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSRange.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSRange.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E38D3BD06C9B16B003BA9B4 = {
+               fRef = 6E98A54C06A740EE006A576D;
+               isa = PBXBookmark;
+       };
+       6E38D3FD06C9B71F003BA9B4 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {991, 911}}";
+                       sepNavSelRange = "{1676, 60}";
+                       sepNavVisRect = "{{0, 217}, {991, 678}}";
+               };
+       };
+       6E38D3FE06C9B71F003BA9B4 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {991, 3967}}";
+                       sepNavSelRange = "{4844, 0}";
+                       sepNavVisRect = "{{0, 2154}, {991, 678}}";
+               };
+       };
+       6E38D41106C9BA2D003BA9B4 = {
+               fRef = 6E38D3FD06C9B71F003BA9B4;
+               isa = PBXTextBookmark;
+               name = "DeleteTableView.h: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 217;
+               vrLoc = 0;
+       };
+       6E38D41206C9BA2D003BA9B4 = {
+               fRef = 6E138C3106C1C140001C688F;
+               isa = PBXTextBookmark;
+               name = "StatusTextField.m: 83";
+               rLen = 0;
+               rLoc = 2278;
+               rType = 0;
+               vrLen = 959;
+               vrLoc = 1028;
+       };
+       6E38D41406C9BA2D003BA9B4 = {
+               fRef = 6ED806710641D3CC002888F7;
+               isa = PBXTextBookmark;
+               name = "@interface NSMenu (MenuExtras)";
+               rLen = 32;
+               rLoc = 893;
+               rType = 0;
+               vrLen = 631;
+               vrLoc = 0;
+       };
+       6E38D41706C9BA2D003BA9B4 = {
+               fRef = 6ED806720641D3CC002888F7;
+               isa = PBXTextBookmark;
+               name = removeItemWithRepresentedObject;
+               rLen = 31;
+               rLoc = 1617;
+               rType = 0;
+               vrLen = 799;
+               vrLoc = 0;
+       };
+       6E38D41F06C9BB6A003BA9B4 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSXMLParser.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSXMLParser.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E38D42406C9BBA9003BA9B4 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSTableView.h;
+               path = /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSTableView.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E38D42606C9BC4D003BA9B4 = {
+               fRef = 6E38D41F06C9BB6A003BA9B4;
+               isa = PBXTextBookmark;
+               name = "    id _delegate;\n";
+               rLen = 18;
+               rLoc = 291;
+               rType = 0;
+               vrLen = 1322;
+               vrLoc = 0;
+       };
+       6E38D42C06C9BC4D003BA9B4 = {
+               fRef = 6E38D42406C9BBA9003BA9B4;
+               isa = PBXTextBookmark;
+               name = "@interface NSObject(NSTableViewDelegate)\n\n- (void)tableView:(NSTableView *)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(int)row;\n- (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(NSTableColumn *)tableColumn row:(int)row;\n- (BOOL)selectionShouldChangeInTableView:(NSTableView *)aTableView;\n- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(int)row;\n- (BOOL)tableView:(NSTableView *)tableView shouldSelectTableColumn:(NSTableColumn *)tableColumn;\n\n- (void) tableView:(NSTableView*)tableView mouseDownInHeaderOfTableColumn:(NSTableColumn *)tableColumn;\n- (void) tableView:(NSTableView*)tableView didClickTableColumn:(NSTableColumn *)tableColumn;\n- (void) tableView:(NSTableView*)tableView didDragTableColumn:(NSTableColumn *)tableColumn;\n\n@end";
+               rLen = 805;
+               rLoc = 11641;
+               rType = 0;
+               vrLen = 1524;
+               vrLoc = 11112;
+       };
+       6E38D4E506C9D6F7003BA9B4 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSArray.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSArray.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E38D56B06C9E302003BA9B4 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSScanner.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSScanner.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E38D61706C9F7A8003BA9B4 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 2367}}";
+                       sepNavSelRange = "{2375, 0}";
+                       sepNavVisRect = "{{0, 979}, {1018, 756}}";
+                       sepNavWindowFrame = "{{15, 375}, {750, 558}}";
+               };
+       };
+       6E38D61806C9F7A8003BA9B4 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 3727}}";
+                       sepNavSelRange = "{1647, 0}";
+                       sepNavVisRect = "{{0, 1822}, {1018, 756}}";
+               };
+       };
+       6E38D62906C9F7CD003BA9B4 = {
+               fRef = 6E138D3C06C22416001C688F;
+               isa = PBXTextBookmark;
+               name = "@interface NSCoder : NSObject\n";
+               rLen = 30;
+               rLoc = 135;
+               rType = 0;
+               vrLen = 1243;
+               vrLoc = 0;
+       };
+       6E38D68906C9FA18003BA9B4 = {
+               fRef = 6E31A1B806B7286300E40AB3;
+               isa = PBXTextBookmark;
+               name = "RemoteCheater.h: 11";
+               rLen = 0;
+               rLoc = 922;
+               rType = 0;
+               vrLen = 245;
+               vrLoc = 0;
+       };
+       6E3D7D1906C445A000A73B29 = {
+               fRef = 6E72B20D06AA5B0E00951D50;
+               isa = PBXTextBookmark;
+               name = "CheatData.h: initWithCoder:";
+               rLen = 0;
+               rLoc = 1341;
+               rType = 0;
+               vrLen = 1081;
+               vrLoc = 36;
+       };
+       6E3D7D3506C4498500A73B29 = {
+               fRef = 6ED806790641D41B002888F7;
+               isa = PBXTextBookmark;
+               name = "cheat_global.h: 42";
+               rLen = 0;
+               rLoc = 1965;
+               rType = 0;
+               vrLen = 734;
+               vrLoc = 558;
+       };
+       6E3D7D3C06C44CFE00A73B29 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 1503}}";
+                       sepNavSelRange = "{2534, 11}";
+                       sepNavVisRect = "{{0, 826}, {1018, 677}}";
+               };
+       };
+       6E3D7D3D06C44CFE00A73B29 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {990, 5743}}";
+                       sepNavSelRange = "{7413, 0}";
+                       sepNavVisRect = "{{0, 2929}, {990, 678}}";
+               };
+       };
+       6E3DC5E3077CE2B7004C82C0 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = types.h;
+               path = /usr/include/sys/types.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E3DC5E4077CE2C1004C82C0 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = vm_types.h;
+               path = /usr/include/mach/ppc/vm_types.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E3DC5E6077CE2CA004C82C0 = {
+               fRef = 6E3DC5E4077CE2C1004C82C0;
+               isa = PBXTextBookmark;
+               name = "typedef unsigned int\tnatural_t;\n";
+               rLen = 32;
+               rLoc = 2600;
+               rType = 0;
+               vrLen = 927;
+               vrLoc = 2361;
+       };
+       6E3DC5F3077CE552004C82C0 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSDictionary.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSDictionary.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E63977106434C0800BD3765 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSObjCRuntime.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSObjCRuntime.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E63977506434C0800BD3765 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = MacTypes.h;
+               path = /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/Headers/MacTypes.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E6B645507120022002B77D9 = {
+               fRef = 6ED806310641D2E9002888F7;
+               isa = PBXTextBookmark;
+               name = "AppController.h: newBlankCheatWindow:";
+               rLen = 0;
+               rLoc = 1340;
+               rType = 0;
+               vrLen = 905;
+               vrLoc = 106;
+       };
+       6E6B64AA071202FF002B77D9 = {
+               fRef = 6ED8062F0641D2E9002888F7;
+               isa = PBXTextBookmark;
+               name = "AboutBoxController.h: 19";
+               rLen = 0;
+               rLoc = 865;
+               rType = 0;
+               vrLen = 1253;
+               vrLoc = 0;
+       };
+       6E6B64AE071202FF002B77D9 = {
+               fRef = 6ED806350641D2E9002888F7;
+               isa = PBXTextBookmark;
+               name = "PreferenceController.h: 19";
+               rLen = 0;
+               rLoc = 865;
+               rType = 0;
+               vrLen = 1285;
+               vrLoc = 0;
+       };
+       6E6B64AF071202FF002B77D9 = {
+               fRef = 6ED806360641D2E9002888F7;
+               isa = PBXTextBookmark;
+               name = "PreferenceController.m: 19";
+               rLen = 0;
+               rLoc = 865;
+               rType = 0;
+               vrLen = 1296;
+               vrLoc = 0;
+       };
+       6E6B64B0071202FF002B77D9 = {
+               fRef = 6ED8072006421B05002888F7;
+               isa = PBXTextBookmark;
+               name = "GeneralPrefs.h: 19";
+               rLen = 0;
+               rLoc = 865;
+               rType = 0;
+               vrLen = 1182;
+               vrLoc = 0;
+       };
+       6E6B64B4071202FF002B77D9 = {
+               fRef = 6ED8072606421B10002888F7;
+               isa = PBXTextBookmark;
+               name = "ServerPrefs.h: 19";
+               rLen = 0;
+               rLoc = 865;
+               rType = 0;
+               vrLen = 1255;
+               vrLoc = 0;
+       };
+       6E6B64C6071202FF002B77D9 = {
+               fRef = 6ED97B9D0645E85700CBF037;
+               isa = PBXTextBookmark;
+               name = "CheatServer.h: 19";
+               rLen = 0;
+               rLoc = 865;
+               rType = 0;
+               vrLen = 1158;
+               vrLoc = 0;
+       };
+       6E6B64C8071202FF002B77D9 = {
+               fRef = 6E31A14306B71EBA00E40AB3;
+               isa = PBXTextBookmark;
+               name = "ServerChild.h: 19";
+               rLen = 0;
+               rLoc = 865;
+               rType = 0;
+               vrLen = 1010;
+               vrLoc = 0;
+       };
+       6E6B64E3071202FF002B77D9 = {
+               fRef = 32CA4F630368D1EE00C91783;
+               isa = PBXTextBookmark;
+               name = "The_Cheat_Prefix.pch: 8";
+               rLen = 0;
+               rLoc = 149;
+               rType = 0;
+               vrLen = 149;
+               vrLoc = 0;
+       };
+       6E6B652A07120A52002B77D9 = {
+               fRef = 6E38D61706C9F7A8003BA9B4;
+               isa = PBXTextBookmark;
+               name = "Cheater.h: TCLessThanOrEqual";
+               rLen = 0;
+               rLoc = 1266;
+               rType = 0;
+               vrLen = 701;
+               vrLoc = 867;
+       };
+       6E6FD69B0762B626004FD845 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 3983}}";
+                       sepNavSelRange = "{2045, 0}";
+                       sepNavVisRect = "{{0, 503}, {1018, 649}}";
+               };
+       };
+       6E6FD69C0762B626004FD845 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1021, 6351}}";
+                       sepNavSelRange = "{4939, 0}";
+                       sepNavVisRect = "{{0, 2533}, {850, 743}}";
+               };
+       };
+       6E6FD6B10762B965004FD845 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {990, 1439}}";
+                       sepNavSelRange = "{806, 0}";
+                       sepNavVisRect = "{{0, 139}, {990, 678}}";
+               };
+       };
+       6E6FD6B20762B965004FD845 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {990, 4735}}";
+                       sepNavSelRange = "{2723, 0}";
+                       sepNavVisRect = "{{0, 1245}, {990, 678}}";
+               };
+       };
+       6E6FD6CC0762C1BB004FD845 = {
+               fRef = 32CA4F630368D1EE00C91783;
+               isa = PBXTextBookmark;
+               name = "The_Cheat_Prefix.pch: 8";
+               rLen = 0;
+               rLoc = 149;
+               rType = 0;
+               vrLen = 149;
+               vrLoc = 0;
+       };
+       6E6FD7750762D0B4004FD845 = {
+               fRef = 6E6FD7760762D0B4004FD845;
+               isa = PBXTextBookmark;
+               name = "(null): 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 979;
+               vrLoc = 1879;
+       };
+       6E6FD7760762D0B4004FD845 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = mach_traps.h;
+               path = /usr/include/mach/mach_traps.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E6FD7840762D0F3004FD845 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = signal.h;
+               path = /usr/include/signal.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E6FD78C0762D118004FD845 = {
+               fRef = 6E6FD7840762D0F3004FD845;
+               isa = PBXTextBookmark;
+               name = "signal.h: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 1365;
+               vrLoc = 3026;
+       };
+       6E6FD78E0762D118004FD845 = {
+               fRef = 6E6FD7840762D0F3004FD845;
+               isa = PBXTextBookmark;
+               name = "signal.h: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 1365;
+               vrLoc = 3026;
+       };
+       6E6FD79C0762D15B004FD845 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = vm_region.h;
+               path = /usr/include/mach/vm_region.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E6FD7AB0762D38D004FD845 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = vm_prot.h;
+               path = /usr/include/mach/vm_prot.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E6FD7AF0762D466004FD845 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = unistd.h;
+               path = /usr/include/unistd.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E6FD7B30762D466004FD845 = {
+               fRef = 6E6FD7AB0762D38D004FD845;
+               isa = PBXTextBookmark;
+               name = "typedef int\t\tvm_prot_t;\n";
+               rLen = 24;
+               rLoc = 2256;
+               rType = 0;
+               vrLen = 1330;
+               vrLoc = 2655;
+       };
+       6E6FD7BA0762D466004FD845 = {
+               fRef = 6E6FD7AB0762D38D004FD845;
+               isa = PBXTextBookmark;
+               name = "typedef int\t\tvm_prot_t;\n";
+               rLen = 24;
+               rLoc = 2256;
+               rType = 0;
+               vrLen = 1330;
+               vrLoc = 2655;
+       };
+       6E6FD7C60762D7FC004FD845 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSData.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSData.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E6FD9750764E3A3004FD845 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSView.h;
+               path = /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSView.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E6FD9BA0764E7BC004FD845 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSBitmapImageRep.h;
+               path = /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSBitmapImageRep.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E6FD9BB0764E81F004FD845 = {
+               fRef = 6E6FD9BA0764E7BC004FD845;
+               isa = PBXTextBookmark;
+               name = "@interface NSBitmapImageRep : NSImageRep {\n";
+               rLen = 43;
+               rLoc = 2569;
+               rType = 0;
+               vrLen = 2002;
+               vrLoc = 3192;
+       };
+       6E6FD9FE0764EDE4004FD845 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {988, 736}}";
+                       sepNavSelRange = "{424, 15}";
+                       sepNavVisRect = "{{0, 32}, {988, 649}}";
+               };
+       };
+       6E6FD9FF0764EDE4004FD845 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1070, 2335}}";
+                       sepNavSelRange = "{1061, 48}";
+                       sepNavVisRect = "{{0, 996}, {1017, 617}}";
+               };
+       };
+       6E6FDA050764F415004FD845 = {
+               fRef = 6E6FD9750764E3A3004FD845;
+               isa = PBXTextBookmark;
+               name = "- (void)removeFromSuperview;\n";
+               rLen = 29;
+               rLoc = 4435;
+               rType = 0;
+               vrLen = 1507;
+               vrLoc = 3424;
+       };
+       6E6FDA0A0764F415004FD845 = {
+               fRef = 6E6FD9FF0764EDE4004FD845;
+               isa = PBXTextBookmark;
+               name = "FadeView.m: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 405;
+               vrLoc = 0;
+       };
+       6E6FDAAD0764F8DD004FD845 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSDate.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSDate.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E6FDAB70764F9FB004FD845 = {
+               fRef = 6E6FD9FE0764EDE4004FD845;
+               isa = PBXTextBookmark;
+               name = "FadeView.h: fadeDuration";
+               rLen = 0;
+               rLoc = 377;
+               rType = 0;
+               vrLen = 761;
+               vrLoc = 18;
+       };
+       6E6FDAFD0764FD0D004FD845 = {
+               fRef = 6EDB02FE06D8156400DBD1D5;
+               isa = PBXTextBookmark;
+               name = "- (void)addTimer:(NSTimer *)timer forMode:(NSString *)mode;\n";
+               rLen = 60;
+               rLoc = 531;
+               rType = 0;
+               vrLen = 1324;
+               vrLoc = 650;
+       };
+       6E6FDB1A0764FFD9004FD845 = {
+               fRef = 6E6FD9FE0764EDE4004FD845;
+               isa = PBXTextBookmark;
+               name = "- (double)alpha";
+               rLen = 15;
+               rLoc = 424;
+               rType = 0;
+               vrLen = 714;
+               vrLoc = 18;
+       };
+       6E6FDC240765858A004FD845 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1017, 649}}";
+                       sepNavSelRange = "{342, 0}";
+                       sepNavVisRect = "{{0, 0}, {1017, 649}}";
+               };
+       };
+       6E6FDC250765858A004FD845 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {991, 678}}";
+                       sepNavSelRange = "{420, 0}";
+                       sepNavVisRect = "{{0, 0}, {991, 678}}";
+               };
+       };
+       6E6FDC4E07658970004FD845 = {
+               fRef = 6E6FDC240765858A004FD845;
+               isa = PBXTextBookmark;
+               name = "DumpContext.h: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 209;
+               vrLoc = 0;
+       };
+       6E6FDC5307658970004FD845 = {
+               fRef = 6E6FDC250765858A004FD845;
+               isa = PBXTextBookmark;
+               name = "- (id)initWithPID:(pid_t)pid";
+               rLen = 28;
+               rLoc = 194;
+               rType = 0;
+               vrLen = 490;
+               vrLoc = 0;
+       };
+       6E6FDCDB076592B8004FD845 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSColorList.h;
+               path = /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSColorList.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E6FDDB50766A1F4004FD845 = {
+               fRef = 6E6FD79C0762D15B004FD845;
+               isa = PBXTextBookmark;
+               name = "vm_region.h: 133";
+               rLen = 0;
+               rLoc = 3880;
+               rType = 0;
+               vrLen = 1648;
+               vrLoc = 3548;
+       };
+       6E72B20D06AA5B0E00951D50 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 1407}}";
+                       sepNavSelRange = "{2617, 32}";
+                       sepNavVisRect = "{{0, 707}, {1018, 678}}";
+               };
+       };
+       6E72B20E06AA5B0E00951D50 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 3999}}";
+                       sepNavSelRange = "{668, 0}";
+                       sepNavVisRect = "{{0, 95}, {1018, 678}}";
+               };
+       };
+       6E7614A206A47A790051C301 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {991, 4047}}";
+                       sepNavSelRange = "{1327, 17}";
+                       sepNavVisRect = "{{0, 405}, {991, 678}}";
+               };
+       };
+       6E7614A306A47A790051C301 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1364, 20607}}";
+                       sepNavSelRange = "{24195, 0}";
+                       sepNavVisRect = "{{0, 13286}, {991, 678}}";
+               };
+       };
+       6E818179076E3D1000A5FBEB = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSScriptWhoseTests.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSScriptWhoseTests.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E81817A076E3D6800A5FBEB = {
+               fRef = 6E818179076E3D1000A5FBEB;
+               isa = PBXTextBookmark;
+               name = "- (BOOL)isEqualTo:(id)object;\n";
+               rLen = 30;
+               rLoc = 1513;
+               rType = 0;
+               vrLen = 1739;
+               vrLoc = 799;
+       };
+       6E818184076E3F8C00A5FBEB = {
+               fRef = 6E138BF706C18765001C688F;
+               isa = PBXTextBookmark;
+               name = "Process.m: 99";
+               rLen = 0;
+               rLoc = 3106;
+               rType = 0;
+               vrLen = 847;
+               vrLoc = 1833;
+       };
+       6E8181D1076E475200A5FBEB = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 1231}}";
+                       sepNavSelRange = "{910, 15}";
+                       sepNavVisRect = "{{0, 494}, {1018, 678}}";
+               };
+       };
+       6E8181D2076E475200A5FBEB = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 3903}}";
+                       sepNavSelRange = "{3536, 22}";
+                       sepNavVisRect = "{{0, 3045}, {1018, 678}}";
+               };
+       };
+       6E83F2AF07B0059D00D9DACB = {
+               fRef = 6EAB446406CAEFE900A4ABF0;
+               isa = PBXTextBookmark;
+               name = "- (void)removeObserver:(id)observer;\n";
+               rLen = 37;
+               rLoc = 1120;
+               rType = 0;
+               vrLen = 1128;
+               vrLoc = 116;
+       };
+       6E83F2ED07B00A5100D9DACB = {
+               fRef = 6EA2533707861AC000C839D1;
+               isa = PBXTextBookmark;
+               name = "- (void)setInteger:(int)value forKey:(NSString *)defaultName;\n";
+               rLen = 62;
+               rLoc = 1220;
+               rType = 0;
+               vrLen = 1325;
+               vrLoc = 79;
+       };
+       6E83F2F607B00A5100D9DACB = {
+               fRef = 6EA2533707861AC000C839D1;
+               isa = PBXTextBookmark;
+               name = "- (void)setInteger:(int)value forKey:(NSString *)defaultName;\n";
+               rLen = 62;
+               rLoc = 1220;
+               rType = 0;
+               vrLen = 1325;
+               vrLoc = 79;
+       };
+       6E83F3E107B0358C00D9DACB = {
+               fRef = 6ED806710641D3CC002888F7;
+               isa = PBXTextBookmark;
+               name = removeAllItems;
+               rLen = 14;
+               rLoc = 1122;
+               rType = 0;
+               vrLen = 1193;
+               vrLoc = 0;
+       };
+       6E83F3F107B0398700D9DACB = {
+               fRef = 6EA399A1077FB486002B0E69;
+               isa = PBXTextBookmark;
+               name = "- (int)indexOfItemWithRepresentedObject:(id)obj;\n";
+               rLen = 49;
+               rLoc = 1633;
+               rType = 0;
+               vrLen = 1165;
+               vrLoc = 1137;
+       };
+       6E83F3F207B0398700D9DACB = {
+               fRef = 6EDB002B06D518FB00DBD1D5;
+               isa = PBXTextBookmark;
+               name = "APPKIT_EXTERN void NSBeginInformationalAlertSheet(NSString *title, NSString *defaultButton, NSString *alternateButton, NSString *otherButton, NSWindow *docWindow, id modalDelegate, SEL didEndSelector, SEL didDismissSelector, void *contextInfo, NSString *msg, ...);\n";
+               rLen = 265;
+               rLoc = 2369;
+               rType = 0;
+               vrLen = 2895;
+               vrLoc = 0;
+       };
+       6E83F53007B048BD00D9DACB = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 2032}}";
+                       sepNavSelRange = "{3281, 0}";
+                       sepNavVisRect = "{{0, 1383}, {1018, 649}}";
+               };
+       };
+       6E83F53107B048BD00D9DACB = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {993, 17711}}";
+                       sepNavSelRange = "{3311, 0}";
+                       sepNavVisRect = "{{0, 2351}, {846, 595}}";
+               };
+       };
+       6E83F5BB07B376DB00D9DACB = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = time_value.h;
+               path = /usr/include/mach/time_value.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E83F5BC07B3771F00D9DACB = {
+               fRef = 6E83F5BB07B376DB00D9DACB;
+               isa = PBXTextBookmark;
+               name = "\tinteger_t seconds;\n";
+               rLen = 20;
+               rLoc = 3254;
+               rType = 0;
+               vrLen = 964;
+               vrLoc = 2447;
+       };
+       6E83F62507B548C400D9DACB = {
+               fRef = 6ED806320641D2E9002888F7;
+               isa = PBXTextBookmark;
+               name = "AppController.m: 60";
+               rLen = 0;
+               rLoc = 2837;
+               rType = 0;
+               vrLen = 1474;
+               vrLoc = 1624;
+       };
+       6E8B669307A2E6D7002A6BAF = {
+               fRef = 6EC06557078BE68300591D61;
+               isa = PBXTextBookmark;
+               name = "ChazUpdate.m: 219";
+               rLen = 0;
+               rLoc = 5491;
+               rType = 0;
+               vrLen = 986;
+               vrLoc = 5023;
+       };
+       6E8B6D0E07A74D66002A6BAF = {
+               fRef = 6EAB490C06CC4FEA00A4ABF0;
+               isa = PBXTextBookmark;
+               name = "#pragma mark -\n#pragma mark VMRegion Functions\n/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/";
+               rLen = 91;
+               rLoc = 2386;
+               rType = 0;
+               vrLen = 989;
+               vrLoc = 2114;
+       };
+       6E9BF25307812D58008F0139 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = stdlib.h;
+               path = /usr/include/stdlib.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E9BF31F0781EEC3008F0139 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1017, 617}}";
+                       sepNavSelRange = "{336, 124}";
+                       sepNavVisRect = "{{0, 0}, {1017, 617}}";
+               };
+       };
+       6E9BF3200781EEC3008F0139 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {888, 649}}";
+                       sepNavSelRange = "{632, 0}";
+                       sepNavVisRect = "{{0, 0}, {888, 649}}";
+               };
+       };
+       6E9BF3230781F113008F0139 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSScrollView.h;
+               path = /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSScrollView.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E9BF3290781F17A008F0139 = {
+               fRef = 6E9BF3230781F113008F0139;
+               isa = PBXTextBookmark;
+               name = "- (NSScroller *)verticalScroller;\n";
+               rLen = 34;
+               rLoc = 3099;
+               rType = 0;
+               vrLen = 1423;
+               vrLoc = 2419;
+       };
+       6E9BF32F0781F17A008F0139 = {
+               fRef = 6E9BF31F0781EEC3008F0139;
+               isa = PBXTextBookmark;
+               name = "VarTableScroller.h: 12";
+               rLen = 0;
+               rLoc = 210;
+               rType = 0;
+               vrLen = 222;
+               vrLoc = 0;
+       };
+       6E9BF3300781F17A008F0139 = {
+               fRef = 6E9BF3200781EEC3008F0139;
+               isa = PBXTextBookmark;
+               name = "VarTableScroller.m: 18";
+               rLen = 0;
+               rLoc = 306;
+               rType = 0;
+               vrLen = 344;
+               vrLoc = 0;
+       };
+       6E9BF3BA07820415008F0139 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {990, 678}}";
+                       sepNavSelRange = "{387, 0}";
+                       sepNavVisRect = "{{0, 0}, {990, 678}}";
+               };
+       };
+       6E9BF3BB07820415008F0139 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 2127}}";
+                       sepNavSelRange = "{1404, 0}";
+                       sepNavVisRect = "{{0, 210}, {1018, 677}}";
+               };
+       };
+       6E9BF3C60782053A008F0139 = {
+               fRef = 6E9BF3BA07820415008F0139;
+               isa = PBXTextBookmark;
+               name = "VariableTable.h: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 214;
+               vrLoc = 0;
+       };
+       6E9BF4B0078287DF008F0139 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 1391}}";
+                       sepNavSelRange = "{359, 0}";
+                       sepNavVisRect = "{{0, 0}, {1018, 756}}";
+               };
+       };
+       6E9BF4B1078287DF008F0139 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1091, 11535}}";
+                       sepNavSelRange = "{16483, 0}";
+                       sepNavVisRect = "{{0, 7946}, {990, 678}}";
+               };
+       };
+       6E9BF4CB07828C86008F0139 = {
+               fRef = 6E9BF4B0078287DF008F0139;
+               isa = PBXTextBookmark;
+               name = "Searching.h: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 206;
+               vrLoc = 0;
+       };
+       6E9BF5030782926E008F0139 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 1167}}";
+                       sepNavSelRange = "{521, 75}";
+                       sepNavVisRect = "{{0, 0}, {1018, 677}}";
+               };
+       };
+       6E9BF5E607836C01008F0139 = {
+               fRef = 6E1095D506D463BB00E343E0;
+               isa = PBXTextBookmark;
+               name = "typedef vm_offset_t     \tvm_address_t;\n";
+               rLen = 39;
+               rLoc = 1166;
+               rType = 0;
+               vrLen = 1377;
+               vrLoc = 0;
+       };
+       6E9BF63407836C01008F0139 = {
+               fRef = 6EAB490B06CC4FEA00A4ABF0;
+               isa = PBXTextBookmark;
+               name = "VMRegion.h: 121";
+               rLen = 0;
+               rLoc = 4902;
+               rType = 0;
+               vrLen = 811;
+               vrLoc = 3095;
+       };
+       6E9BF6CB07838C56008F0139 = {
+               fRef = 6E6FD6B10762B965004FD845;
+               isa = PBXTextBookmark;
+               name = "SearchContext.h: _value";
+               rLen = 0;
+               rLoc = 669;
+               rType = 0;
+               vrLen = 1199;
+               vrLoc = 258;
+       };
+       6E9BF6FD078394E7008F0139 = {
+               fRef = 6E10960A06D4673700E343E0;
+               isa = PBXTextBookmark;
+               name = "kern_return_t vm_read_overwrite\n";
+               rLen = 32;
+               rLoc = 3143;
+               rType = 0;
+               vrLen = 669;
+               vrLoc = 2820;
+       };
+       6E9BF708078394E7008F0139 = {
+               fRef = 6EAB490C06CC4FEA00A4ABF0;
+               isa = PBXTextBookmark;
+               name = "VMRegion.m: 232";
+               rLen = 0;
+               rLoc = 6276;
+               rType = 0;
+               vrLen = 1043;
+               vrLoc = 5615;
+       };
+       6E9BF84D0783CE0C008F0139 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = types.h;
+               path = /usr/include/ppc/types.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E9BF84E0783CE4E008F0139 = {
+               fRef = 6E9BF84D0783CE0C008F0139;
+               isa = PBXTextBookmark;
+               name = "typedef\tint\t\t\tint32_t;\n";
+               rLen = 23;
+               rLoc = 3197;
+               rType = 0;
+               vrLen = 2236;
+               vrLoc = 597;
+       };
+       6E9BFAF90784CA06008F0139 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSMatrix.h;
+               path = /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSMatrix.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E9BFAFC0784CAF5008F0139 = {
+               fRef = 6E9BFAF90784CA06008F0139;
+               isa = PBXTextBookmark;
+               name = "- (id)cellWithTag:(int)anInt;\n";
+               rLen = 30;
+               rLoc = 5968;
+               rType = 0;
+               vrLen = 1591;
+               vrLoc = 5077;
+       };
+       6E9BFC330784D9EC008F0139 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSColor.h;
+               path = /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSColor.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6E9BFC340784DA01008F0139 = {
+               fRef = 6E9BFC330784D9EC008F0139;
+               isa = PBXTextBookmark;
+               name = colorWithCalibratedRed;
+               rLen = 22;
+               rLoc = 2942;
+               rType = 0;
+               vrLen = 1682;
+               vrLoc = 2380;
+       };
+       6E9BFC4C0784DDCF008F0139 = {
+               fRef = 6EA3969B077F419A002B0E69;
+               isa = PBXTextBookmark;
+               name = "[ibSearchVariableTable setToolTip:[NSString stringWithFormat:@\"Displaying %i of %i results.\", TCArrayElementCount( variables ), count]];";
+               rLen = 0;
+               rLoc = 4762;
+               rType = 0;
+               vrLen = 1502;
+               vrLoc = 3901;
+       };
+       6EA251D80785EEBB00C839D1 = {
+               fRef = 6EAB490B06CC4FEA00A4ABF0;
+               isa = PBXTextBookmark;
+               name = "VMREGION_STATIC_INLINE BOOL VMRegionBytes( VMRegion region, void *bytes, vm_size_t *size )\n";
+               rLen = 91;
+               rLoc = 5383;
+               rType = 0;
+               vrLen = 1049;
+               vrLoc = 4889;
+       };
+       6EA252220785FE0700C839D1 = {
+               fRef = 6E6FDC240765858A004FD845;
+               isa = PBXTextBookmark;
+               name = "DumpContext.h: lastRegion";
+               rLen = 0;
+               rLoc = 342;
+               rType = 0;
+               vrLen = 437;
+               vrLoc = 0;
+       };
+       6EA252AC078606DA00C839D1 = {
+               fRef = 6E9BF3BB07820415008F0139;
+               isa = PBXTextBookmark;
+               name = "VariableTable.m: 64";
+               rLen = 0;
+               rLoc = 1436;
+               rType = 0;
+               vrLen = 1066;
+               vrLoc = 1145;
+       };
+       6EA2533707861AC000C839D1 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSUserDefaults.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSUserDefaults.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EA253F60786249800C839D1 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1017, 816}}";
+                       sepNavSelRange = "{998, 0}";
+                       sepNavVisRect = "{{0, 199}, {1017, 617}}";
+               };
+       };
+       6EA253F70786249800C839D1 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 2495}}";
+                       sepNavSelRange = "{522, 22}";
+                       sepNavVisRect = "{{0, 212}, {1018, 649}}";
+               };
+       };
+       6EA254210786265900C839D1 = {
+               fRef = 6EA253F60786249800C839D1;
+               isa = PBXTextBookmark;
+               name = "ChazLog.h: 43";
+               rLen = 0;
+               rLoc = 998;
+               rType = 0;
+               vrLen = 909;
+               vrLoc = 167;
+       };
+       6EA254220786265900C839D1 = {
+               fRef = 6EA253F70786249800C839D1;
+               isa = PBXTextBookmark;
+               name = "ChazLog.m: 142";
+               rLen = 0;
+               rLoc = 2338;
+               rType = 0;
+               vrLen = 862;
+               vrLoc = 1825;
+       };
+       6EA2560007876BD300C839D1 = {
+               fRef = 6E31A16B06B723CB00E40AB3;
+               isa = PBXTextBookmark;
+               name = "LocalCheater.h: _savedResults";
+               rLen = 0;
+               rLoc = 1243;
+               rType = 0;
+               vrLen = 704;
+               vrLoc = 665;
+       };
+       6EA2573B0787D3B000C839D1 = {
+               fRef = 6E6FD9FF0764EDE4004FD845;
+               isa = PBXTextBookmark;
+               name = "- (void)setFadeDuration:(NSTimeInterval)seconds\n";
+               rLen = 48;
+               rLoc = 1061;
+               rType = 0;
+               vrLen = 500;
+               vrLoc = 859;
+       };
+       6EA257F60787E57B00C839D1 = {
+               fRef = 6E9BF31F0781EEC3008F0139;
+               isa = PBXTextBookmark;
+               name = "- (void)scrollerDidStartScrolling:(TrackerScroller *)scroller;\n- (void)scrollerDidStopScrolling:(TrackerScroller *)scroller;";
+               rLen = 124;
+               rLoc = 336;
+               rType = 0;
+               vrLen = 466;
+               vrLoc = 0;
+       };
+       6EA258560787F09200C839D1 = {
+               fRef = 6E138BF606C18765001C688F;
+               isa = PBXTextBookmark;
+               name = "Process.h: 24";
+               rLen = 0;
+               rLoc = 946;
+               rType = 0;
+               vrLen = 1025;
+               vrLoc = 552;
+       };
+       6EA258D50787FA1400C839D1 = {
+               fRef = 6ED806D00641D5F2002888F7;
+               isa = PBXTextBookmark;
+               name = "Info-The_Cheat.plist: 43";
+               rLen = 0;
+               rLoc = 1494;
+               rType = 0;
+               vrLen = 1123;
+               vrLoc = 0;
+       };
+       6EA258D80787FA1400C839D1 = {
+               fRef = 6ECDE0990643984400B1DD8A;
+               isa = PBXBookmark;
+       };
+       6EA258E20787FA3000C839D1 = {
+               fRef = 6E6FD8FA0764D1B0004FD845;
+               isa = PBXBookmark;
+       };
+       6EA25928078820C200C839D1 = {
+               fRef = 6E6FDAAD0764F8DD004FD845;
+               isa = PBXTextBookmark;
+               name = "- (NSDate *)laterDate:(NSDate *)anotherDate;\n";
+               rLen = 45;
+               rLoc = 589;
+               rType = 0;
+               vrLen = 850;
+               vrLoc = 0;
+       };
+       6EA39693077F4025002B0E69 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {993, 9791}}";
+                       sepNavSelRange = "{14657, 0}";
+                       sepNavVisRect = "{{0, 8741}, {991, 678}}";
+               };
+       };
+       6EA3969B077F419A002B0E69 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {990, 7119}}";
+                       sepNavSelRange = "{10554, 0}";
+                       sepNavVisRect = "{{0, 6096}, {990, 678}}";
+                       sepNavWindowFrame = "{{15, 375}, {750, 558}}";
+               };
+       };
+       6EA396C8077F4934002B0E69 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSApplication.h;
+               path = /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSApplication.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EA396C9077F4C2F002B0E69 = {
+               fRef = 6EDB024D06D5B74700DBD1D5;
+               isa = PBXTextBookmark;
+               name = "typedef struct objc_selector \t*SEL;    \n";
+               rLen = 40;
+               rLoc = 1275;
+               rType = 0;
+               vrLen = 1385;
+               vrLoc = 102;
+       };
+       6EA396CA077F4C2F002B0E69 = {
+               fRef = 6EA396C8077F4934002B0E69;
+               isa = PBXTextBookmark;
+               name = SEL;
+               rLen = 3;
+               rLoc = 4967;
+               rType = 0;
+               vrLen = 1946;
+               vrLoc = 4005;
+       };
+       6EA3971B077F7648002B0E69 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSCell.h;
+               path = /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSCell.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EA398C1077FA115002B0E69 = {
+               fRef = 6ED806720641D3CC002888F7;
+               isa = PBXTextBookmark;
+               name = "MenuExtras.m: 89";
+               rLen = 0;
+               rLoc = 1961;
+               rType = 0;
+               vrLen = 480;
+               vrLoc = 1801;
+       };
+       6EA39931077FAB48002B0E69 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = socket.h;
+               path = /usr/include/sys/socket.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EA39943077FAC55002B0E69 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = in.h;
+               path = /usr/include/netinet/in.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EA399A1077FB486002B0E69 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSPopUpButton.h;
+               path = /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSPopUpButton.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EA39A24077FCC3D002B0E69 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSMenuItem.h;
+               path = /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSMenuItem.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EA39A25077FCC63002B0E69 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSEvent.h;
+               path = /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSEvent.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EA39A27077FCC6D002B0E69 = {
+               fRef = 6EA39A24077FCC3D002B0E69;
+               isa = PBXTextBookmark;
+               name = setKeyEquivalent;
+               rLen = 16;
+               rLoc = 3922;
+               rType = 0;
+               vrLen = 1250;
+               vrLoc = 3667;
+       };
+       6EA39A28077FCC6D002B0E69 = {
+               fRef = 6EA39A25077FCC63002B0E69;
+               isa = PBXTextBookmark;
+               name = NSCommandKeyMask;
+               rLen = 16;
+               rLoc = 2124;
+               rType = 0;
+               vrLen = 1258;
+               vrLoc = 1384;
+       };
+       6EAB446406CAEFE900A4ABF0 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSNotification.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSNotification.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EAB446506CAF05D00A4ABF0 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = OpenTransportProtocol.h;
+               path = /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/OSServices.framework/Versions/A/Headers/OpenTransportProtocol.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EAB446A06CAF1B700A4ABF0 = {
+               fRef = 6EAB446506CAF05D00A4ABF0;
+               isa = PBXTextBookmark;
+               name = "  SInt32              ic_cmd;                 /* downstream command */\n";
+               rLen = 71;
+               rLoc = 34759;
+               rType = 0;
+               vrLen = 1289;
+               vrLoc = 34143;
+       };
+       6EAB447106CAF1B700A4ABF0 = {
+               fRef = 6E38D61806C9F7A8003BA9B4;
+               isa = PBXTextBookmark;
+               name = "Cheater.m: 72";
+               rLen = 0;
+               rLoc = 2609;
+               rType = 0;
+               vrLen = 1024;
+               vrLoc = 1296;
+       };
+       6EAB44EB06CB378F00A4ABF0 = {
+               fileEncoding = 4;
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.objc;
+               name = Conversions.m;
+               path = "/Users/chaz/The Cheat/The Cheat/Conversions.m";
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EAB44F706CB39CD00A4ABF0 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = string.h;
+               path = /usr/include/string.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EAB451006CB3DFC00A4ABF0 = {
+               fRef = 6EAB44EB06CB378F00A4ABF0;
+               isa = PBXTextBookmark;
+               name = "Conversions.m: 56";
+               rLen = 0;
+               rLoc = 2204;
+               rType = 0;
+               vrLen = 809;
+               vrLoc = 455;
+       };
+       6EAB457C06CB467900A4ABF0 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSWindow.h;
+               path = /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSWindow.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EAB465806CC01EA00A4ABF0 = {
+               fRef = 6E138C3006C1C140001C688F;
+               isa = PBXTextBookmark;
+               name = "- (void)setTemporaryStatus:(NSString *)message duration:(NSTimeInterval)duration";
+               rLen = 80;
+               rLoc = 1316;
+               rType = 0;
+               vrLen = 796;
+               vrLoc = 0;
+       };
+       6EAB490B06CC4FEA00A4ABF0 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {867, 3119}}";
+                       sepNavSelRange = "{4691, 0}";
+                       sepNavVisRect = "{{0, 1861}, {850, 743}}";
+               };
+       };
+       6EAB490C06CC4FEA00A4ABF0 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1017, 4479}}";
+                       sepNavSelRange = "{2386, 91}";
+                       sepNavVisRect = "{{0, 868}, {1017, 617}}";
+               };
+       };
+       6EB3527907C561AC000347B9 = {
+               isa = PBXFileReference;
+               lastKnownFileType = image.tiff;
+               name = docicon128.tiff;
+               path = "/Users/chaz/The Cheat/icons/docicon128.tiff";
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EB3527F07C56742000347B9 = {
+               fRef = 6EB3527907C561AC000347B9;
+               isa = PBXBookmark;
+       };
+       6EB3528007C56742000347B9 = {
+               fRef = 6EB3527907C561AC000347B9;
+               isa = PBXBookmark;
+       };
+       6EB3529007C56783000347B9 = {
+               fRef = 6EB3528707C56771000347B9;
+               isa = PBXBookmark;
+       };
+       6EB3529107C56783000347B9 = {
+               fRef = 6EB3528807C56771000347B9;
+               isa = PBXBookmark;
+       };
+       6EB352A707C56E94000347B9 = {
+               fRef = 6ED806900641D498002888F7;
+               isa = PBXBookmark;
+       };
+       6EB352A807C56E94000347B9 = {
+               fRef = 6ED806900641D498002888F7;
+               isa = PBXBookmark;
+       };
+       6EB352C207C574C9000347B9 = {
+               fRef = 6ED806300641D2E9002888F7;
+               isa = PBXTextBookmark;
+               name = "AboutBoxController.m: 15";
+               rLen = 0;
+               rLoc = 668;
+               rType = 0;
+               vrLen = 1028;
+               vrLoc = 0;
+       };
+       6EB352CF07C594F7000347B9 = {
+               fRef = 6ED8062F0641D2E9002888F7;
+               isa = PBXTextBookmark;
+               name = "AboutBoxController.h: 25";
+               rLen = 0;
+               rLoc = 935;
+               rType = 0;
+               vrLen = 931;
+               vrLoc = 322;
+       };
+       6EB3531907C5AA1C000347B9 = {
+               fRef = 6E138BF606C18765001C688F;
+               isa = PBXTextBookmark;
+               name = "Process.h: pid";
+               rLen = 0;
+               rLoc = 1435;
+               rType = 0;
+               vrLen = 1442;
+               vrLoc = 0;
+       };
+       6EB3532B07C5AAB8000347B9 = {
+               fRef = 6E138BF706C18765001C688F;
+               isa = PBXTextBookmark;
+               name = "- (BOOL)isEqual:(id)anObject\n";
+               rLen = 29;
+               rLoc = 2767;
+               rType = 0;
+               vrLen = 1086;
+               vrLoc = 2268;
+       };
+       6EB3532C07C5AAB8000347B9 = {
+               fRef = 6E31A16B06B723CB00E40AB3;
+               isa = PBXTextBookmark;
+               name = _processes;
+               rLen = 10;
+               rLoc = 1065;
+               rType = 0;
+               vrLen = 842;
+               vrLoc = 866;
+       };
+       6EB3539807C5C71B000347B9 = {
+               fRef = 6E31A16C06B723CB00E40AB3;
+               isa = PBXTextBookmark;
+               name = "LocalCheater.m: 662";
+               rLen = 0;
+               rLoc = 17666;
+               rType = 0;
+               vrLen = 1347;
+               vrLoc = 16667;
+       };
+       6EB353AA07C5C84D000347B9 = {
+               fRef = 6E63977106434C0800BD3765;
+               isa = PBXTextBookmark;
+               name = "FOUNDATION_EXPORT NSString *NSStringFromClass(Class aClass);\n";
+               rLen = 61;
+               rLoc = 1561;
+               rType = 0;
+               vrLen = 1322;
+               vrLoc = 880;
+       };
+       6EB3549607C7DE47000347B9 = {
+               fRef = 6E9BF3BB07820415008F0139;
+               isa = PBXTextBookmark;
+               name = "VariableTable.m: 68";
+               rLen = 0;
+               rLoc = 1404;
+               rType = 0;
+               vrLen = 999;
+               vrLoc = 210;
+       };
+       6EB354E907C7F3FF000347B9 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSBrowser.h;
+               path = /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSBrowser.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EB354EA07C7F537000347B9 = {
+               fRef = 6EB354E907C7F3FF000347B9;
+               isa = PBXTextBookmark;
+               name = "- (void)setMaxVisibleColumns:(int)columnCount;\n";
+               rLen = 47;
+               rLoc = 4777;
+               rType = 0;
+               vrLen = 1469;
+               vrLoc = 4178;
+       };
+       6EB354F007C7F637000347B9 = {
+               fRef = 6E138D8906C308C0001C688F;
+               isa = PBXTextBookmark;
+               name = "- (BOOL)isMemberOfClass:(Class)aClass;\n";
+               rLen = 39;
+               rLoc = 661;
+               rType = 0;
+               vrLen = 912;
+               vrLoc = 0;
+       };
+       6EB354F107C7F637000347B9 = {
+               fRef = 6EEA099A06BF83F200770544;
+               isa = PBXTextBookmark;
+               name = "- (void)appendString:(NSString *)aString;\n";
+               rLen = 42;
+               rLoc = 9868;
+               rType = 0;
+               vrLen = 2003;
+               vrLoc = 8968;
+       };
+       6EB3551A07C7FBBD000347B9 = {
+               fRef = 6E9BF5030782926E008F0139;
+               isa = PBXTextBookmark;
+               name = "TCArray TCMakeArrayWithBytes( unsigned count, unsigned size, void *bytes )\n";
+               rLen = 75;
+               rLoc = 521;
+               rType = 0;
+               vrLen = 778;
+               vrLoc = 0;
+       };
+       6EB3552007C7FBBD000347B9 = {
+               fRef = 6E38D3FE06C9B71F003BA9B4;
+               isa = PBXTextBookmark;
+               name = "DeleteTableView.m: 210";
+               rLen = 0;
+               rLoc = 6072;
+               rType = 0;
+               vrLen = 1064;
+               vrLoc = 4520;
+       };
+       6EB3554B07C8029A000347B9 = {
+               fRef = 6E3D7D3C06C44CFE00A73B29;
+               isa = PBXTextBookmark;
+               name = stringValue;
+               rLen = 11;
+               rLoc = 2534;
+               rType = 0;
+               vrLen = 1227;
+               vrLoc = 1506;
+       };
+       6EB355B907C80BEB000347B9 = {
+               fRef = 6E7614A206A47A790051C301;
+               isa = PBXTextBookmark;
+               name = _lastResponder;
+               rLen = 14;
+               rLoc = 3034;
+               rType = 0;
+               vrLen = 1418;
+               vrLoc = 2300;
+       };
+       6EB355D807C80DED000347B9 = {
+               fRef = 6EAB457C06CB467900A4ABF0;
+               isa = PBXTextBookmark;
+               name = "- (NSResponder *)firstResponder;\n";
+               rLen = 33;
+               rLoc = 9260;
+               rType = 0;
+               vrLen = 1307;
+               vrLoc = 8674;
+       };
+       6EB3569207C8208E000347B9 = {
+               fRef = 6E38D42406C9BBA9003BA9B4;
+               isa = PBXTextBookmark;
+               name = "NSTableView.h: clickedColumn";
+               rLen = 0;
+               rLoc = 5889;
+               rType = 0;
+               vrLen = 3044;
+               vrLoc = 7403;
+       };
+       6EB3572707C83197000347B9 = {
+               fRef = 6E8181D1076E475200A5FBEB;
+               isa = PBXTextBookmark;
+               name = numberOfResults;
+               rLen = 15;
+               rLoc = 910;
+               rType = 0;
+               vrLen = 951;
+               vrLoc = 472;
+       };
+       6EB3572807C83197000347B9 = {
+               fRef = 6E8181D2076E475200A5FBEB;
+               isa = PBXTextBookmark;
+               name = "- (void)didAddResults\n";
+               rLen = 22;
+               rLoc = 3536;
+               rType = 0;
+               vrLen = 363;
+               vrLoc = 3374;
+       };
+       6EB3573E07C832B4000347B9 = {
+               fRef = 6E72B20D06AA5B0E00951D50;
+               isa = PBXTextBookmark;
+               name = "- (unsigned)enabledVariableCount";
+               rLen = 32;
+               rLoc = 2617;
+               rType = 0;
+               vrLen = 1252;
+               vrLoc = 1406;
+       };
+       6EB3575307C837D6000347B9 = {
+               fRef = 6E72B20E06AA5B0E00951D50;
+               isa = PBXTextBookmark;
+               name = "CheatData.m: 15";
+               rLen = 0;
+               rLoc = 668;
+               rType = 0;
+               vrLen = 1298;
+               vrLoc = 178;
+       };
+       6EB3575E07C838EC000347B9 = {
+               fRef = 6E38D56B06C9E302003BA9B4;
+               isa = PBXTextBookmark;
+               name = "- (BOOL)scanLongLong:(long long *)value;\n";
+               rLen = 41;
+               rLoc = 679;
+               rType = 0;
+               vrLen = 1252;
+               vrLoc = 15;
+       };
+       6EB3576E07C83A91000347B9 = {
+               fRef = 6E3D7D3D06C44CFE00A73B29;
+               isa = PBXTextBookmark;
+               name = "Variable.m: 295";
+               rLen = 0;
+               rLoc = 7012;
+               rType = 0;
+               vrLen = 697;
+               vrLoc = 6719;
+       };
+       6EB3578E07C83B99000347B9 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {990, 678}}";
+                       sepNavSelRange = "{100, 0}";
+                       sepNavVisRect = "{{0, 0}, {990, 678}}";
+               };
+       };
+       6EB3578F07C83B99000347B9 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {990, 678}}";
+                       sepNavSelRange = "{116, 0}";
+                       sepNavVisRect = "{{0, 0}, {990, 678}}";
+               };
+       };
+       6EB3579A07C83C60000347B9 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {990, 678}}";
+                       sepNavSelRange = "{211, 0}";
+                       sepNavVisRect = "{{0, 0}, {990, 678}}";
+               };
+       };
+       6EB3579B07C83C60000347B9 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {990, 678}}";
+                       sepNavSelRange = "{424, 0}";
+                       sepNavVisRect = "{{0, 0}, {990, 678}}";
+               };
+       };
+       6EB357A807C83CE3000347B9 = {
+               fRef = 6EB3578E07C83B99000347B9;
+               isa = PBXTextBookmark;
+               name = "CheatURLHandler.scriptTerminology: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 517;
+               vrLoc = 0;
+       };
+       6EB357AA07C83CE3000347B9 = {
+               fRef = 6EB3579A07C83C60000347B9;
+               isa = PBXTextBookmark;
+               name = "CheatURLCommand.h: 12";
+               rLen = 0;
+               rLoc = 247;
+               rType = 0;
+               vrLen = 224;
+               vrLoc = 0;
+       };
+       6EB357CC07C83ECA000347B9 = {
+               fRef = 6EB3578E07C83B99000347B9;
+               isa = PBXTextBookmark;
+               name = "CheatURLHandler.scriptTerminology: 6";
+               rLen = 0;
+               rLoc = 100;
+               rType = 0;
+               vrLen = 241;
+               vrLoc = 0;
+       };
+       6EB357CD07C83ECA000347B9 = {
+               fRef = 6EB3578F07C83B99000347B9;
+               isa = PBXTextBookmark;
+               name = "CheatURLHandler.scriptSuite: 9";
+               rLen = 0;
+               rLoc = 116;
+               rType = 0;
+               vrLen = 219;
+               vrLoc = 0;
+       };
+       6EB357D007C83ECA000347B9 = {
+               fRef = 6EB3579B07C83C60000347B9;
+               isa = PBXTextBookmark;
+               name = "CheatURLCommand.m: 26";
+               rLen = 0;
+               rLoc = 654;
+               rType = 0;
+               vrLen = 612;
+               vrLoc = 0;
+       };
+       6EB357D207C83ECA000347B9 = {
+               fRef = 6EB3578F07C83B99000347B9;
+               isa = PBXTextBookmark;
+               name = "CheatURLHandler.scriptSuite: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 551;
+               vrLoc = 0;
+       };
+       6EB3582F07C84168000347B9 = {
+               fRef = 6EB3579A07C83C60000347B9;
+               isa = PBXTextBookmark;
+               name = "CheatURLCommand.h: 12";
+               rLen = 0;
+               rLoc = 211;
+               rType = 0;
+               vrLen = 271;
+               vrLoc = 0;
+       };
+       6EB3584707C84621000347B9 = {
+               fRef = 6EB3579B07C83C60000347B9;
+               isa = PBXTextBookmark;
+               name = "CheatURLCommand.m: 18";
+               rLen = 0;
+               rLoc = 424;
+               rType = 0;
+               vrLen = 663;
+               vrLoc = 0;
+       };
+       6EB3585807C84621000347B9 = {
+               fRef = 6EA39693077F4025002B0E69;
+               isa = PBXTextBookmark;
+               name = "DocInterfaceActions.m: 402";
+               rLen = 0;
+               rLoc = 11024;
+               rType = 0;
+               vrLen = 1215;
+               vrLoc = 10063;
+       };
+       6EB358B107C873F2000347B9 = {
+               fRef = 6ED806430641D305002888F7;
+               isa = PBXTextBookmark;
+               name = "HelpController.h: 19";
+               rLen = 0;
+               rLoc = 865;
+               rType = 0;
+               vrLen = 1058;
+               vrLoc = 0;
+       };
+       6EB358FD07C87DD5000347B9 = {
+               fRef = 6ED806440641D305002888F7;
+               isa = PBXTextBookmark;
+               name = "HelpController.m: 51";
+               rLen = 0;
+               rLoc = 1549;
+               rType = 0;
+               vrLen = 946;
+               vrLoc = 894;
+       };
+       6EB3598507C96786000347B9 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSText.h;
+               path = /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSText.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EB3598807C967BE000347B9 = {
+               fRef = 6EB3598507C96786000347B9;
+               isa = PBXTextBookmark;
+               name = "@interface NSText : NSView <NSChangeSpelling, NSIgnoreMisspelledWords> {\n";
+               rLen = 73;
+               rLoc = 1772;
+               rType = 0;
+               vrLen = 1572;
+               vrLoc = 894;
+       };
+       6EB3599C07C96968000347B9 = {
+               fRef = 6E7614A306A47A790051C301;
+               isa = PBXTextBookmark;
+               name = "CheatDocument.m: 386";
+               rLen = 0;
+               rLoc = 11118;
+               rType = 0;
+               vrLen = 1061;
+               vrLoc = 10419;
+       };
+       6EB359AE07C96AD6000347B9 = {
+               fRef = 6E9BF3BA07820415008F0139;
+               isa = PBXTextBookmark;
+               name = "VariableTable.h: 19";
+               rLen = 0;
+               rLoc = 387;
+               rType = 0;
+               vrLen = 670;
+               vrLoc = 0;
+       };
+       6EB359AF07C96AD6000347B9 = {
+               fRef = 6E6FD69C0762B626004FD845;
+               isa = PBXTextBookmark;
+               name = "ThreadedTask.m: 289";
+               rLen = 0;
+               rLoc = 7314;
+               rType = 0;
+               vrLen = 1180;
+               vrLoc = 6692;
+       };
+       6EB359CD07C99112000347B9 = {
+               fRef = 6EA3969B077F419A002B0E69;
+               isa = PBXTextBookmark;
+               name = "DocCheaterDelegate.m: 397";
+               rLen = 0;
+               rLoc = 10554;
+               rType = 0;
+               vrLen = 1040;
+               vrLoc = 10116;
+       };
+       6EB35A0A07C9BEB0000347B9 = {
+               fileReference = 6E9BF4B1078287DF008F0139;
+               functionName = "SearchStringIterationLastValue()";
+               isa = PBXFileBreakpoint;
+               lineNumber = 526;
+               state = 1;
+       };
+       6EB35A1107C9C033000347B9 = {
+               fRef = 6E9BF4B1078287DF008F0139;
+               isa = PBXTextBookmark;
+               name = "Searching.m: 519";
+               rLen = 0;
+               rLoc = 16483;
+               rType = 0;
+               vrLen = 1767;
+               vrLoc = 15766;
+       };
+       6EB35A1207C9C033000347B9 = {
+               fRef = 6E6FD6B10762B965004FD845;
+               isa = PBXTextBookmark;
+               name = "SearchContext.h: _searchType";
+               rLen = 0;
+               rLoc = 806;
+               rType = 0;
+               vrLen = 1409;
+               vrLoc = 140;
+       };
+       6EB35A1B07C9C141000347B9 = {
+               fRef = 6E6FD6B20762B965004FD845;
+               isa = PBXTextBookmark;
+               name = "SearchContext.m: 91";
+               rLen = 0;
+               rLoc = 2723;
+               rType = 0;
+               vrLen = 1683;
+               vrLoc = 2254;
+       };
+       6EB35A1C07C9C141000347B9 = {
+               fRef = 6E3D7D3D06C44CFE00A73B29;
+               isa = PBXTextBookmark;
+               name = "Variable.m: 320";
+               rLen = 0;
+               rLoc = 7413;
+               rType = 0;
+               vrLen = 762;
+               vrLoc = 4378;
+       };
+       6EB35A1E07C9C141000347B9 = {
+               fRef = 6E6FD6B20762B965004FD845;
+               isa = PBXTextBookmark;
+               name = "SearchContext.m: 91";
+               rLen = 0;
+               rLoc = 2723;
+               rType = 0;
+               vrLen = 1683;
+               vrLoc = 2254;
+       };
+       6EB35AAC07CA6027000347B9 = {
+               fRef = 6EB35AA107CA5FE0000347B9;
+               isa = PBXBookmark;
+       };
+       6EB35ABB07CA624E000347B9 = {
+               fRef = 6ED806350641D2E9002888F7;
+               isa = PBXTextBookmark;
+               name = "PreferenceController.h: chooseUpdate:";
+               rLen = 0;
+               rLoc = 1237;
+               rType = 0;
+               vrLen = 1323;
+               vrLoc = 1;
+       };
+       6EB35B3507CA6BCC000347B9 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {991, 678}}";
+                       sepNavSelRange = "{287, 0}";
+                       sepNavVisRect = "{{0, 0}, {991, 678}}";
+               };
+       };
+       6EB35B3607CA6BCC000347B9 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {991, 678}}";
+                       sepNavSelRange = "{236, 0}";
+                       sepNavVisRect = "{{0, 0}, {991, 678}}";
+               };
+       };
+       6EB35B3907CA6C8C000347B9 = {
+               fRef = 6ED97B9E0645E85700CBF037;
+               isa = PBXTextBookmark;
+               name = "CheatServer.m: 233";
+               rLen = 0;
+               rLoc = 6294;
+               rType = 0;
+               vrLen = 786;
+               vrLoc = 5682;
+       };
+       6EB35B3E07CA6C8C000347B9 = {
+               fRef = 6ED8072606421B10002888F7;
+               isa = PBXTextBookmark;
+               name = "ServerPrefs.h: ibStatusField";
+               rLen = 0;
+               rLoc = 1031;
+               rType = 0;
+               vrLen = 1380;
+               vrLoc = 1;
+       };
+       6EB35B4107CA6C8C000347B9 = {
+               fRef = 6EB35B3507CA6BCC000347B9;
+               isa = PBXTextBookmark;
+               name = "- (IBAction)ibAutoCheckButton:(id)sender;\n- (IBAction)ibCheckNowButton:(id)sender;";
+               rLen = 82;
+               rLoc = 280;
+               rType = 0;
+               vrLen = 369;
+               vrLoc = 0;
+       };
+       6EB35B4207CA6C8C000347B9 = {
+               fRef = 6EB35B3607CA6BCC000347B9;
+               isa = PBXTextBookmark;
+               name = "UpdatePrefs.m: 16";
+               rLen = 0;
+               rLoc = 543;
+               rType = 0;
+               vrLen = 284;
+               vrLoc = 0;
+       };
+       6EB35B9807CA7141000347B9 = {
+               fRef = 6ED8072006421B05002888F7;
+               isa = PBXTextBookmark;
+               name = "GeneralPrefs.h: ibFadeSmoothlyButton";
+               rLen = 0;
+               rLoc = 1078;
+               rType = 0;
+               vrLen = 1594;
+               vrLoc = 75;
+       };
+       6EB35BAF07CA7311000347B9 = {
+               fRef = 6ED8072106421B05002888F7;
+               isa = PBXTextBookmark;
+               name = "[ibSwitchVariablesButton setState:[[NSUserDefaults standardUserDefaults] boolForKey:TCSwitchVariablesPref]];\n\t[ibStartEditingVarsButton setState:[[NSUserDefaults standardUserDefaults] boolForKey:TCAutoStartEditingVarsPref]];";
+               rLen = 224;
+               rLoc = 1761;
+               rType = 0;
+               vrLen = 1807;
+               vrLoc = 738;
+       };
+       6EB35BF507CABCBB000347B9 = {
+               fRef = 6EB35B3507CA6BCC000347B9;
+               isa = PBXTextBookmark;
+               name = "UpdatePrefs.h: ibAutoCheckButton";
+               rLen = 0;
+               rLoc = 287;
+               rType = 0;
+               vrLen = 380;
+               vrLoc = 0;
+       };
+       6EB35C0107CABE47000347B9 = {
+               fRef = 6EB35B3607CA6BCC000347B9;
+               isa = PBXTextBookmark;
+               name = "UpdatePrefs.m: 17";
+               rLen = 0;
+               rLoc = 236;
+               rType = 0;
+               vrLen = 595;
+               vrLoc = 0;
+       };
+       6EB35C2207CAC0C8000347B9 = {
+               fRef = 6ED806310641D2E9002888F7;
+               isa = PBXTextBookmark;
+               name = _preferenceController;
+               rLen = 21;
+               rLoc = 1235;
+               rType = 0;
+               vrLen = 914;
+               vrLoc = 801;
+       };
+       6EB35C7507CAC91F000347B9 = {
+               fRef = 6ED8072706421B10002888F7;
+               isa = PBXTextBookmark;
+               name = "ServerPrefs.m: 181";
+               rLen = 0;
+               rLoc = 5065;
+               rType = 0;
+               vrLen = 1115;
+               vrLoc = 4569;
+       };
+       6EB35C9D07CB8C2B000347B9 = {
+               fRef = 6ED806320641D2E9002888F7;
+               isa = PBXTextBookmark;
+               name = "AppController.m: 57";
+               rLen = 0;
+               rLoc = 2685;
+               rType = 0;
+               vrLen = 1956;
+               vrLoc = 978;
+       };
+       6EB35C9E07CB8C2B000347B9 = {
+               fRef = 6ED806790641D41B002888F7;
+               isa = PBXTextBookmark;
+               name = "cheat_global.h: TCAutoStartEditingVarsPref";
+               rLen = 0;
+               rLoc = 1645;
+               rType = 0;
+               vrLen = 1271;
+               vrLoc = 738;
+       };
+       6EB35CA607CB94A2000347B9 = {
+               fRef = 6ED8067A0641D41B002888F7;
+               isa = PBXTextBookmark;
+               name = "cheat_global.m: TCAutoStartEditingVarsPref";
+               rLen = 0;
+               rLoc = 1709;
+               rType = 0;
+               vrLen = 1763;
+               vrLoc = 486;
+       };
+       6EB35CAE07CBA6CC000347B9 = {
+               fRef = 6E31A14406B71EBA00E40AB3;
+               isa = PBXTextBookmark;
+               name = "ServerChild.m: 140";
+               rLen = 0;
+               rLoc = 4040;
+               rType = 0;
+               vrLen = 1001;
+               vrLoc = 3144;
+       };
+       6EB35CAF07CBA6CC000347B9 = {
+               fRef = 6ECDE09D0643985000B1DD8A;
+               isa = PBXBookmark;
+       };
+       6EB35CB007CBA6CC000347B9 = {
+               fRef = 6ECDE0990643984400B1DD8A;
+               isa = PBXBookmark;
+       };
+       6EB35CB107CBA6CC000347B9 = {
+               fRef = 6EB35AA107CA5FE0000347B9;
+               isa = PBXBookmark;
+       };
+       6EB35CB207CBA6CC000347B9 = {
+               fRef = 6E6FD8FA0764D1B0004FD845;
+               isa = PBXBookmark;
+       };
+       6EB35CB307CBA6CC000347B9 = {
+               fRef = 6EB3528707C56771000347B9;
+               isa = PBXBookmark;
+       };
+       6EB35CB407CBA6CC000347B9 = {
+               fRef = 6EB3528807C56771000347B9;
+               isa = PBXBookmark;
+       };
+       6EB35CB507CBA6CC000347B9 = {
+               fRef = 6EC06600078BFBE900591D61;
+               isa = PBXTextBookmark;
+               name = "Help.html: 91";
+               rLen = 0;
+               rLoc = 1890;
+               rType = 0;
+               vrLen = 523;
+               vrLoc = 0;
+       };
+       6EB35CD407CBAC0F000347B9 = {
+               fRef = 6ED806830641D434002888F7;
+               isa = PBXTextBookmark;
+               name = "main.m: 29";
+               rLen = 0;
+               rLoc = 1038;
+               rType = 0;
+               vrLen = 1187;
+               vrLoc = 0;
+       };
+       6EB35CDD07CBAD23000347B9 = {
+               fRef = 6E38D3FE06C9B71F003BA9B4;
+               isa = PBXTextBookmark;
+               name = "BetterTableView.m: 172";
+               rLen = 0;
+               rLoc = 4844;
+               rType = 0;
+               vrLen = 1142;
+               vrLoc = 3764;
+       };
+       6EB35CDE07CBAD23000347B9 = {
+               fRef = 6E38D3FD06C9B71F003BA9B4;
+               isa = PBXTextBookmark;
+               name = "- (BOOL)tableViewDidReceiveSpaceKey:(NSTableView *)tableView";
+               rLen = 60;
+               rLoc = 1676;
+               rType = 0;
+               vrLen = 1127;
+               vrLoc = 617;
+       };
+       6EB9054707CBC34300D8982B = {
+               fRef = 6E6FDC250765858A004FD845;
+               isa = PBXTextBookmark;
+               name = "DumpContext.m: 26";
+               rLen = 0;
+               rLoc = 420;
+               rType = 0;
+               vrLen = 490;
+               vrLoc = 0;
+       };
+       6EB9054807CBC34300D8982B = {
+               fRef = 6ED806360641D2E9002888F7;
+               isa = PBXTextBookmark;
+               name = "PreferenceController.m: 138";
+               rLen = 0;
+               rLoc = 3607;
+               rType = 0;
+               vrLen = 1217;
+               vrLoc = 2573;
+       };
+       6EB9054907CBC34300D8982B = {
+               fRef = 6EF2F0BF077B424000C8B55A;
+               isa = PBXTextBookmark;
+               name = "CHEAT_STATIC_INLINE unsigned TCArrayElementSize( TCArray array )\n";
+               rLen = 65;
+               rLoc = 2229;
+               rType = 0;
+               vrLen = 1031;
+               vrLoc = 1820;
+       };
+       6EB9054A07CBC34300D8982B = {
+               fRef = 6E7614A206A47A790051C301;
+               isa = PBXTextBookmark;
+               name = TCSearchingStatus;
+               rLen = 17;
+               rLoc = 1327;
+               rType = 0;
+               vrLen = 834;
+               vrLoc = 964;
+       };
+       6EB9054B07CBC34300D8982B = {
+               fRef = 6EA39693077F4025002B0E69;
+               isa = PBXTextBookmark;
+               name = "DocInterfaceActions.m: 568";
+               rLen = 0;
+               rLoc = 14657;
+               rType = 0;
+               vrLen = 1138;
+               vrLoc = 14052;
+       };
+       6EB9054D07CBC34300D8982B = {
+               fRef = 6E6FDC250765858A004FD845;
+               isa = PBXTextBookmark;
+               name = "DumpContext.m: 26";
+               rLen = 0;
+               rLoc = 420;
+               rType = 0;
+               vrLen = 490;
+               vrLoc = 0;
+       };
+       6EB9054E07CBC34300D8982B = {
+               fRef = 6ED806360641D2E9002888F7;
+               isa = PBXTextBookmark;
+               name = "PreferenceController.m: 138";
+               rLen = 0;
+               rLoc = 3607;
+               rType = 0;
+               vrLen = 1217;
+               vrLoc = 2573;
+       };
+       6EB9054F07CBC34300D8982B = {
+               fRef = 6E7614A306A47A790051C301;
+               isa = PBXTextBookmark;
+               name = "CheatDocument.m: 866";
+               rLen = 0;
+               rLoc = 25014;
+               rType = 0;
+               vrLen = 970;
+               vrLoc = 23806;
+       };
+       6EB9055007CBC34300D8982B = {
+               fRef = 6E7614A206A47A790051C301;
+               isa = PBXTextBookmark;
+               name = "typedef unsigned TCDocumentStatus;\n";
+               rLen = 35;
+               rLoc = 1265;
+               rType = 0;
+               vrLen = 834;
+               vrLoc = 964;
+       };
+       6EB9055107CBC34300D8982B = {
+               fRef = 6EA39693077F4025002B0E69;
+               isa = PBXTextBookmark;
+               name = "DocInterfaceActions.m: 568";
+               rLen = 0;
+               rLoc = 14657;
+               rType = 0;
+               vrLen = 1138;
+               vrLoc = 14052;
+       };
+       6EB9055207CBC34300D8982B = {
+               fRef = 6EF2F0BF077B424000C8B55A;
+               isa = PBXTextBookmark;
+               name = "CHEAT_STATIC_INLINE unsigned TCArrayElementSize( TCArray array )\n";
+               rLen = 65;
+               rLoc = 2229;
+               rType = 0;
+               vrLen = 1031;
+               vrLoc = 1820;
+       };
+       6EB9055307CBC34300D8982B = {
+               fRef = 6E7614A206A47A790051C301;
+               isa = PBXTextBookmark;
+               name = TCSearchingStatus;
+               rLen = 17;
+               rLoc = 1327;
+               rType = 0;
+               vrLen = 834;
+               vrLoc = 964;
+       };
+       6EB9055407CBC34300D8982B = {
+               fRef = 6E7614A306A47A790051C301;
+               isa = PBXTextBookmark;
+               name = "CheatDocument.m: 869";
+               rLen = 0;
+               rLoc = 24811;
+               rType = 0;
+               vrLen = 1092;
+               vrLoc = 23806;
+       };
+       6EB9055507CBC34300D8982B = {
+               fRef = 6EA39693077F4025002B0E69;
+               isa = PBXTextBookmark;
+               name = "DocInterfaceActions.m: 568";
+               rLen = 0;
+               rLoc = 14657;
+               rType = 0;
+               vrLen = 1138;
+               vrLoc = 14052;
+       };
+       6EB9056407CBC5E600D8982B = {
+               fRef = 6E7614A306A47A790051C301;
+               isa = PBXTextBookmark;
+               name = "CheatDocument.m: 845";
+               rLen = 0;
+               rLoc = 24195;
+               rType = 0;
+               vrLen = 1096;
+               vrLoc = 23768;
+       };
+       6EB9056607CBC5E600D8982B = {
+               isa = PBXFileReference;
+               lastKnownFileType = text.plist.strings;
+               name = InfoPlist.strings;
+               path = "/Users/chaz/Desktop/The Cheat/The Cheat.app/Contents/Resources/English.lproj/InfoPlist.strings";
+               refType = 0;
+               sourceTree = "<absolute>";
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {991, 678}}";
+                       sepNavSelRange = "{65, 0}";
+                       sepNavVisRect = "{{0, 0}, {991, 678}}";
+               };
+       };
+       6EB9056907CBC5E600D8982B = {
+               fRef = 6E7614A306A47A790051C301;
+               isa = PBXTextBookmark;
+               name = "CheatDocument.m: 845";
+               rLen = 0;
+               rLoc = 24195;
+               rType = 0;
+               vrLen = 1096;
+               vrLoc = 23768;
+       };
+       6EB9056A07CBC5E600D8982B = {
+               fRef = 6EB9056B07CBC5E600D8982B;
+               isa = PBXTextBookmark;
+               name = "(null): 6";
+               rLen = 0;
+               rLoc = 204;
+               rType = 0;
+               vrLen = 204;
+               vrLoc = 0;
+       };
+       6EB9056B07CBC5E600D8982B = {
+               isa = PBXFileReference;
+               name = InfoPlist.strings;
+               path = "/Users/chaz/Desktop/The Cheat/The Cheat.app/Contents/Resources/English.lproj/InfoPlist.strings";
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EB9056C07CBC5E600D8982B = {
+               fRef = 6ED806940641D498002888F7;
+               isa = PBXTextBookmark;
+               name = "English: 7";
+               rLen = 0;
+               rLoc = 130;
+               rType = 0;
+               vrLen = 411;
+               vrLoc = 0;
+       };
+       6EB9056D07CBC5E600D8982B = {
+               fRef = 6ED806D00641D5F2002888F7;
+               isa = PBXTextBookmark;
+               name = "Info.plist: 51";
+               rLen = 0;
+               rLoc = 1404;
+               rType = 0;
+               vrLen = 1074;
+               vrLoc = 700;
+       };
+       6EB9057407CBC67800D8982B = {
+               fRef = 6ED806940641D498002888F7;
+               isa = PBXTextBookmark;
+               name = "English: 7";
+               rLen = 0;
+               rLoc = 130;
+               rType = 0;
+               vrLen = 411;
+               vrLoc = 0;
+       };
+       6EB9057507CBC67800D8982B = {
+               fRef = 6ED806D00641D5F2002888F7;
+               isa = PBXTextBookmark;
+               name = "Info.plist: 51";
+               rLen = 0;
+               rLoc = 1404;
+               rType = 0;
+               vrLen = 1074;
+               vrLoc = 700;
+       };
+       6EB9057607CBC67800D8982B = {
+               fRef = 6ED806940641D498002888F7;
+               isa = PBXTextBookmark;
+               name = "English: 7";
+               rLen = 0;
+               rLoc = 130;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 0;
+       };
+       6EB9057707CBC67800D8982B = {
+               fRef = 6ED806D00641D5F2002888F7;
+               isa = PBXTextBookmark;
+               name = "Info.plist: 51";
+               rLen = 0;
+               rLoc = 1404;
+               rType = 0;
+               vrLen = 1074;
+               vrLoc = 700;
+       };
+       6EB9058407CBC6F100D8982B = {
+               fRef = 6EB9058507CBC6F100D8982B;
+               isa = PBXTextBookmark;
+               name = "(null): 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 1124;
+               vrLoc = 0;
+       };
+       6EB9058507CBC6F100D8982B = {
+               isa = PBXFileReference;
+               name = InfoPlist.strings;
+               path = /Applications/iTunes.app/Contents/Resources/English.lproj/InfoPlist.strings;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EB9058607CBC6F100D8982B = {
+               fRef = 6ED806940641D498002888F7;
+               isa = PBXTextBookmark;
+               name = "English: 5";
+               rLen = 0;
+               rLoc = 130;
+               rType = 0;
+               vrLen = 130;
+               vrLoc = 0;
+       };
+       6EB9058807CBC6F100D8982B = {
+               fRef = 6ED806940641D498002888F7;
+               isa = PBXTextBookmark;
+               name = "English: 7";
+               rLen = 0;
+               rLoc = 130;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 0;
+       };
+       6EB9058907CBC6F100D8982B = {
+               fRef = 6EB9058A07CBC6F100D8982B;
+               isa = PBXTextBookmark;
+               name = "(null): 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 1124;
+               vrLoc = 0;
+       };
+       6EB9058A07CBC6F100D8982B = {
+               isa = PBXFileReference;
+               name = InfoPlist.strings;
+               path = /Applications/iTunes.app/Contents/Resources/English.lproj/InfoPlist.strings;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EB9058B07CBC6F100D8982B = {
+               fRef = 6ED806940641D498002888F7;
+               isa = PBXTextBookmark;
+               name = "English: 7";
+               rLen = 0;
+               rLoc = 130;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 0;
+       };
+       6EB9058C07CBC6F100D8982B = {
+               fRef = 6ED806D00641D5F2002888F7;
+               isa = PBXTextBookmark;
+               name = "Info.plist: 51";
+               rLen = 0;
+               rLoc = 1404;
+               rType = 0;
+               vrLen = 1213;
+               vrLoc = 0;
+       };
+       6EB9058D07CBC6F100D8982B = {
+               fRef = 6ED806940641D498002888F7;
+               isa = PBXTextBookmark;
+               name = "English: 7";
+               rLen = 0;
+               rLoc = 130;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 0;
+       };
+       6EB9058E07CBC6F100D8982B = {
+               fRef = 6ED806D00641D5F2002888F7;
+               isa = PBXTextBookmark;
+               name = "Info.plist: 51";
+               rLen = 0;
+               rLoc = 1404;
+               rType = 0;
+               vrLen = 1213;
+               vrLoc = 0;
+       };
+       6EB9058F07CBC6F100D8982B = {
+               fRef = 6ED806940641D498002888F7;
+               isa = PBXTextBookmark;
+               name = "English: 7";
+               rLen = 0;
+               rLoc = 130;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 0;
+       };
+       6EB9059007CBC6F100D8982B = {
+               fRef = 6ED806D00641D5F2002888F7;
+               isa = PBXTextBookmark;
+               name = "Info.plist: 51";
+               rLen = 0;
+               rLoc = 1404;
+               rType = 0;
+               vrLen = 1135;
+               vrLoc = 383;
+       };
+       6EB9059107CBC6F100D8982B = {
+               fRef = 6ED806940641D498002888F7;
+               isa = PBXTextBookmark;
+               name = "English: 5";
+               rLen = 0;
+               rLoc = 130;
+               rType = 0;
+               vrLen = 130;
+               vrLoc = 0;
+       };
+       6EB9059507CBC72D00D8982B = {
+               fRef = 6ED806D00641D5F2002888F7;
+               isa = PBXTextBookmark;
+               name = "Info.plist: 51";
+               rLen = 0;
+               rLoc = 1404;
+               rType = 0;
+               vrLen = 1044;
+               vrLoc = 730;
+       };
+       6EB9059907CBC7C400D8982B = {
+               fRef = 6EB9056607CBC5E600D8982B;
+               isa = PBXTextBookmark;
+               name = "InfoPlist.strings: 1";
+               rLen = 0;
+               rLoc = 65;
+               rType = 0;
+               vrLen = 65;
+               vrLoc = 0;
+       };
+       6EB9059A07CBC7C400D8982B = {
+               fRef = 6ED806D00641D5F2002888F7;
+               isa = PBXTextBookmark;
+               name = "Info.plist: 51";
+               rLen = 0;
+               rLoc = 1404;
+               rType = 0;
+               vrLen = 1074;
+               vrLoc = 700;
+       };
+       6EB9059B07CBC7C400D8982B = {
+               fRef = 6EB9056607CBC5E600D8982B;
+               isa = PBXTextBookmark;
+               name = "InfoPlist.strings: 1";
+               rLen = 0;
+               rLoc = 65;
+               rType = 0;
+               vrLen = 65;
+               vrLoc = 0;
+       };
+       6EB9059C07CBC7C400D8982B = {
+               fRef = 6ED806D00641D5F2002888F7;
+               isa = PBXTextBookmark;
+               name = "Info.plist: 51";
+               rLen = 0;
+               rLoc = 1404;
+               rType = 0;
+               vrLen = 1074;
+               vrLoc = 700;
+       };
+       6EB9059E07CBC7C400D8982B = {
+               fRef = 6ED806940641D498002888F7;
+               isa = PBXTextBookmark;
+               name = "English: 5";
+               rLen = 0;
+               rLoc = 130;
+               rType = 0;
+               vrLen = 130;
+               vrLoc = 0;
+       };
+       6EC064A3078BA17E00591D61 = {
+               fRef = 6E138D3C06C22416001C688F;
+               isa = PBXTextBookmark;
+               name = "- (void)encodeBytes:(const void *)byteaddr length:(unsigned)length;\n";
+               rLen = 68;
+               rLoc = 877;
+               rType = 0;
+               vrLen = 1473;
+               vrLoc = 135;
+       };
+       6EC064A8078BA17E00591D61 = {
+               fRef = 6E3D7D3C06C44CFE00A73B29;
+               isa = PBXTextBookmark;
+               name = "Variable.h: 40";
+               rLen = 0;
+               rLoc = 1310;
+               rType = 0;
+               vrLen = 1080;
+               vrLoc = 669;
+       };
+       6EC064D1078BC50500591D61 = {
+               fRef = 6EA3971B077F7648002B0E69;
+               isa = PBXTextBookmark;
+               name = "    NSOnState    =  1    \n";
+               rLen = 26;
+               rLoc = 1481;
+               rType = 0;
+               vrLen = 957;
+               vrLoc = 1022;
+       };
+       6EC064D7078BC50500591D61 = {
+               fRef = 6ED8072106421B05002888F7;
+               isa = PBXTextBookmark;
+               name = "GeneralPrefs.m: 47";
+               rLen = 0;
+               rLoc = 2409;
+               rType = 0;
+               vrLen = 1125;
+               vrLoc = 893;
+       };
+       6EC06500078BD5F000591D61 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSFont.h;
+               path = /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSFont.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EC06501078BD61800591D61 = {
+               fRef = 6EC06500078BD5F000591D61;
+               isa = PBXTextBookmark;
+               name = "+ (NSFont *)systemFontOfSize:(float)fontSize;\t// Aqua System font\n";
+               rLen = 66;
+               rLoc = 2141;
+               rType = 0;
+               vrLen = 1606;
+               vrLoc = 1456;
+       };
+       6EC06522078BDC7B00591D61 = {
+               fRef = 6ED806300641D2E9002888F7;
+               isa = PBXTextBookmark;
+               name = "AboutBoxController.m: 44";
+               rLen = 0;
+               rLoc = 1297;
+               rType = 0;
+               vrLen = 1752;
+               vrLoc = 1005;
+       };
+       6EC06556078BE68300591D61 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 649}}";
+                       sepNavSelRange = "{839, 0}";
+                       sepNavVisRect = "{{0, 0}, {1018, 649}}";
+               };
+       };
+       6EC06557078BE68300591D61 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1238, 5183}}";
+                       sepNavSelRange = "{5856, 0}";
+                       sepNavVisRect = "{{0, 3511}, {1234, 579}}";
+               };
+       };
+       6EC0655C078BEF7B00591D61 = {
+               fRef = 6EA253F60786249800C839D1;
+               isa = PBXTextBookmark;
+               name = "ChazLog.h: ChazOpenDebugLog";
+               rLen = 0;
+               rLoc = 998;
+               rType = 0;
+               vrLen = 883;
+               vrLoc = 193;
+       };
+       6EC06565078BEF7B00591D61 = {
+               fRef = 6EC06556078BE68300591D61;
+               isa = PBXTextBookmark;
+               name = "ChazUpdate.h: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 206;
+               vrLoc = 0;
+       };
+       6EC0656D078BEF7B00591D61 = {
+               fRef = 6EC06557078BE68300591D61;
+               isa = PBXTextBookmark;
+               name = "ChazUpdate.m: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 194;
+               vrLoc = 0;
+       };
+       6EC065CF078BF85100591D61 = {
+               fRef = 6E138C3006C1C140001C688F;
+               isa = PBXTextBookmark;
+               name = "StatusTextField.h: 19";
+               rLen = 0;
+               rLoc = 865;
+               rType = 0;
+               vrLen = 1504;
+               vrLoc = 0;
+       };
+       6EC065D0078BF85100591D61 = {
+               fRef = 6E9BF3200781EEC3008F0139;
+               isa = PBXTextBookmark;
+               name = "TrackerScroller.m: 35";
+               rLen = 0;
+               rLoc = 632;
+               rType = 0;
+               vrLen = 640;
+               vrLoc = 0;
+       };
+       6EC06600078BFBE900591D61 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {5592, 6576}}";
+                       sepNavSelRange = "{1890, 0}";
+                       sepNavVisRect = "{{0, 0}, {991, 678}}";
+               };
+       };
+       6EC06606078BFBFB00591D61 = {
+               fRef = 6EC06600078BFBE900591D61;
+               isa = PBXTextBookmark;
+               name = "Help.html: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 87;
+               vrLoc = 0;
+       };
+       6ED806180641D21A002888F7 = {
+               activeArgIndex = 2147483647;
+               activeArgIndices = (
+               );
+               argumentStrings = (
+               );
+               configStateDict = {
+               };
+               cppStopOnCatchEnabled = 0;
+               cppStopOnThrowEnabled = 0;
+               customDataFormattersEnabled = 1;
+               debuggerPlugin = GDBDebugging;
+               disassemblyDisplayState = 0;
+               dylibVariantSuffix = "";
+               enableDebugStr = 1;
+               environmentEntries = (
+               );
+               isa = PBXExecutable;
+               libgmallocEnabled = 0;
+               name = "The Cheat";
+               savedGlobals = {
+               };
+               shlibInfoDictList = (
+               );
+               sourceDirectories = (
+               );
+       };
+       6ED806210641D21D002888F7 = {
+               fallbackIsa = XCSourceControlManager;
+               isSCMEnabled = 0;
+               isa = PBXSourceControlManager;
+               scmConfiguration = {
+               };
+               scmType = scm.cvs;
+       };
+       6ED806220641D21D002888F7 = {
+               indexTemplatePath = "";
+               isa = PBXCodeSenseManager;
+               usesDefaults = 1;
+               wantsCodeCompletion = 0;
+               wantsCodeCompletionAutoSuggestions = 1;
+               wantsCodeCompletionCaseSensitivity = 1;
+               wantsCodeCompletionListAlways = 0;
+               wantsCodeCompletionOnlyMatchingItems = 1;
+               wantsCodeCompletionParametersIncluded = 0;
+               wantsCodeCompletionPlaceholdersInserted = 0;
+               wantsCodeCompletionTabCompletes = 1;
+               wantsIndex = 1;
+       };
+       6ED8062F0641D2E9002888F7 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 655}}";
+                       sepNavSelRange = "{935, 0}";
+                       sepNavVisRect = "{{0, 120}, {1018, 520}}";
+               };
+       };
+       6ED806300641D2E9002888F7 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 1295}}";
+                       sepNavSelRange = "{668, 0}";
+                       sepNavVisRect = "{{0, 0}, {1018, 520}}";
+               };
+       };
+       6ED806310641D2E9002888F7 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {991, 1039}}";
+                       sepNavSelRange = "{1235, 21}";
+                       sepNavVisRect = "{{0, 272}, {991, 678}}";
+               };
+       };
+       6ED806320641D2E9002888F7 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1385, 4111}}";
+                       sepNavSelRange = "{2685, 0}";
+                       sepNavVisRect = "{{0, 408}, {991, 678}}";
+                       sepNavWindowFrame = "{{15, 375}, {750, 558}}";
+               };
+       };
+       6ED806350641D2E9002888F7 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {991, 704}}";
+                       sepNavSelRange = "{1237, 0}";
+                       sepNavVisRect = "{{0, 16}, {991, 678}}";
+               };
+       };
+       6ED806360641D2E9002888F7 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {991, 2352}}";
+                       sepNavSelRange = "{3607, 0}";
+                       sepNavVisRect = "{{0, 1674}, {991, 678}}";
+               };
+       };
+       6ED806430641D305002888F7 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {990, 678}}";
+                       sepNavSelRange = "{865, 0}";
+                       sepNavVisRect = "{{0, 0}, {990, 678}}";
+               };
+       };
+       6ED806440641D305002888F7 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1504, 1023}}";
+                       sepNavSelRange = "{1808, 0}";
+                       sepNavVisRect = "{{0, 416}, {1234, 469}}";
+               };
+       };
+       6ED806710641D3CC002888F7 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 649}}";
+                       sepNavSelRange = "{1122, 14}";
+                       sepNavVisRect = "{{0, 0}, {1018, 649}}";
+               };
+       };
+       6ED806720641D3CC002888F7 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {989, 1840}}";
+                       sepNavSelRange = "{1961, 0}";
+                       sepNavVisRect = "{{0, 1188}, {989, 649}}";
+               };
+       };
+       6ED806790641D41B002888F7 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {991, 1104}}";
+                       sepNavSelRange = "{1645, 0}";
+                       sepNavVisRect = "{{0, 269}, {991, 678}}";
+               };
+       };
+       6ED8067A0641D41B002888F7 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1189, 2175}}";
+                       sepNavSelRange = "{1709, 0}";
+                       sepNavVisRect = "{{0, 189}, {991, 678}}";
+                       sepNavWindowFrame = "{{15, 375}, {750, 558}}";
+               };
+       };
+       6ED806830641D434002888F7 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {991, 678}}";
+                       sepNavSelRange = "{1038, 0}";
+                       sepNavVisRect = "{{0, 0}, {991, 678}}";
+               };
+       };
+       6ED806940641D498002888F7 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {991, 678}}";
+                       sepNavSelRange = "{130, 0}";
+                       sepNavVisRect = "{{0, 0}, {991, 678}}";
+               };
+       };
+       6ED806D00641D5F2002888F7 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {991, 1103}}";
+                       sepNavSelRange = "{1404, 0}";
+                       sepNavVisRect = "{{0, 413}, {991, 678}}";
+               };
+       };
+       6ED8072006421B05002888F7 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {991, 751}}";
+                       sepNavSelRange = "{1078, 0}";
+                       sepNavVisRect = "{{0, 45}, {991, 678}}";
+               };
+       };
+       6ED8072106421B05002888F7 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {991, 2223}}";
+                       sepNavSelRange = "{1761, 224}";
+                       sepNavVisRect = "{{0, 268}, {991, 678}}";
+               };
+       };
+       6ED8072606421B10002888F7 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {991, 751}}";
+                       sepNavSelRange = "{1031, 0}";
+                       sepNavVisRect = "{{0, 26}, {991, 678}}";
+               };
+       };
+       6ED8072706421B10002888F7 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {991, 3343}}";
+                       sepNavSelRange = "{5065, 0}";
+                       sepNavVisRect = "{{0, 2665}, {991, 678}}";
+               };
+       };
+       6ED97B9D0645E85700CBF037 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1018, 1327}}";
+                       sepNavSelRange = "{1794, 11}";
+                       sepNavVisRect = "{{0, 165}, {1018, 756}}";
+               };
+       };
+       6ED97B9E0645E85700CBF037 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {991, 4127}}";
+                       sepNavSelRange = "{6294, 0}";
+                       sepNavVisRect = "{{0, 3354}, {991, 678}}";
+               };
+       };
+       6EDB002B06D518FB00DBD1D5 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSPanel.h;
+               path = /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSPanel.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EDB006906D5213D00DBD1D5 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = mach_init.h;
+               path = /usr/include/mach/mach_init.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EDB006D06D5216D00DBD1D5 = {
+               fRef = 6EDB006906D5213D00DBD1D5;
+               isa = PBXTextBookmark;
+               name = "mach_init.h: mach_thread_self";
+               rLen = 0;
+               rLoc = 2438;
+               rType = 0;
+               vrLen = 1045;
+               vrLoc = 1526;
+       };
+       6EDB008F06D525CE00DBD1D5 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = kern_return.h;
+               path = /usr/include/mach/ppc/kern_return.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EDB009806D5282200DBD1D5 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = kern_return.h;
+               path = /usr/include/mach/kern_return.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EDB009906D5286C00DBD1D5 = {
+               fRef = 6EDB008F06D525CE00DBD1D5;
+               isa = PBXTextBookmark;
+               name = "kern_return.h: 138";
+               rLen = 0;
+               rLoc = 4188;
+               rType = 0;
+               vrLen = 1280;
+               vrLoc = 2908;
+       };
+       6EDB014606D53E8400DBD1D5 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSThread.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSThread.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EDB01ED06D58C1100DBD1D5 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSNull.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSNull.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EDB021306D5AAD400DBD1D5 = {
+               fRef = 6EDB01ED06D58C1100DBD1D5;
+               isa = PBXTextBookmark;
+               name = "@interface NSNull : NSObject <NSCopying, NSCoding>\n";
+               rLen = 51;
+               rLoc = 108;
+               rType = 0;
+               vrLen = 185;
+               vrLoc = 0;
+       };
+       6EDB024D06D5B74700DBD1D5 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = objc.h;
+               path = /usr/include/objc/objc.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EDB02FE06D8156400DBD1D5 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSRunLoop.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSRunLoop.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EDB04F706D86E6400DBD1D5 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSConnection.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSConnection.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EDB05C806D96DA400DBD1D5 = {
+               fRef = 6EDB014606D53E8400DBD1D5;
+               isa = PBXTextBookmark;
+               name = "+ (NSThread *)currentThread;\n";
+               rLen = 29;
+               rLoc = 508;
+               rType = 0;
+               vrLen = 1139;
+               vrLoc = 373;
+       };
+       6EDB06E306DA7CC700DBD1D5 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = mig.h;
+               path = /usr/include/mach/mig.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EDB06E406DA8A7900DBD1D5 = {
+               fRef = 6EDB06E306DA7CC700DBD1D5;
+               isa = PBXTextBookmark;
+               name = "\tmach_msg_id_t\t\t start;\t\t\t/* Min routine number\t    */\n";
+               rLen = 55;
+               rLoc = 2977;
+               rType = 0;
+               vrLen = 1538;
+               vrLoc = 2145;
+       };
+       6EDB070D06DA910700DBD1D5 = {
+               fRef = 6EDB04F706D86E6400DBD1D5;
+               isa = PBXTextBookmark;
+               name = "- (NSDistantObject *)rootProxy;\n";
+               rLen = 32;
+               rLoc = 1820;
+               rType = 0;
+               vrLen = 1349;
+               vrLoc = 1027;
+       };
+       6EDB072A06DA921700DBD1D5 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSInvocation.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSInvocation.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EDB072B06DA926900DBD1D5 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSAppleEventDescriptor.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSAppleEventDescriptor.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EDB072F06DA92D800DBD1D5 = {
+               fRef = 6EDB072B06DA926900DBD1D5;
+               isa = PBXTextBookmark;
+               name = "- (Boolean)booleanValue;\n";
+               rLen = 25;
+               rLoc = 3403;
+               rType = 0;
+               vrLen = 1756;
+               vrLoc = 2413;
+       };
+       6EDB073506DA950800DBD1D5 = {
+               fRef = 6EDB072A06DA921700DBD1D5;
+               isa = PBXTextBookmark;
+               name = "- (void)getReturnValue:(void *)retLoc;\n";
+               rLen = 39;
+               rLoc = 1757;
+               rType = 0;
+               vrLen = 937;
+               vrLoc = 1131;
+       };
+       6EDB078E06DA9BAA00DBD1D5 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = "objc-api.h";
+               path = "/usr/include/objc/objc-api.h";
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EDB079A06DA9CBB00DBD1D5 = {
+               fRef = 6EDB079B06DA9CBB00DBD1D5;
+               isa = PBXTextBookmark;
+               name = objc_msgSend;
+               rLen = 12;
+               rLoc = 1972;
+               rType = 0;
+               vrLen = 1538;
+               vrLoc = 3137;
+       };
+       6EDB079B06DA9CBB00DBD1D5 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = "objc-runtime.h";
+               path = "/usr/include/objc/objc-runtime.h";
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EDB079C06DA9CBB00DBD1D5 = {
+               fRef = 6EDB078E06DA9BAA00DBD1D5;
+               isa = PBXTextBookmark;
+               name = "objc-api.h: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 1284;
+               vrLoc = 0;
+       };
+       6EDB07AC06DA9D7D00DBD1D5 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSAutoreleasePool.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSAutoreleasePool.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EDB07AD06DA9D9A00DBD1D5 = {
+               fRef = 6EDB07AC06DA9D7D00DBD1D5;
+               isa = PBXTextBookmark;
+               name = "@interface NSAutoreleasePool : NSObject {\n";
+               rLen = 42;
+               rLoc = 119;
+               rType = 0;
+               vrLen = 328;
+               vrLoc = 0;
+       };
+       6EDB07E006DAA3D200DBD1D5 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = kmod.h;
+               path = /usr/include/mach/kmod.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EDB07E106DAA3F700DBD1D5 = {
+               fRef = 6EDB07E006DAA3D200DBD1D5;
+               isa = PBXTextBookmark;
+               name = "\tint\t\t\tid;\n";
+               rLen = 11;
+               rLoc = 2599;
+               rType = 0;
+               vrLen = 1245;
+               vrLoc = 1892;
+       };
+       6EEA099A06BF83F200770544 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSString.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSString.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EEE8F0206DD23AA00788128 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSButton.h;
+               path = /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSButton.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EEE8F0C06DE3A6600788128 = {
+               fRef = 6EEE8F0206DD23AA00788128;
+               isa = PBXTextBookmark;
+               name = "NSButton.h: setBezelStyle:";
+               rLen = 0;
+               rLoc = 1609;
+               rType = 0;
+               vrLen = 1310;
+               vrLoc = 519;
+       };
+       6EEE8F0D06DE3A6600788128 = {
+               fRef = 6EEE8F0206DD23AA00788128;
+               isa = PBXTextBookmark;
+               name = "NSButton.h: setBezelStyle:";
+               rLen = 0;
+               rLoc = 1609;
+               rType = 0;
+               vrLen = 1310;
+               vrLoc = 519;
+       };
+       6EEE972906E14E9600788128 = {
+               fRef = 6ED806440641D305002888F7;
+               isa = PBXTextBookmark;
+               name = "HelpController.m: 20";
+               rLen = 0;
+               rLoc = 990;
+               rType = 0;
+               vrLen = 792;
+               vrLoc = 0;
+       };
+       6EEE972A06E14E9600788128 = {
+               fRef = 6ED806430641D305002888F7;
+               isa = PBXTextBookmark;
+               name = "HelpController.h: 13";
+               rLen = 0;
+               rLoc = 933;
+               rType = 0;
+               vrLen = 500;
+               vrLoc = 0;
+       };
+       6EEEB31A06E3FE1700788128 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSWindowController.h;
+               path = /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSWindowController.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EEEB31D06E3FF3600788128 = {
+               fRef = 6EEEB31A06E3FE1700788128;
+               isa = PBXTextBookmark;
+               name = "- (id)initWithWindowNibName:(NSString *)windowNibName;\t// self is the owner\n";
+               rLen = 76;
+               rLoc = 861;
+               rType = 0;
+               vrLen = 1553;
+               vrLoc = 0;
+       };
+       6EF2EFB90777C11B00C8B55A = {
+               fRef = 6E8181D1076E475200A5FBEB;
+               isa = PBXTextBookmark;
+               name = IntegerSign;
+               rLen = 0;
+               rLoc = 352;
+               rType = 0;
+               vrLen = 315;
+               vrLoc = 0;
+       };
+       6EF2F0A5077B3C0C00C8B55A = {
+               fRef = 6ECDE09D0643985000B1DD8A;
+               isa = PBXBookmark;
+       };
+       6EF2F0BF077B424000C8B55A = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {991, 2735}}";
+                       sepNavSelRange = "{2229, 65}";
+                       sepNavVisRect = "{{0, 1597}, {991, 678}}";
+               };
+       };
+       6EF2F224077B955F00C8B55A = {
+               fRef = 6ED806960641D498002888F7;
+               isa = PBXBookmark;
+       };
+       6EF2F227077B955F00C8B55A = {
+               fRef = 6ED806940641D498002888F7;
+               isa = PBXTextBookmark;
+               name = "English: 5";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 410;
+               vrLoc = 0;
+       };
+       6EF2F228077B955F00C8B55A = {
+               fRef = 6ED806960641D498002888F7;
+               isa = PBXBookmark;
+       };
+       6EFBA94007BDDFCE0052D697 = {
+               fRef = 6E6FD7C60762D7FC004FD845;
+               isa = PBXTextBookmark;
+               name = "- (void)increaseLengthBy:(unsigned)extraLength;\n";
+               rLen = 48;
+               rLoc = 2132;
+               rType = 0;
+               vrLen = 1384;
+               vrLoc = 1186;
+       };
+       6EFBA94A07BDE4170052D697 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = cdefs.h;
+               path = /usr/include/sys/cdefs.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EFBA94B07BDE4980052D697 = {
+               fRef = 6E9BF25307812D58008F0139;
+               isa = PBXTextBookmark;
+               name = "stdlib.h: calloc";
+               rLen = 0;
+               rLoc = 4400;
+               rType = 0;
+               vrLen = 1128;
+               vrLoc = 5304;
+       };
+       6EFBA94C07BDE4980052D697 = {
+               fRef = 6EFBA94A07BDE4170052D697;
+               isa = PBXTextBookmark;
+               name = "cdefs.h: __BEGIN_DECLS";
+               rLen = 0;
+               rLoc = 3116;
+               rType = 0;
+               vrLen = 869;
+               vrLoc = 5762;
+       };
+       6EFBA94E07BDE4980052D697 = {
+               fRef = 6E9BF25307812D58008F0139;
+               isa = PBXTextBookmark;
+               name = "stdlib.h: calloc";
+               rLen = 0;
+               rLoc = 4400;
+               rType = 0;
+               vrLen = 1128;
+               vrLoc = 5304;
+       };
+       6EFBA95607BDE5370052D697 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = fcntl.h;
+               path = /usr/include/fcntl.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EFBA95707BDE5370052D697 = {
+               fRef = 6E12D5FD076AC55100A95DFE;
+               isa = PBXTextBookmark;
+               name = "stdio.h: fopen";
+               rLen = 0;
+               rLoc = 8892;
+               rType = 0;
+               vrLen = 1713;
+               vrLoc = 4448;
+       };
+       6EFBA95B07BDE5770052D697 = {
+               fRef = 6EFBA95607BDE5370052D697;
+               isa = PBXTextBookmark;
+               name = "fcntl.h: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 1002;
+               vrLoc = 0;
+       };
+       6EFBA95D07BDE5770052D697 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = fcntl.h;
+               path = /usr/include/sys/fcntl.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EFBA95E07BDE5770052D697 = {
+               fRef = 6EFBA95607BDE5370052D697;
+               isa = PBXTextBookmark;
+               name = "fcntl.h: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 1002;
+               vrLoc = 0;
+       };
+       6EFBA96907BDEA150052D697 = {
+               fRef = 6EFBA95D07BDE5770052D697;
+               isa = PBXTextBookmark;
+               name = "fcntl.h: O_RDWR";
+               rLen = 0;
+               rLoc = 3958;
+               rType = 0;
+               vrLen = 1398;
+               vrLoc = 10167;
+       };
+       6EFBA97607BDEC830052D697 = {
+               fRef = 6E12D5FD076AC55100A95DFE;
+               isa = PBXTextBookmark;
+               name = "stdio.h: _read";
+               rLen = 0;
+               rLoc = 5326;
+               rType = 0;
+               vrLen = 1351;
+               vrLoc = 8712;
+       };
+       6EFBAB0507BEEDA90052D697 = {
+               fRef = 6EFBA95D07BDE5770052D697;
+               isa = PBXTextBookmark;
+               name = "int\tfcntl __P((int, int, ...));\n";
+               rLen = 32;
+               rLoc = 11408;
+               rType = 0;
+               vrLen = 1398;
+               vrLoc = 10167;
+       };
+       6EFBAB7907BFC40E0052D697 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSScriptClassDescription.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSScriptClassDescription.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EFBAB7C07BFC4200052D697 = {
+               fRef = 6EFBAB7907BFC40E0052D697;
+               isa = PBXTextBookmark;
+               name = "- (NSString *)keyWithAppleEventCode:(unsigned long)code;\n";
+               rLen = 57;
+               rLoc = 1670;
+               rType = 0;
+               vrLen = 1387;
+               vrLoc = 677;
+       };
+       6EFBABE707C0693F0052D697 = {
+               fRef = 6E3DC5E3077CE2B7004C82C0;
+               isa = PBXTextBookmark;
+               name = "#define\tFD_COPY(f, t)\tbcopy(f, t, sizeof(*(f)))\n";
+               rLen = 48;
+               rLoc = 5974;
+               rType = 0;
+               vrLen = 1159;
+               vrLoc = 5231;
+       };
+       6EFBABEA07C0693F0052D697 = {
+               fRef = 6E3DC5E3077CE2B7004C82C0;
+               isa = PBXTextBookmark;
+               name = "#define\tFD_COPY(f, t)\tbcopy(f, t, sizeof(*(f)))\n";
+               rLen = 48;
+               rLoc = 5974;
+               rType = 0;
+               vrLen = 1159;
+               vrLoc = 5231;
+       };
+       6EFBACAC07C082180052D697 = {
+               fRef = 6E31A14406B71EBA00E40AB3;
+               isa = PBXTextBookmark;
+               name = "ServerChild.m: 156";
+               rLen = 0;
+               rLoc = 4333;
+               rType = 0;
+               vrLen = 879;
+               vrLoc = 3675;
+       };
+       6EFBACBA07C082D90052D697 = {
+               fRef = 6EC06556078BE68300591D61;
+               isa = PBXTextBookmark;
+               name = "ChazUpdate.h: 23";
+               rLen = 0;
+               rLoc = 839;
+               rType = 0;
+               vrLen = 1290;
+               vrLoc = 0;
+       };
+       6EFBACF507C087650052D697 = {
+               fRef = 6E12D6B4076AFD5900A95DFE;
+               isa = PBXTextBookmark;
+               name = "NSTimer.h: timerWithTimeInterval:target:selector:userInfo:repeats:";
+               rLen = 0;
+               rLoc = 461;
+               rType = 0;
+               vrLen = 1133;
+               vrLoc = 0;
+       };
+       6EFBAD0D07C089110052D697 = {
+               fRef = 6ED8072706421B10002888F7;
+               isa = PBXTextBookmark;
+               name = "ServerPrefs.m: 76";
+               rLen = 0;
+               rLoc = 2493;
+               rType = 0;
+               vrLen = 965;
+               vrLoc = 3461;
+       };
+       6EFBAD1C07C08A070052D697 = {
+               fRef = 6EA39931077FAB48002B0E69;
+               isa = PBXTextBookmark;
+               name = "int\tgetsockopt __P((int, int, int, void *, int *));\n";
+               rLen = 52;
+               rLoc = 17619;
+               rType = 0;
+               vrLen = 1469;
+               vrLoc = 16959;
+       };
+       6EFBADB907C14A7D0052D697 = {
+               fRef = 6E6FD7AF0762D466004FD845;
+               isa = PBXTextBookmark;
+               name = "unistd.h: unlink";
+               rLen = 0;
+               rLoc = 6340;
+               rType = 0;
+               vrLen = 1151;
+               vrLoc = 5801;
+       };
+       6EFBADE507C162350052D697 = {
+               fRef = 6EA39943077FAC55002B0E69;
+               isa = PBXTextBookmark;
+               name = "\tu_short\tsin_port;\n";
+               rLen = 19;
+               rLoc = 13167;
+               rType = 0;
+               vrLen = 1174;
+               vrLoc = 12565;
+       };
+       6EFBAE2907C16A5F0052D697 = {
+               fRef = 6E83F53107B048BD00D9DACB;
+               isa = PBXTextBookmark;
+               name = "MySocket.m: 697";
+               rLen = 0;
+               rLoc = 15339;
+               rType = 0;
+               vrLen = 961;
+               vrLoc = 14302;
+       };
+       6EFBAEB307C1C79E0052D697 = {
+               fRef = 6E31A1B906B7286300E40AB3;
+               isa = PBXTextBookmark;
+               name = "else if ( strncmp( \"vars\", _header.name, sizeof(_header.name) ) == 0 ) {\n\t\tstruct varInfo {\n\t\t\tunsigned count;\n\t\t\tunsigned varCount;\n\t\t\tunsigned varSize;\n\t\t} *varInfo;\n\t\tvoid *bytes;\n\t\tTCArray variables;\n\t\tvarInfo = (struct varInfo *)[_parameters bytes];\n\t\tbytes = (void *)[_parameters bytes] + sizeof(*varInfo);\n\t\tvariables = TCMakeArrayWithBytes( varInfo->varCount, varInfo->varSize, bytes );\n\t\t[_delegate cheater:self didFindVariables:variables actualAmount:varInfo->count];\n\t}";
+               rLen = 480;
+               rLoc = 10600;
+               rType = 0;
+               vrLen = 1644;
+               vrLoc = 10526;
+       };
+       6EFBAEE707C1CBD40052D697 = {
+               fRef = 6E138C3106C1C140001C688F;
+               isa = PBXTextBookmark;
+               name = "- (void)setTemporaryStatus:(NSString *)message\n";
+               rLen = 47;
+               rLoc = 1865;
+               rType = 0;
+               vrLen = 1021;
+               vrLoc = 1451;
+       };
+       6EFBAF1007C1D0D90052D697 = {
+               fRef = 6E83F53007B048BD00D9DACB;
+               isa = PBXTextBookmark;
+               name = "MySocket.h: addressWithHost:port:";
+               rLen = 0;
+               rLoc = 3281;
+               rType = 0;
+               vrLen = 1224;
+               vrLoc = 2534;
+       };
+       6EFBAF1207C1D0D90052D697 = {
+               fRef = 6E83F53107B048BD00D9DACB;
+               isa = PBXTextBookmark;
+               name = "MySocket.m: 448";
+               rLen = 0;
+               rLoc = 9164;
+               rType = 0;
+               vrLen = 703;
+               vrLoc = 8811;
+       };
+       6EFBAF3A07C1D5950052D697 = {
+               fRef = 6E31A14306B71EBA00E40AB3;
+               isa = PBXTextBookmark;
+               name = "ServerChild.h: _client";
+               rLen = 0;
+               rLoc = 1097;
+               rType = 0;
+               vrLen = 679;
+               vrLoc = 801;
+       };
+       6EFBAF4907C1D6440052D697 = {
+               fRef = 6E31A1B806B7286300E40AB3;
+               isa = PBXTextBookmark;
+               name = "RemoteCheater.h: connectToHostWithData:";
+               rLen = 0;
+               rLoc = 1113;
+               rType = 0;
+               vrLen = 1200;
+               vrLoc = 0;
+       };
+       6EFBAF6E07C1D81C0052D697 = {
+               fRef = 6EA253F70786249800C839D1;
+               isa = PBXTextBookmark;
+               name = "void ChazLogDisable()\n";
+               rLen = 22;
+               rLoc = 522;
+               rType = 0;
+               vrLen = 663;
+               vrLoc = 189;
+       };
+       6EFBAF8007C1D8E80052D697 = {
+               fRef = 6ED806830641D434002888F7;
+               isa = PBXTextBookmark;
+               name = "main.m: 29";
+               rLen = 0;
+               rLoc = 1038;
+               rType = 0;
+               vrLen = 1187;
+               vrLoc = 0;
+       };
+       6EFBB01907C295BB0052D697 = {
+               fRef = 6EDB02FE06D8156400DBD1D5;
+               isa = PBXTextBookmark;
+               name = "NSRunLoop.h: performSelector:withObject:afterDelay:";
+               rLen = 0;
+               rLoc = 1320;
+               rType = 0;
+               vrLen = 1383;
+               vrLoc = 591;
+       };
+       6EFBB03107C297D00052D697 = {
+               fRef = 6E6FD69C0762B626004FD845;
+               isa = PBXTextBookmark;
+               name = "ThreadedTask.m: 286";
+               rLen = 0;
+               rLoc = 7151;
+               rType = 0;
+               vrLen = 1083;
+               vrLoc = 6491;
+       };
+       6EFBB04707C298530052D697 = {
+               fRef = 6E6FD69B0762B626004FD845;
+               isa = PBXTextBookmark;
+               name = "ThreadedTask.h: _modes";
+               rLen = 0;
+               rLoc = 2045;
+               rType = 0;
+               vrLen = 1240;
+               vrLoc = 1640;
+       };
+       6EFBB1F607C2D1950052D697 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = Chaz.h;
+               path = /Users/chaz/Projects/chazlib/Chaz.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EFBB1FC07C2D1A30052D697 = {
+               fRef = 6EFBB1F607C2D1950052D697;
+               isa = PBXTextBookmark;
+               name = "Chaz.h: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 532;
+               vrLoc = 0;
+       };
+       6EFBB1FE07C2D1A30052D697 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = cltypes.h;
+               path = /Users/chaz/Projects/chazlib/cltypes.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EFBB1FF07C2D1A30052D697 = {
+               fRef = 6EFBB1F607C2D1950052D697;
+               isa = PBXTextBookmark;
+               name = "Chaz.h: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 532;
+               vrLoc = 0;
+       };
+       6EFBB20407C2D35A0052D697 = {
+               fRef = 6EFBB1FE07C2D1A30052D697;
+               isa = PBXTextBookmark;
+               name = "cltypes.h: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 759;
+               vrLoc = 82;
+       };
+       6EFBB20507C2D35A0052D697 = {
+               fRef = 6EFBB20607C2D35A0052D697;
+               isa = PBXTextBookmark;
+               name = "if ( eps > fabsf( a - b ) ) {\n\t\treturn 0;\n\t}\n\telse if ( a < b ) {\n\t\treturn -1;\n\t}\n\treturn 1;";
+               rLen = 92;
+               rLoc = 2459;
+               rType = 0;
+               vrLen = 794;
+               vrLoc = 2184;
+       };
+       6EFBB20607C2D35A0052D697 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.c;
+               name = CLmath.c;
+               path = /Users/chaz/Projects/chazlib/CLmath.c;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EFBB20C07C2D35A0052D697 = {
+               fRef = 6EFBB1FE07C2D1A30052D697;
+               isa = PBXTextBookmark;
+               name = "cltypes.h: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 759;
+               vrLoc = 82;
+       };
+       6EFBB20D07C2D35A0052D697 = {
+               fRef = 6EFBB20E07C2D35A0052D697;
+               isa = PBXTextBookmark;
+               name = "if ( eps > fabsf( a - b ) ) {\n\t\treturn 0;\n\t}\n\telse if ( a < b ) {\n\t\treturn -1;\n\t}\n\treturn 1;";
+               rLen = 92;
+               rLoc = 2459;
+               rType = 0;
+               vrLen = 794;
+               vrLoc = 2184;
+       };
+       6EFBB20E07C2D35A0052D697 = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.c;
+               name = CLmath.c;
+               path = /Users/chaz/Projects/chazlib/CLmath.c;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EFBB24E07C2DBF90052D697 = {
+               fRef = 6E9BF4B0078287DF008F0139;
+               isa = PBXTextBookmark;
+               name = "Searching.h: 20";
+               rLen = 0;
+               rLoc = 359;
+               rType = 0;
+               vrLen = 1562;
+               vrLoc = 0;
+       };
+       6EFBB27107C2DFA10052D697 = {
+               fRef = 6EAB44F706CB39CD00A4ABF0;
+               isa = PBXTextBookmark;
+               name = "int\t memcmp(const void *, const void *, size_t);\n";
+               rLen = 49;
+               rLoc = 3128;
+               rType = 0;
+               vrLen = 1426;
+               vrLoc = 2717;
+       };
+       6EFBB28207C2E3940052D697 = {
+               fRef = 6E9BF4B1078287DF008F0139;
+               isa = PBXTextBookmark;
+               name = "Searching.m: 46";
+               rLen = 0;
+               rLoc = 1209;
+               rType = 0;
+               vrLen = 1128;
+               vrLoc = 358;
+       };
+       6EFBB2CC07C2EAE90052D697 = {
+               fRef = 6E31A1B906B7286300E40AB3;
+               isa = PBXTextBookmark;
+               name = "RemoteCheater.m: 81";
+               rLen = 0;
+               rLoc = 2035;
+               rType = 0;
+               vrLen = 1278;
+               vrLoc = 1269;
+       };
+       6EFBB3DB07C411B10052D697 = {
+               fRef = 6E8181D2076E475200A5FBEB;
+               isa = PBXTextBookmark;
+               name = "SearchData.m: 173";
+               rLen = 0;
+               rLoc = 3048;
+               rType = 0;
+               vrLen = 1014;
+               vrLoc = 2472;
+       };
+       6EFBB40507C415970052D697 = {
+               fRef = 6ED97B9D0645E85700CBF037;
+               isa = PBXTextBookmark;
+               name = isListening;
+               rLen = 11;
+               rLoc = 1794;
+               rType = 0;
+               vrLen = 1367;
+               vrLoc = 419;
+       };
+       6EFBB46007C41FCA0052D697 = {
+               fRef = 6E38D61706C9F7A8003BA9B4;
+               isa = PBXTextBookmark;
+               name = "Cheater.h: limitReturnedResults:";
+               rLen = 0;
+               rLoc = 2375;
+               rType = 0;
+               vrLen = 1465;
+               vrLoc = 1821;
+       };
+       6EFBB46107C41FCA0052D697 = {
+               fRef = 6E38D61806C9F7A8003BA9B4;
+               isa = PBXTextBookmark;
+               name = "Cheater.m: 60";
+               rLen = 0;
+               rLoc = 1647;
+               rType = 0;
+               vrLen = 1491;
+               vrLoc = 2804;
+       };
+       6EFE498107B7458700F67D2B = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = time.h;
+               path = /usr/include/sys/time.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EFE498707B7459800F67D2B = {
+               fRef = 6EFE498107B7458700F67D2B;
+               isa = PBXTextBookmark;
+               name = "int\tgettimeofday __P((struct timeval *, struct timezone *));\n";
+               rLen = 61;
+               rLoc = 6358;
+               rType = 0;
+               vrLen = 1216;
+               vrLoc = 5486;
+       };
+       6EFE49EC07B823CF00F67D2B = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = CFDate.h;
+               path = /System/Library/Frameworks/CoreFoundation.framework/Versions/A/Headers/CFDate.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EFE49ED07B824F200F67D2B = {
+               fRef = 6EFE49EC07B823CF00F67D2B;
+               isa = PBXTextBookmark;
+               name = CFAbsoluteTimeGetCurrent;
+               rLen = 24;
+               rLoc = 457;
+               rType = 0;
+               vrLen = 964;
+               vrLoc = 0;
+       };
+       6EFE4AD907B8854400F67D2B = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSDistantObject.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSDistantObject.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EFE4B0307B8924D00F67D2B = {
+               fRef = 6EFE4AD907B8854400F67D2B;
+               isa = PBXTextBookmark;
+               name = "NSDistantObject.h: conn";
+               rLen = 0;
+               rLoc = 331;
+               rType = 0;
+               vrLen = 819;
+               vrLoc = 0;
+       };
+       6EFE4B0607B8924D00F67D2B = {
+               fRef = 6ED97B9E0645E85700CBF037;
+               isa = PBXTextBookmark;
+               name = "CheatServer.m: 93";
+               rLen = 0;
+               rLoc = 2520;
+               rType = 0;
+               vrLen = 894;
+               vrLoc = 2107;
+       };
+       6EFE4B9107B9654300F67D2B = {
+               fRef = 6E63977506434C0800BD3765;
+               isa = PBXTextBookmark;
+               name = "typedef UInt8                           Byte;\n";
+               rLen = 46;
+               rLoc = 24934;
+               rType = 0;
+               vrLen = 1795;
+               vrLoc = 23931;
+       };
+       6EFE4C0C07B9761E00F67D2B = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = errno.h;
+               path = /usr/include/sys/errno.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EFE4C0F07B9763800F67D2B = {
+               fRef = 6EFE4C0C07B9761E00F67D2B;
+               isa = PBXTextBookmark;
+               name = "#define errno (*__error())\n";
+               rLen = 27;
+               rLoc = 3359;
+               rType = 0;
+               vrLen = 1487;
+               vrLoc = 2523;
+       };
+       6EFE4C6D07B982E300F67D2B = {
+               fRef = 6E38D4E506C9D6F7003BA9B4;
+               isa = PBXTextBookmark;
+               name = "- (id)initWithObjects:(id)firstObj, ...;\n";
+               rLen = 41;
+               rLoc = 2475;
+               rType = 0;
+               vrLen = 1269;
+               vrLoc = 1863;
+       };
+       6EFE4CC907B99A7C00F67D2B = {
+               fRef = 6E38D32F06C99E71003BA9B4;
+               isa = PBXTextBookmark;
+               name = "FOUNDATION_STATIC_INLINE NSRange NSMakeRange(unsigned int loc, unsigned int len) {\n";
+               rLen = 83;
+               rLoc = 250;
+               rType = 0;
+               vrLen = 1143;
+               vrLoc = 0;
+       };
+       6EFE4CD407B99E0C00F67D2B = {
+               fRef = 6E3DC5F3077CE552004C82C0;
+               isa = PBXTextBookmark;
+               name = "- (id)initWithObjectsAndKeys:(id)firstObject, ...;\n";
+               rLen = 51;
+               rLoc = 1811;
+               rType = 0;
+               vrLen = 1599;
+               vrLoc = 839;
+       };
+       6EFE4CD707B99E0C00F67D2B = {
+               fRef = 6E83F53007B048BD00D9DACB;
+               isa = PBXTextBookmark;
+               name = "MySocket.h: _unclaimedReadBytes";
+               rLen = 0;
+               rLoc = 1513;
+               rType = 0;
+               vrLen = 1103;
+               vrLoc = 757;
+       };
+       6EFE4DF907B9D23100F67D2B = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSArchiver.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSArchiver.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EFE4DFF07B9D39B00F67D2B = {
+               fRef = 6EFE4DF907B9D23100F67D2B;
+               isa = PBXTextBookmark;
+               name = unarchiveObjectWithData;
+               rLen = 23;
+               rLoc = 1579;
+               rType = 0;
+               vrLen = 1086;
+               vrLoc = 967;
+       };
+       6EFE4EAC07BABEBC00F67D2B = {
+               fRef = 6E10944406D4202100E343E0;
+               isa = PBXTextBookmark;
+               name = "- (void)setDoubleValue:(double)doubleValue;\n";
+               rLen = 44;
+               rLoc = 2844;
+               rType = 0;
+               vrLen = 1104;
+               vrLoc = 2453;
+       };
+       6EFE4EB407BABEBC00F67D2B = {
+               fRef = 6E10944406D4202100E343E0;
+               isa = PBXTextBookmark;
+               name = "- (void)setDoubleValue:(double)doubleValue;\n";
+               rLen = 44;
+               rLoc = 2844;
+               rType = 0;
+               vrLen = 1104;
+               vrLoc = 2453;
+       };
+       6EFE4EC107BABF2500F67D2B = {
+               fRef = 6E98A54C06A740EE006A576D;
+               isa = PBXBookmark;
+       };
+       6EFE4F5807BB021400F67D2B = {
+               fRef = 6EFFEFCB0691FA0800A30A6B;
+               isa = PBXTextBookmark;
+               name = "- (unsigned int)unsignedIntValue;\n";
+               rLen = 34;
+               rLoc = 941;
+               rType = 0;
+               vrLen = 913;
+               vrLoc = 521;
+       };
+       6EFE4F6207BB021400F67D2B = {
+               fRef = 6EFFEFCB0691FA0800A30A6B;
+               isa = PBXTextBookmark;
+               name = unsignedCharValue;
+               rLen = 17;
+               rLoc = 846;
+               rType = 0;
+               vrLen = 922;
+               vrLoc = 72;
+       };
+       6EFE4F6C07BB021400F67D2B = {
+               fRef = 6E31A16C06B723CB00E40AB3;
+               isa = PBXTextBookmark;
+               name = "variables = TCMakeArray( TCArrayElementCount(searchContext->variables), TCArrayElementSize(searchContext->variables) );\n\t\t\tvariabse->_bytes = TCArrayBytes(searchContext->variables);";
+               rLen = 124;
+               rLoc = 15128;
+               rType = 0;
+               vrLen = 1490;
+               vrLoc = 13707;
+       };
+       6EFE4F7B07BB07E900F67D2B = {
+               fRef = 6EF2F0BF077B424000C8B55A;
+               isa = PBXTextBookmark;
+               name = TCArrayCopyContainer;
+               rLen = 135;
+               rLoc = 2996;
+               rType = 0;
+               vrLen = 1151;
+               vrLoc = 2328;
+       };
+       6EFE4F9D07BB2D7F00F67D2B = {
+               fRef = 6E9BF5030782926E008F0139;
+               isa = PBXTextBookmark;
+               name = "CheaterTypes.m: 36";
+               rLen = 0;
+               rLoc = 665;
+               rType = 0;
+               vrLen = 779;
+               vrLoc = 36;
+       };
+       6EFE4FD507BB32CB00F67D2B = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = CFSocket.h;
+               path = /System/Library/Frameworks/CoreFoundation.framework/Versions/A/Headers/CFSocket.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EFE4FD607BB337E00F67D2B = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = CFBase.h;
+               path = /System/Library/Frameworks/CoreFoundation.framework/Versions/A/Headers/CFBase.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       6EFE4FD907BB33BA00F67D2B = {
+               fRef = 6EFE4FD507BB32CB00F67D2B;
+               isa = PBXTextBookmark;
+               name = "CF_EXPORT CFSocketRef\tCFSocketCreate(CFAllocatorRef allocator, SInt32 protocolFamily, SInt32 socketType, SInt32 protocol, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context);\n";
+               rLen = 210;
+               rLoc = 5909;
+               rType = 0;
+               vrLen = 2858;
+               vrLoc = 5306;
+       };
+       6EFE4FDA07BB33BA00F67D2B = {
+               fRef = 6EFE4FD607BB337E00F67D2B;
+               isa = PBXTextBookmark;
+               name = "void CFRelease(CFTypeRef cf);\n";
+               rLen = 30;
+               rLoc = 9335;
+               rType = 0;
+               vrLen = 742;
+               vrLoc = 8924;
+       };
+       6EFE4FDE07BB33BA00F67D2B = {
+               fRef = 6EFE4FD507BB32CB00F67D2B;
+               isa = PBXTextBookmark;
+               name = "CF_EXPORT CFSocketRef\tCFSocketCreate(CFAllocatorRef allocator, SInt32 protocolFamily, SInt32 socketType, SInt32 protocol, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context);\n";
+               rLen = 210;
+               rLoc = 5909;
+               rType = 0;
+               vrLen = 2858;
+               vrLoc = 5306;
+       };
+       6EFFEFCB0691FA0800A30A6B = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = NSValue.h;
+               path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSValue.h;
+               refType = 0;
+               sourceTree = "<absolute>";
+       };
+       8D1107260486CEB800E47090 = {
+               activeExec = 0;
+               executables = (
+                       6ED806180641D21A002888F7,
+               );
+       };
+}
diff --git a/The Cheat.xcode/project.pbxproj b/The Cheat.xcode/project.pbxproj
new file mode 100644 (file)
index 0000000..70aeccc
--- /dev/null
@@ -0,0 +1,1886 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 39;
+       objects = {
+               080E96DDFE201D6D7F000001 = {
+                       children = (
+                               6ED806310641D2E9002888F7,
+                               6ED806320641D2E9002888F7,
+                               6ED8062F0641D2E9002888F7,
+                               6ED806300641D2E9002888F7,
+                               6ED806430641D305002888F7,
+                               6ED806440641D305002888F7,
+                               6EB3579A07C83C60000347B9,
+                               6EB3579B07C83C60000347B9,
+                               6ED807190641EC6E002888F7,
+                       );
+                       isa = PBXGroup;
+                       name = Controllers;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+//080
+//081
+//082
+//083
+//084
+//100
+//101
+//102
+//103
+//104
+               1058C7A0FEA54F0111CA2CBB = {
+                       children = (
+                               6E63969806423AFE00BD3765,
+                               1058C7A1FEA54F0111CA2CBB,
+                               6ED806FA0641E70F002888F7,
+                       );
+                       isa = PBXGroup;
+                       name = "Linked Frameworks";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               1058C7A1FEA54F0111CA2CBB = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = wrapper.framework;
+                       name = Cocoa.framework;
+                       path = /System/Library/Frameworks/Cocoa.framework;
+                       refType = 0;
+                       sourceTree = "<absolute>";
+               };
+               1058C7A2FEA54F0111CA2CBB = {
+                       children = (
+                               29B97325FDCFA39411CA2CEA,
+                               29B97324FDCFA39411CA2CEA,
+                       );
+                       isa = PBXGroup;
+                       name = "Other Frameworks";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+//100
+//101
+//102
+//103
+//104
+//190
+//191
+//192
+//193
+//194
+               19C28FACFE9D520D11CA2CBB = {
+                       children = (
+                               8D1107320486CEB800E47090,
+                       );
+                       isa = PBXGroup;
+                       name = Products;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+//190
+//191
+//192
+//193
+//194
+//290
+//291
+//292
+//293
+//294
+               29B97313FDCFA39411CA2CEA = {
+                       buildSettings = {
+                       };
+                       buildStyles = (
+                               4A9504CCFFE6A4B311CA0CBA,
+                               4A9504CDFFE6A4B311CA0CBA,
+                       );
+                       hasScannedForEncodings = 1;
+                       isa = PBXProject;
+                       mainGroup = 29B97314FDCFA39411CA2CEA;
+                       projectDirPath = "";
+                       targets = (
+                               8D1107260486CEB800E47090,
+                       );
+               };
+               29B97314FDCFA39411CA2CEA = {
+                       children = (
+                               080E96DDFE201D6D7F000001,
+                               6E98A54A06A73E37006A576D,
+                               6E38D68006C9F98E003BA9B4,
+                               6ED97B900645E2EE00CBF037,
+                               6E7157BC0647004B00763517,
+                               6ED806580641D343002888F7,
+                               6ED806700641D3AC002888F7,
+                               29B97315FDCFA39411CA2CEA,
+                               29B97317FDCFA39411CA2CEA,
+                               29B97323FDCFA39411CA2CEA,
+                               19C28FACFE9D520D11CA2CBB,
+                       );
+                       isa = PBXGroup;
+                       name = "The Cheat";
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               29B97315FDCFA39411CA2CEA = {
+                       children = (
+                               6ED806830641D434002888F7,
+                               6ED806790641D41B002888F7,
+                               6ED8067A0641D41B002888F7,
+                               6EA253F60786249800C839D1,
+                               6EA253F70786249800C839D1,
+                               6EC06556078BE68300591D61,
+                               6EC06557078BE68300591D61,
+                               32CA4F630368D1EE00C91783,
+                       );
+                       isa = PBXGroup;
+                       name = "Other Sources";
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               29B97317FDCFA39411CA2CEA = {
+                       children = (
+                               6ED806950641D498002888F7,
+                               6ED8068F0641D498002888F7,
+                               6ED806910641D498002888F7,
+                               6ED806990641D498002888F7,
+                               6E98A54B06A740EE006A576D,
+                               6EF2F08B077A7BFC00C8B55A,
+                               6EB357C907C83E9D000347B9,
+                               6EC06600078BFBE900591D61,
+                               6ED806930641D498002888F7,
+                               6ED806D00641D5F2002888F7,
+                       );
+                       isa = PBXGroup;
+                       name = Resources;
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               29B97323FDCFA39411CA2CEA = {
+                       children = (
+                               1058C7A0FEA54F0111CA2CBB,
+                               1058C7A2FEA54F0111CA2CBB,
+                       );
+                       isa = PBXGroup;
+                       name = Frameworks;
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               29B97324FDCFA39411CA2CEA = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = wrapper.framework;
+                       name = AppKit.framework;
+                       path = /System/Library/Frameworks/AppKit.framework;
+                       refType = 0;
+                       sourceTree = "<absolute>";
+               };
+               29B97325FDCFA39411CA2CEA = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = wrapper.framework;
+                       name = Foundation.framework;
+                       path = /System/Library/Frameworks/Foundation.framework;
+                       refType = 0;
+                       sourceTree = "<absolute>";
+               };
+//290
+//291
+//292
+//293
+//294
+//320
+//321
+//322
+//323
+//324
+               32CA4F630368D1EE00C91783 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = The_Cheat_Prefix.pch;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+//320
+//321
+//322
+//323
+//324
+//4A0
+//4A1
+//4A2
+//4A3
+//4A4
+               4A9504CCFFE6A4B311CA0CBA = {
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               DEBUGGING_SYMBOLS = YES;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               OPTIMIZATION_CFLAGS = "-O0";
+                               ZERO_LINK = YES;
+                       };
+                       isa = PBXBuildStyle;
+                       name = Development;
+               };
+               4A9504CDFFE6A4B311CA0CBA = {
+                       buildSettings = {
+                               COPY_PHASE_STRIP = YES;
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               ZERO_LINK = NO;
+                       };
+                       isa = PBXBuildStyle;
+                       name = Deployment;
+               };
+//4A0
+//4A1
+//4A2
+//4A3
+//4A4
+//6E0
+//6E1
+//6E2
+//6E3
+//6E4
+               6E138BF606C18765001C688F = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = Process.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E138BF706C18765001C688F = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = Process.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E138BF806C18765001C688F = {
+                       fileRef = 6E138BF606C18765001C688F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E138BF906C18765001C688F = {
+                       fileRef = 6E138BF706C18765001C688F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E138C3006C1C140001C688F = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = StatusTextField.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E138C3106C1C140001C688F = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = StatusTextField.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E138C3206C1C140001C688F = {
+                       fileRef = 6E138C3006C1C140001C688F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E138C3306C1C140001C688F = {
+                       fileRef = 6E138C3106C1C140001C688F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E31A14306B71EBA00E40AB3 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = ServerChild.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E31A14406B71EBA00E40AB3 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = ServerChild.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E31A14506B71EBA00E40AB3 = {
+                       fileRef = 6E31A14306B71EBA00E40AB3;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E31A14606B71EBA00E40AB3 = {
+                       fileRef = 6E31A14406B71EBA00E40AB3;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E31A16B06B723CB00E40AB3 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = LocalCheater.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E31A16C06B723CB00E40AB3 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = LocalCheater.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E31A16D06B723CB00E40AB3 = {
+                       fileRef = 6E31A16B06B723CB00E40AB3;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E31A16E06B723CB00E40AB3 = {
+                       fileRef = 6E31A16C06B723CB00E40AB3;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E31A1B806B7286300E40AB3 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = RemoteCheater.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E31A1B906B7286300E40AB3 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = RemoteCheater.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E31A1BA06B7286300E40AB3 = {
+                       fileRef = 6E31A1B806B7286300E40AB3;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E31A1BB06B7286300E40AB3 = {
+                       fileRef = 6E31A1B906B7286300E40AB3;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E38D3FD06C9B71F003BA9B4 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = BetterTableView.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E38D3FE06C9B71F003BA9B4 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = BetterTableView.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E38D3FF06C9B71F003BA9B4 = {
+                       fileRef = 6E38D3FD06C9B71F003BA9B4;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E38D40006C9B71F003BA9B4 = {
+                       fileRef = 6E38D3FE06C9B71F003BA9B4;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E38D61706C9F7A8003BA9B4 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = Cheater.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E38D61806C9F7A8003BA9B4 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = Cheater.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E38D61906C9F7A8003BA9B4 = {
+                       fileRef = 6E38D61706C9F7A8003BA9B4;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E38D61A06C9F7A8003BA9B4 = {
+                       fileRef = 6E38D61806C9F7A8003BA9B4;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E38D68006C9F98E003BA9B4 = {
+                       children = (
+                               6EF2F0BF077B424000C8B55A,
+                               6E9BF5030782926E008F0139,
+                               6E31A16B06B723CB00E40AB3,
+                               6E31A16C06B723CB00E40AB3,
+                               6E31A1B806B7286300E40AB3,
+                               6E31A1B906B7286300E40AB3,
+                               6E38D61706C9F7A8003BA9B4,
+                               6E38D61806C9F7A8003BA9B4,
+                               6E6FD6B10762B965004FD845,
+                               6E6FD6B20762B965004FD845,
+                               6E9BF4B0078287DF008F0139,
+                               6E9BF4B1078287DF008F0139,
+                               6E6FDC240765858A004FD845,
+                               6E6FDC250765858A004FD845,
+                               6E138BF606C18765001C688F,
+                               6E138BF706C18765001C688F,
+                               6E3D7D3C06C44CFE00A73B29,
+                               6E3D7D3D06C44CFE00A73B29,
+                       );
+                       isa = PBXGroup;
+                       name = Cheating;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E3D7D3C06C44CFE00A73B29 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = Variable.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E3D7D3D06C44CFE00A73B29 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = Variable.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E3D7D3E06C44CFE00A73B29 = {
+                       fileRef = 6E3D7D3C06C44CFE00A73B29;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E3D7D3F06C44CFE00A73B29 = {
+                       fileRef = 6E3D7D3D06C44CFE00A73B29;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E63969806423AFE00BD3765 = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = wrapper.framework;
+                       name = Carbon.framework;
+                       path = /System/Library/Frameworks/Carbon.framework;
+                       refType = 0;
+                       sourceTree = "<absolute>";
+               };
+               6E63969906423AFE00BD3765 = {
+                       fileRef = 6E63969806423AFE00BD3765;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E6FD69B0762B626004FD845 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = ThreadedTask.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E6FD69C0762B626004FD845 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = ThreadedTask.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E6FD69D0762B626004FD845 = {
+                       fileRef = 6E6FD69B0762B626004FD845;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E6FD69E0762B626004FD845 = {
+                       fileRef = 6E6FD69C0762B626004FD845;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E6FD6B10762B965004FD845 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = SearchContext.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E6FD6B20762B965004FD845 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = SearchContext.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E6FD6B30762B965004FD845 = {
+                       fileRef = 6E6FD6B10762B965004FD845;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E6FD6B40762B965004FD845 = {
+                       fileRef = 6E6FD6B20762B965004FD845;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E6FD8FA0764D1B0004FD845 = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = image.tiff;
+                       path = Lock.tif;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E6FD8FB0764D1B0004FD845 = {
+                       fileRef = 6E6FD8FA0764D1B0004FD845;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E6FD9FE0764EDE4004FD845 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = FadeView.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E6FD9FF0764EDE4004FD845 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = FadeView.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E6FDA000764EDE4004FD845 = {
+                       fileRef = 6E6FD9FE0764EDE4004FD845;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E6FDA010764EDE4004FD845 = {
+                       fileRef = 6E6FD9FF0764EDE4004FD845;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E6FDC240765858A004FD845 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = DumpContext.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E6FDC250765858A004FD845 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = DumpContext.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E6FDC260765858A004FD845 = {
+                       fileRef = 6E6FDC240765858A004FD845;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E6FDC270765858A004FD845 = {
+                       fileRef = 6E6FDC250765858A004FD845;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E7157BC0647004B00763517 = {
+                       children = (
+                               6E6FD69B0762B626004FD845,
+                               6E6FD69C0762B626004FD845,
+                               6EAB490B06CC4FEA00A4ABF0,
+                               6EAB490C06CC4FEA00A4ABF0,
+                       );
+                       isa = PBXGroup;
+                       name = "The Core";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E72B20D06AA5B0E00951D50 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = CheatData.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E72B20E06AA5B0E00951D50 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = CheatData.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E72B20F06AA5B0E00951D50 = {
+                       fileRef = 6E72B20D06AA5B0E00951D50;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E72B21006AA5B0E00951D50 = {
+                       fileRef = 6E72B20E06AA5B0E00951D50;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E7614A206A47A790051C301 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = CheatDocument.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E7614A306A47A790051C301 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = CheatDocument.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E7614A406A47A790051C301 = {
+                       fileRef = 6E7614A206A47A790051C301;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E7614A506A47A790051C301 = {
+                       fileRef = 6E7614A306A47A790051C301;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E8181D1076E475200A5FBEB = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = SearchData.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E8181D2076E475200A5FBEB = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = SearchData.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E8181D3076E475200A5FBEB = {
+                       fileRef = 6E8181D1076E475200A5FBEB;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E8181D4076E475200A5FBEB = {
+                       fileRef = 6E8181D2076E475200A5FBEB;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E83F53007B048BD00D9DACB = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = MySocket.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E83F53107B048BD00D9DACB = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = MySocket.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E83F53207B048BD00D9DACB = {
+                       fileRef = 6E83F53007B048BD00D9DACB;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E83F53307B048BD00D9DACB = {
+                       fileRef = 6E83F53107B048BD00D9DACB;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E98A54A06A73E37006A576D = {
+                       children = (
+                               6E7614A206A47A790051C301,
+                               6E7614A306A47A790051C301,
+                               6EA39693077F4025002B0E69,
+                               6EA3969B077F419A002B0E69,
+                               6E72B20D06AA5B0E00951D50,
+                               6E72B20E06AA5B0E00951D50,
+                               6E8181D1076E475200A5FBEB,
+                               6E8181D2076E475200A5FBEB,
+                       );
+                       isa = PBXGroup;
+                       name = Document;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E98A54B06A740EE006A576D = {
+                       children = (
+                               6E98A54C06A740EE006A576D,
+                       );
+                       isa = PBXVariantGroup;
+                       name = CheatDocument.nib;
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E98A54C06A740EE006A576D = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = wrapper.nib;
+                       name = English;
+                       path = English.lproj/CheatDocument.nib;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E98A54D06A740EE006A576D = {
+                       fileRef = 6E98A54B06A740EE006A576D;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E9BF31F0781EEC3008F0139 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = TrackerScroller.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E9BF3200781EEC3008F0139 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = TrackerScroller.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E9BF3210781EEC3008F0139 = {
+                       fileRef = 6E9BF31F0781EEC3008F0139;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E9BF3220781EEC3008F0139 = {
+                       fileRef = 6E9BF3200781EEC3008F0139;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E9BF3BA07820415008F0139 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = VariableTable.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E9BF3BB07820415008F0139 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = VariableTable.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E9BF3BC07820415008F0139 = {
+                       fileRef = 6E9BF3BA07820415008F0139;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E9BF3BD07820415008F0139 = {
+                       fileRef = 6E9BF3BB07820415008F0139;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E9BF4B0078287DF008F0139 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = Searching.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E9BF4B1078287DF008F0139 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = Searching.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E9BF4B2078287DF008F0139 = {
+                       fileRef = 6E9BF4B0078287DF008F0139;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E9BF4B3078287DF008F0139 = {
+                       fileRef = 6E9BF4B1078287DF008F0139;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E9BF5030782926E008F0139 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = CheaterTypes.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E9BF5040782926E008F0139 = {
+                       fileRef = 6E9BF5030782926E008F0139;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6EA253F60786249800C839D1 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = ChazLog.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EA253F70786249800C839D1 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = ChazLog.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EA253F80786249800C839D1 = {
+                       fileRef = 6EA253F60786249800C839D1;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6EA253F90786249800C839D1 = {
+                       fileRef = 6EA253F70786249800C839D1;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6EA39693077F4025002B0E69 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = DocInterfaceActions.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EA39694077F4025002B0E69 = {
+                       fileRef = 6EA39693077F4025002B0E69;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6EA3969B077F419A002B0E69 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = DocCheaterDelegate.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EA3969C077F419A002B0E69 = {
+                       fileRef = 6EA3969B077F419A002B0E69;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6EAB490B06CC4FEA00A4ABF0 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = VMRegion.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EAB490C06CC4FEA00A4ABF0 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = VMRegion.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EAB490D06CC4FEA00A4ABF0 = {
+                       fileRef = 6EAB490B06CC4FEA00A4ABF0;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6EAB490E06CC4FEA00A4ABF0 = {
+                       fileRef = 6EAB490C06CC4FEA00A4ABF0;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6EB3528707C56771000347B9 = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = image.icns;
+                       path = icon.icns;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EB3528807C56771000347B9 = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = image.icns;
+                       path = icondoc.icns;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EB3528907C56771000347B9 = {
+                       fileRef = 6EB3528707C56771000347B9;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6EB3528A07C56771000347B9 = {
+                       fileRef = 6EB3528807C56771000347B9;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6EB3578E07C83B99000347B9 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text.plist.scriptTerminology;
+                       path = CheatURLHandler.scriptTerminology;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EB3578F07C83B99000347B9 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text.plist.scriptSuite;
+                       path = CheatURLHandler.scriptSuite;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EB3579007C83B99000347B9 = {
+                       fileRef = 6EB3578E07C83B99000347B9;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6EB3579107C83B99000347B9 = {
+                       fileRef = 6EB3578F07C83B99000347B9;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6EB3579A07C83C60000347B9 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = CheatURLCommand.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EB3579B07C83C60000347B9 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = CheatURLCommand.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EB3579C07C83C60000347B9 = {
+                       fileRef = 6EB3579A07C83C60000347B9;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6EB3579D07C83C60000347B9 = {
+                       fileRef = 6EB3579B07C83C60000347B9;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6EB357C907C83E9D000347B9 = {
+                       children = (
+                               6EB3578F07C83B99000347B9,
+                               6EB3578E07C83B99000347B9,
+                       );
+                       isa = PBXGroup;
+                       name = AppleScript;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EB35A2D07C9C7C8000347B9 = {
+                       buildActionMask = 2147483647;
+                       dstPath = /;
+                       dstSubfolderSpec = 0;
+                       files = (
+                       );
+                       isa = PBXCopyFilesBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               6EB35AA107CA5FE0000347B9 = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = image.png;
+                       path = Update.png;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EB35AA207CA5FE0000347B9 = {
+                       fileRef = 6EB35AA107CA5FE0000347B9;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6EB35B3507CA6BCC000347B9 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = UpdatePrefs.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EB35B3607CA6BCC000347B9 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = UpdatePrefs.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EB35B3707CA6BCC000347B9 = {
+                       fileRef = 6EB35B3507CA6BCC000347B9;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6EB35B3807CA6BCC000347B9 = {
+                       fileRef = 6EB35B3607CA6BCC000347B9;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6EC06556078BE68300591D61 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = ChazUpdate.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EC06557078BE68300591D61 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = ChazUpdate.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EC06558078BE68300591D61 = {
+                       fileRef = 6EC06556078BE68300591D61;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6EC06559078BE68300591D61 = {
+                       fileRef = 6EC06557078BE68300591D61;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6EC06600078BFBE900591D61 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text.html;
+                       path = Help.html;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EC06601078BFBE900591D61 = {
+                       fileRef = 6EC06600078BFBE900591D61;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ECDE0990643984400B1DD8A = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = image.png;
+                       path = Server.png;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ECDE09A0643984400B1DD8A = {
+                       fileRef = 6ECDE0990643984400B1DD8A;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ECDE09D0643985000B1DD8A = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = image.png;
+                       path = General.png;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ECDE09E0643985000B1DD8A = {
+                       fileRef = 6ECDE09D0643985000B1DD8A;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED8062F0641D2E9002888F7 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = AboutBoxController.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806300641D2E9002888F7 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = AboutBoxController.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806310641D2E9002888F7 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = AppController.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806320641D2E9002888F7 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = AppController.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806350641D2E9002888F7 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = PreferenceController.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806360641D2E9002888F7 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = PreferenceController.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806390641D2E9002888F7 = {
+                       fileRef = 6ED8062F0641D2E9002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED8063A0641D2E9002888F7 = {
+                       fileRef = 6ED806300641D2E9002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED8063B0641D2E9002888F7 = {
+                       fileRef = 6ED806310641D2E9002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED8063C0641D2E9002888F7 = {
+                       fileRef = 6ED806320641D2E9002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED8063F0641D2E9002888F7 = {
+                       fileRef = 6ED806350641D2E9002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED806400641D2E9002888F7 = {
+                       fileRef = 6ED806360641D2E9002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED806430641D305002888F7 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = HelpController.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806440641D305002888F7 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = HelpController.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806450641D305002888F7 = {
+                       fileRef = 6ED806430641D305002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED806460641D305002888F7 = {
+                       fileRef = 6ED806440641D305002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED806580641D343002888F7 = {
+                       children = (
+                               6E38D3FD06C9B71F003BA9B4,
+                               6E38D3FE06C9B71F003BA9B4,
+                               6E9BF3BA07820415008F0139,
+                               6E9BF3BB07820415008F0139,
+                               6E9BF31F0781EEC3008F0139,
+                               6E9BF3200781EEC3008F0139,
+                               6E6FD9FE0764EDE4004FD845,
+                               6E6FD9FF0764EDE4004FD845,
+                               6E138C3006C1C140001C688F,
+                               6E138C3106C1C140001C688F,
+                       );
+                       isa = PBXGroup;
+                       name = Interface;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806700641D3AC002888F7 = {
+                       children = (
+                               6ED806710641D3CC002888F7,
+                               6ED806720641D3CC002888F7,
+                       );
+                       isa = PBXGroup;
+                       name = Categories;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806710641D3CC002888F7 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = MenuExtras.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806720641D3CC002888F7 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = MenuExtras.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806730641D3CC002888F7 = {
+                       fileRef = 6ED806710641D3CC002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED806740641D3CC002888F7 = {
+                       fileRef = 6ED806720641D3CC002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED806790641D41B002888F7 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = cheat_global.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED8067A0641D41B002888F7 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = cheat_global.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806800641D41B002888F7 = {
+                       fileRef = 6ED806790641D41B002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED806810641D41B002888F7 = {
+                       fileRef = 6ED8067A0641D41B002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED806830641D434002888F7 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = main.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806840641D434002888F7 = {
+                       fileRef = 6ED806830641D434002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED8068F0641D498002888F7 = {
+                       children = (
+                               6ED806900641D498002888F7,
+                       );
+                       isa = PBXVariantGroup;
+                       name = AboutBox.nib;
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806900641D498002888F7 = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = wrapper.nib;
+                       name = English;
+                       path = English.lproj/AboutBox.nib;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806910641D498002888F7 = {
+                       children = (
+                               6ED806920641D498002888F7,
+                       );
+                       isa = PBXVariantGroup;
+                       name = Help.nib;
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806920641D498002888F7 = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = wrapper.nib;
+                       name = English;
+                       path = English.lproj/Help.nib;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806930641D498002888F7 = {
+                       children = (
+                               6ED806940641D498002888F7,
+                       );
+                       isa = PBXVariantGroup;
+                       name = InfoPlist.strings;
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806940641D498002888F7 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text.plist.strings;
+                       name = English;
+                       path = English.lproj/InfoPlist.strings;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806950641D498002888F7 = {
+                       children = (
+                               6ED806960641D498002888F7,
+                       );
+                       isa = PBXVariantGroup;
+                       name = MainMenu.nib;
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806960641D498002888F7 = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = wrapper.nib;
+                       name = English;
+                       path = English.lproj/MainMenu.nib;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806990641D498002888F7 = {
+                       children = (
+                               6ED8069A0641D498002888F7,
+                       );
+                       isa = PBXVariantGroup;
+                       name = Preferences.nib;
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED8069A0641D498002888F7 = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = wrapper.nib;
+                       name = English;
+                       path = English.lproj/Preferences.nib;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED8069F0641D498002888F7 = {
+                       fileRef = 6ED8068F0641D498002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED806A00641D498002888F7 = {
+                       fileRef = 6ED806910641D498002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED806A10641D498002888F7 = {
+                       fileRef = 6ED806930641D498002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED806A20641D498002888F7 = {
+                       fileRef = 6ED806950641D498002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED806A40641D498002888F7 = {
+                       fileRef = 6ED806990641D498002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED806D00641D5F2002888F7 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text.xml;
+                       path = Info.plist;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED806FA0641E70F002888F7 = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = wrapper.framework;
+                       name = WebKit.framework;
+                       path = /System/Library/Frameworks/WebKit.framework;
+                       refType = 0;
+                       sourceTree = "<absolute>";
+               };
+               6ED806FB0641E70F002888F7 = {
+                       fileRef = 6ED806FA0641E70F002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED807190641EC6E002888F7 = {
+                       children = (
+                               6ED806350641D2E9002888F7,
+                               6ED806360641D2E9002888F7,
+                               6ED8072006421B05002888F7,
+                               6ED8072106421B05002888F7,
+                               6EB35B3507CA6BCC000347B9,
+                               6EB35B3607CA6BCC000347B9,
+                               6ED8072606421B10002888F7,
+                               6ED8072706421B10002888F7,
+                       );
+                       isa = PBXGroup;
+                       name = Preferences;
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED8072006421B05002888F7 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = GeneralPrefs.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED8072106421B05002888F7 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = GeneralPrefs.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED8072206421B05002888F7 = {
+                       fileRef = 6ED8072006421B05002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED8072306421B05002888F7 = {
+                       fileRef = 6ED8072106421B05002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED8072606421B10002888F7 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = ServerPrefs.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED8072706421B10002888F7 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = ServerPrefs.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED8072806421B10002888F7 = {
+                       fileRef = 6ED8072606421B10002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED8072906421B10002888F7 = {
+                       fileRef = 6ED8072706421B10002888F7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED97B900645E2EE00CBF037 = {
+                       children = (
+                               6ED97B9D0645E85700CBF037,
+                               6ED97B9E0645E85700CBF037,
+                               6E31A14306B71EBA00E40AB3,
+                               6E31A14406B71EBA00E40AB3,
+                               6E83F53007B048BD00D9DACB,
+                               6E83F53107B048BD00D9DACB,
+                       );
+                       isa = PBXGroup;
+                       name = Networking;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED97B9D0645E85700CBF037 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = CheatServer.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED97B9E0645E85700CBF037 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = CheatServer.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6ED97B9F0645E85700CBF037 = {
+                       fileRef = 6ED97B9D0645E85700CBF037;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6ED97BA00645E85700CBF037 = {
+                       fileRef = 6ED97B9E0645E85700CBF037;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6EF2F08B077A7BFC00C8B55A = {
+                       children = (
+                               6ECDE09D0643985000B1DD8A,
+                               6ECDE0990643984400B1DD8A,
+                               6EB35AA107CA5FE0000347B9,
+                               6E6FD8FA0764D1B0004FD845,
+                               6EB3528707C56771000347B9,
+                               6EB3528807C56771000347B9,
+                       );
+                       isa = PBXGroup;
+                       name = Images;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EF2F0BF077B424000C8B55A = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = CheaterTypes.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6EF2F0C0077B424000C8B55A = {
+                       fileRef = 6EF2F0BF077B424000C8B55A;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+//6E0
+//6E1
+//6E2
+//6E3
+//6E4
+//8D0
+//8D1
+//8D2
+//8D3
+//8D4
+               8D1107260486CEB800E47090 = {
+                       buildPhases = (
+                               8D1107270486CEB800E47090,
+                               8D1107290486CEB800E47090,
+                               8D11072C0486CEB800E47090,
+                               8D11072E0486CEB800E47090,
+                               6EB35A2D07C9C7C8000347B9,
+                       );
+                       buildRules = (
+                       );
+                       buildSettings = {
+                               COPY_PHASE_STRIP = YES;
+                               FRAMEWORK_SEARCH_PATHS = "";
+                               GCC_DYNAMIC_NO_PIC = YES;
+                               GCC_ENABLE_OBJC_EXCEPTIONS = NO;
+                               GCC_ENABLE_TRIGRAPHS = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
+                               GCC_PREFIX_HEADER = The_Cheat_Prefix.pch;
+                               GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+                               GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+                               GCC_WARN_UNKNOWN_PRAGMAS = NO;
+                               HEADER_SEARCH_PATHS = /Users/chaz/Projects/chazlib/build/usr/local/include;
+                               INFOPLIST_FILE = Info.plist;
+                               INSTALL_PATH = "$(HOME)/Applications";
+                               LIBRARY_SEARCH_PATHS = /Users/chaz/Projects/chazlib/build;
+                               MACOSX_DEPLOYMENT_TARGET = "";
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               PRODUCT_NAME = "The Cheat";
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+                               WRAPPER_EXTENSION = app;
+                       };
+                       dependencies = (
+                       );
+                       isa = PBXNativeTarget;
+                       name = "The Cheat";
+                       productInstallPath = "$(HOME)/Applications";
+                       productName = "The Cheat";
+                       productReference = 8D1107320486CEB800E47090;
+                       productType = "com.apple.product-type.application";
+               };
+               8D1107270486CEB800E47090 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               8D1107280486CEB800E47090,
+                               6ED806390641D2E9002888F7,
+                               6ED8063B0641D2E9002888F7,
+                               6ED8063F0641D2E9002888F7,
+                               6ED806450641D305002888F7,
+                               6ED806730641D3CC002888F7,
+                               6ED806800641D41B002888F7,
+                               6ED8072206421B05002888F7,
+                               6ED8072806421B10002888F7,
+                               6ED97B9F0645E85700CBF037,
+                               6E7614A406A47A790051C301,
+                               6E72B20F06AA5B0E00951D50,
+                               6E31A14506B71EBA00E40AB3,
+                               6E31A16D06B723CB00E40AB3,
+                               6E31A1BA06B7286300E40AB3,
+                               6E138BF806C18765001C688F,
+                               6E138C3206C1C140001C688F,
+                               6E3D7D3E06C44CFE00A73B29,
+                               6E38D3FF06C9B71F003BA9B4,
+                               6E38D61906C9F7A8003BA9B4,
+                               6EAB490D06CC4FEA00A4ABF0,
+                               6E6FD69D0762B626004FD845,
+                               6E6FD6B30762B965004FD845,
+                               6E6FDA000764EDE4004FD845,
+                               6E6FDC260765858A004FD845,
+                               6E8181D3076E475200A5FBEB,
+                               6EF2F0C0077B424000C8B55A,
+                               6E9BF3210781EEC3008F0139,
+                               6E9BF3BC07820415008F0139,
+                               6E9BF4B2078287DF008F0139,
+                               6EA253F80786249800C839D1,
+                               6EC06558078BE68300591D61,
+                               6E83F53207B048BD00D9DACB,
+                               6EB3579C07C83C60000347B9,
+                               6EB35B3707CA6BCC000347B9,
+                       );
+                       isa = PBXHeadersBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               8D1107280486CEB800E47090 = {
+                       fileRef = 32CA4F630368D1EE00C91783;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               8D1107290486CEB800E47090 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               6ED8069F0641D498002888F7,
+                               6ED806A00641D498002888F7,
+                               6ED806A10641D498002888F7,
+                               6ED806A20641D498002888F7,
+                               6ED806A40641D498002888F7,
+                               6ECDE09A0643984400B1DD8A,
+                               6ECDE09E0643985000B1DD8A,
+                               6E98A54D06A740EE006A576D,
+                               6E6FD8FB0764D1B0004FD845,
+                               6EC06601078BFBE900591D61,
+                               6EB3528907C56771000347B9,
+                               6EB3528A07C56771000347B9,
+                               6EB3579007C83B99000347B9,
+                               6EB3579107C83B99000347B9,
+                               6EB35AA207CA5FE0000347B9,
+                       );
+                       isa = PBXResourcesBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               8D11072C0486CEB800E47090 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               6ED8063A0641D2E9002888F7,
+                               6ED8063C0641D2E9002888F7,
+                               6ED806400641D2E9002888F7,
+                               6ED806460641D305002888F7,
+                               6ED806740641D3CC002888F7,
+                               6ED806810641D41B002888F7,
+                               6ED806840641D434002888F7,
+                               6ED8072306421B05002888F7,
+                               6ED8072906421B10002888F7,
+                               6ED97BA00645E85700CBF037,
+                               6E7614A506A47A790051C301,
+                               6E72B21006AA5B0E00951D50,
+                               6E31A14606B71EBA00E40AB3,
+                               6E31A16E06B723CB00E40AB3,
+                               6E31A1BB06B7286300E40AB3,
+                               6E138BF906C18765001C688F,
+                               6E138C3306C1C140001C688F,
+                               6E3D7D3F06C44CFE00A73B29,
+                               6E38D40006C9B71F003BA9B4,
+                               6E38D61A06C9F7A8003BA9B4,
+                               6EAB490E06CC4FEA00A4ABF0,
+                               6E6FD69E0762B626004FD845,
+                               6E6FD6B40762B965004FD845,
+                               6E6FDA010764EDE4004FD845,
+                               6E6FDC270765858A004FD845,
+                               6E8181D4076E475200A5FBEB,
+                               6EA39694077F4025002B0E69,
+                               6EA3969C077F419A002B0E69,
+                               6E9BF3220781EEC3008F0139,
+                               6E9BF3BD07820415008F0139,
+                               6E9BF4B3078287DF008F0139,
+                               6E9BF5040782926E008F0139,
+                               6EA253F90786249800C839D1,
+                               6EC06559078BE68300591D61,
+                               6E83F53307B048BD00D9DACB,
+                               6EB3579D07C83C60000347B9,
+                               6EB35B3807CA6BCC000347B9,
+                       );
+                       isa = PBXSourcesBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               8D11072E0486CEB800E47090 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               8D11072F0486CEB800E47090,
+                               6ED806FB0641E70F002888F7,
+                               6E63969906423AFE00BD3765,
+                       );
+                       isa = PBXFrameworksBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               8D11072F0486CEB800E47090 = {
+                       fileRef = 1058C7A1FEA54F0111CA2CBB;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               8D1107320486CEB800E47090 = {
+                       explicitFileType = wrapper.application;
+                       includeInIndex = 0;
+                       isa = PBXFileReference;
+                       path = "The Cheat.app";
+                       refType = 3;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+       };
+       rootObject = 29B97313FDCFA39411CA2CEA;
+}
index 92e9b973ad4550fccef660b814d8633275ed0ebb..0d0c539bac4c992ed60ebd6f6f00d24c784e955b 100644 (file)
@@ -1,13 +1,7 @@
-
 //
 // Prefix header for all source files of the 'The Cheat' target in the 'The Cheat' project
 //
-/*
+
 #ifdef __OBJC__
     #import <Cocoa/Cocoa.h>
 #endif
-*/
-#ifdef __OBJC__
-#import <Foundation/Foundation.h>
-#import <AppKit/AppKit.h>
-#endif
diff --git a/ThreadedTask.h b/ThreadedTask.h
new file mode 100644 (file)
index 0000000..25971d4
--- /dev/null
@@ -0,0 +1,248 @@
+
+// 
+// ThreadedTask 0.3
+// Perform a long task without blocking the main thread.
+// 
+// Copyright (c) 2004-2005, Chaz McGarvey
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+// 
+// 1. Redistributions of source code must retain the above copyright notice, this list
+// of conditions and the following disclaimer.
+// 
+// 2. Redistributions in binary form must reproduce the above copyright notice, this
+// list of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+// 
+// 3. Neither the name of the BrokenZipper nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+// SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+// 
+// Web:   http://www.brokenzipper.com/
+// Email: chaz@brokenzipper.com
+// 
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface ThreadedTask : NSObject
+{
+       // task objects
+       id _target;
+       SEL _selector;
+       int (*_function)(id, unsigned);
+       id _context;
+       // keeping track of things...
+       BOOL _isTaskThreadRunning;
+       BOOL _doCancelTask;
+       // the delegate object
+       id _delegate;
+       NSRunLoop *_runloop;
+       NSArray *_modes;
+       // locks
+       NSLock *_taskLock;
+}
+
+// #############################################################################
+#pragma mark Initialization
+// #############################################################################
+
+/* See accessor methods for a description of the parameters. */
+- (id)initWithTarget:(id)target selector:(SEL)selector delegate:(id)delegate;
+- (id)initWithTarget:(id)target selector:(SEL)selector context:(id)context delegate:(id)delegate;
+- (id)initWithFunction:(int (*)(id, unsigned))function delegate:(id)delegate;
+- (id)initWithFunction:(int (*)(id, unsigned))function context:(id)context delegate:(id)delegate;
+
+
+// #############################################################################
+#pragma mark Accessor Methods
+// #############################################################################
+
+/*
+ * As a protection, it is not possible to change the iteration method or function,
+ * or the context while the task is running.
+ */
+
+/*
+ * The target is the object (or class) that the selector is used on.  Target is
+ * not retained.
+ * 
+ * The selector which should be used should be in this form:
+ * 
+ * - (int)task:(ThreadedTask *)task iteration:(unsigned)iteration;
+ * 
+ * The task parameter is the ThreadedTask object belonging to the task. 
+ * The iteration parameter increases by one for each iteration that passes.
+ * 
+ * The return value is the important part.  It's what tells task object
+ * whether to continue or stop or report a failure.  Here are the values:
+ * 
+ * Returning 1 means the task is not finished, and the iteration method
+ * or function will be called again.
+ * Returning 0 means the task is finished, and to end it.
+ * Returning _anything_ else and the task will assume it is an error code;
+ * the task would then abort and report the error code to the delegate.
+ * 
+ * The target and selector will be set to nil if either are not valid.
+ */
+- (id)target;
+- (SEL)selector;
+- (void)setTarget:(id)target selector:(SEL)selector;
+
+/*
+ * A function can be used instead of a target and selector.  The function
+ * should be in the following form:
+ * 
+ * int MyTask( ThreadedTask *task, unsigned iteration );
+ * 
+ * The parameters and return value are the same as for the selector.  The
+ * task uses the function if setFunction: was called after setTarget:, or
+ * if setTarget: was never called.
+ */
+
+- (int (*)(id, unsigned))function;
+- (void)setFunction:(int (*)(id, unsigned))function;
+
+/*
+ * The context of the threaded task can be any object.  It is set before
+ * the task is run.  The iteration method/function can retrieve this
+ * context from the task and use it to safely store results from the
+ * task. The context can also be nil if the iteration doesn't need it.
+ */
+- (id)context;
+- (void)setContext:(id)context;
+
+/*
+ * Delegation is how information is received from the task. Setting a
+ * delegate isn't required, but it's pointless not to do so.  Unlike
+ * the above accessors, the delegate can be changed while a task is running.
+ * A runloop can also be specified which is used to send the delegate
+ * methods using the given modes.  If no runloop is specified, the current
+ * runloop for the thread which runs the threaded task is used.  Neither
+ * the delegate or the runloop are retained, but the modes are.  If a
+ * runloop is not specified and there is no current runloop, then no delegate
+ * methods will be sent.  Pass nil for modes to use the mode of the current
+ * runloop.
+ */
+- (id)delegate;
+- (void)setDelegate:(id)delegate;
+- (void)setDelegateRunLoop:(NSRunLoop *)runloop modes:(NSArray *)modes;
+
+/*
+ * Returns YES if the thread is detached and the task is being performed.
+ */
+- (BOOL)isRunning;
+
+
+// #############################################################################
+#pragma mark Control Methods
+// #############################################################################
+
+/*
+ * Begin execution of the task.  This method returns immediately.
+ * The delegate will recieve threadedTaskFinished: when the task has completed
+ * its purpose.  This method will return YES if the task was successfully
+ * started, and NO if the task could not be run, which usually occurs if the
+ * iteration method/selector or function is not valid.
+ */
+- (BOOL)run;
+
+/*
+ * General information about cancelling: If you release the ThreadedTask object
+ * while a task is running, the task will be cancelled for you automatically
+ * and this is generally safe to do, but the release may block the main thread
+ * for a short amount of time while the task cancels.  This can be avoided by
+ * using a cancel method below which doesn't block.
+ */
+
+/*
+ * Signal the task to cancel prematurely.  This method will block until the
+ * task actually does cancel.  It is safe to release the ThreadedTask object
+ * any time after this call without blocking.  If the iteration method or
+ * function is blocking for some reason, you should used a different cancel
+ * method which doesn't block, otherwise a deadlock could occur.
+ */
+- (void)cancel;
+
+/*
+ * Signal the task to cancel prematurely.  This method returns immediately, but
+ * you should not release the ThreadedTask object until the delegate receives
+ * a conclusion method.
+ */
+- (void)cancelWithoutWaiting;
+
+/*
+ * Signal the task to cancel prematurely.  This is a convenience method that
+ * sets the delegate to nil and cancels the task without blocking at the same
+ * time.  This is useful if the delegate is going to be released while the task
+ * is running.  You should not release the ThreadedTask object immediately
+ * after this call, but you will also not receive any notification that it is
+ * safe to do so.  You will know when receiver can be released without blocking
+ * when the isRunning method returns NO.
+ */
+- (void)cancelAndRemoveDelegate;
+
+
+// #############################################################################
+#pragma mark Iteration Methods
+// #############################################################################
+
+/*
+ * Report progress of the task back to the main thread.  This method should only
+ * be called from the iteration method or function.  It takes a single integer
+ * parameter which can be anything the receiver of the progress report will
+ * understand (perhaps 0 thru 100, like as a percentage).
+ */
+- (void)reportProgress:(int)progress;
+
+@end
+
+
+@interface NSObject ( ThreadedTaskDelegate )
+
+// #############################################################################
+#pragma mark Delegate Methods
+// #############################################################################
+
+/*
+ * These delegate methods are sent on the thread running the delegate runloop,
+ * or the main runloop if none is specified.  It is typically safe to update
+ * the user interface from these methods.
+ */
+
+/*
+ * Sent to the delegate upon completion of the task.
+ */
+- (void)threadedTaskFinished:(ThreadedTask *)theTask;
+
+/*
+ * Sent to the delegate when the task has finished cancelling.
+ */
+- (void)threadedTaskCancelled:(ThreadedTask *)theTask;
+
+/*
+ * Sent to the delegate when the iteration returned an error.
+ */
+- (void)threadedTask:(ThreadedTask *)theTask failedWithErrorCode:(int)errorCode;
+
+/*
+ * Sent to the delegate to report the progress of the task.  This is a direct
+ * result of the reportProgress: method being called from the iteration.
+ */
+- (void)threadedTask:(ThreadedTask *)theTask reportedProgress:(int)theProgress;
+
+@end
+
diff --git a/ThreadedTask.m b/ThreadedTask.m
new file mode 100644 (file)
index 0000000..19a91ab
--- /dev/null
@@ -0,0 +1,396 @@
+
+// 
+// ThreadedTask 0.3
+// Perform a long task without blocking the main thread.
+// 
+// Copyright (c) 2004-2005, Chaz McGarvey
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+// 
+// 1. Redistributions of source code must retain the above copyright notice, this list
+// of conditions and the following disclaimer.
+// 
+// 2. Redistributions in binary form must reproduce the above copyright notice, this
+// list of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+// 
+// 3. Neither the name of the BrokenZipper nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+// SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+// 
+// Web:   http://www.brokenzipper.com/
+// Email: chaz@brokenzipper.com
+// 
+
+#import "ThreadedTask.h"
+
+#import <objc/objc-runtime.h>
+
+
+@interface ThreadedTask ( PrivateAPI )
+
+/* private initialization: designated initializer */
+- (id)_initWithContext:(id)context delegate:(id)delegate;
+/* task method */
+- (void)_runTask:(NSArray *)package;
+/* sent to the main thread to report task progress */
+- (void)_taskReportProgress:(NSNumber *)progress;
+/* sent to the main thread to report a cancellation */
+- (void)_taskDidCancel:(id)dummy;
+/* sent to the main thread to report a completion */
+- (void)_taskDidFinish:(id)dummy;
+/* sent to the main thread to report a failure */
+- (void)_taskDidFailWithErrorCode:(NSNumber *)errorCode;
+
+@end
+
+
+@implementation ThreadedTask
+
+
+// #############################################################################
+#pragma mark Initialization
+// #############################################################################
+
+- (id)init
+{
+       return [self initWithTarget:nil selector:nil context:nil delegate:nil];
+}
+
+- (id)_initWithContext:(id)context delegate:(id)delegate // DESIGNATED
+{
+       if ( self = [super init] ) {
+               [self setContext:context];
+               [self setDelegate:delegate];
+               // create objects
+               _taskLock = [[NSLock alloc] init];
+       }
+       return self;
+}
+
+- (id)initWithTarget:(id)target selector:(SEL)selector delegate:(id)delegate
+{
+       return [self initWithTarget:target selector:selector context:nil delegate:delegate];
+}
+
+- (id)initWithTarget:(id)target selector:(SEL)selector context:(id)context delegate:(id)delegate
+{
+       if ( self = [self _initWithContext:context delegate:delegate] ) {
+               // set initial values
+               [self setTarget:target selector:selector];
+       }
+       return self;
+}
+
+- (id)initWithFunction:(int (*)(ThreadedTask *, unsigned))function delegate:(id)delegate
+{
+       return [self initWithFunction:function context:nil delegate:delegate];
+}
+
+- (id)initWithFunction:(int (*)(ThreadedTask *, unsigned))function context:(id)context delegate:(id)delegate
+{
+       if ( self = [self _initWithContext:context delegate:delegate] ) {
+               // set initial values
+               [self setFunction:function];
+       }
+       return self;
+}
+
+- (void)dealloc
+{
+       // cancel any running task
+       [self cancel];
+       [_taskLock release];
+       // release retained objects
+       [_context release];
+       [_modes release];
+
+       [super dealloc];
+}
+
+
+// #############################################################################
+#pragma mark Accessor Methods
+// #############################################################################
+
+- (id)target
+{
+       return _target;
+}
+
+- (SEL)selector
+{
+       return _selector;
+}
+
+- (void)setTarget:(id)target selector:(SEL)selector
+{
+       // don't do anything if the task is running
+       if ( [self isRunning] ) {
+               return;
+       }
+       
+       if ( [target respondsToSelector:selector] ) {
+               // target & selector look good, save them
+               _target = target;
+               _selector = selector;
+               _function = NULL;
+       }
+       else {
+               // bad target and/or selector, use nil
+               _target = nil;
+               _selector = NULL;
+       }
+}
+
+
+- (int (*)(id, unsigned))function
+{
+       return _function;
+}
+
+- (void)setFunction:(int (*)(id, unsigned))function
+{
+       // don't do anything if the task is running
+       if ( [self isRunning] ) {
+               return;
+       }
+       
+       _function = function;
+       if ( _function ) {
+               _target = nil;
+               _selector = NULL;
+       }
+}
+
+
+- (id)context
+{
+       return _context;
+}
+
+- (void)setContext:(id)context
+{
+       // don't do anything if the task is running
+       if ( [self isRunning] ) {
+               return;
+       }
+       
+       [context retain];
+       [_context release];
+       _context = context;
+}
+
+
+- (id)delegate
+{
+       return _delegate;
+}
+
+- (void)setDelegate:(id)delegate
+{
+       _delegate = delegate;
+}
+
+- (void)setDelegateRunLoop:(NSRunLoop *)runloop modes:(NSArray *)modes
+{
+       _runloop = runloop;
+       [modes retain];
+       [_modes release];
+       _modes = modes;
+}
+
+
+- (BOOL)isRunning
+{
+       return _isTaskThreadRunning;
+}
+
+
+// #############################################################################
+#pragma mark Control Methods
+// #############################################################################
+
+- (BOOL)run
+{
+       // don't run if there is no iteration method/function to call
+       if ( [self isRunning] || (!_target && !_function) ) {
+               return NO;
+       }
+
+       // set initial values
+       _doCancelTask = NO;
+       
+       if ( !_runloop ) {
+               // use the default runloop
+               NSRunLoop *current = [NSRunLoop currentRunLoop];
+               if ( !_modes ) {
+                       NSString *currentMode = [current currentMode];
+                       NSArray *modes = currentMode? [NSArray arrayWithObject:currentMode]
+                               : [NSArray arrayWithObjects:NSDefaultRunLoopMode,NSModalPanelRunLoopMode,NSEventTrackingRunLoopMode,NSConnectionReplyMode,nil];
+                       [self setDelegateRunLoop:current modes:modes];
+               }
+               else {
+                       [self setDelegateRunLoop:current modes:_modes];
+               }
+       }
+       
+       // start the task thread!
+       _isTaskThreadRunning = YES;
+    [NSThread detachNewThreadSelector:@selector(_runTask:) toTarget:self withObject:nil];
+       return YES;
+}
+
+- (void)cancel
+{
+       if ( [self isRunning] ) {
+               _doCancelTask = YES;
+               // this blocks until the task thread exits.
+               [_taskLock lock];
+               [_taskLock unlock];
+       }
+}
+
+- (void)cancelWithoutWaiting
+{
+       _doCancelTask = YES;
+}
+
+- (void)cancelAndRemoveDelegate
+{
+       [self setDelegate:nil];
+       [self cancelWithoutWaiting];
+}
+
+
+// #############################################################################
+#pragma mark Task Methods
+// #############################################################################
+
+- (void)reportProgress:(int)progress
+{
+       //[_runloop performSelector:@selector(_taskReportProgress:) target:self
+       //                               argument:[[NSNumber alloc] initWithInt:progress] order:0 modes:_modes];
+       [self performSelectorOnMainThread:@selector(_taskReportProgress:)
+                                                  withObject:[[NSNumber alloc] initWithInt:progress] waitUntilDone:NO];
+}
+
+
+// #############################################################################
+#pragma mark Private Methods
+// #############################################################################
+
+- (void)_runTask:(NSArray *)package
+{
+       NSAutoreleasePool *pool;
+
+       unsigned iteration;
+       int returnCode;
+       
+       // create the ever-so-important pool
+    pool = [[NSAutoreleasePool alloc] init];
+       
+       // set the lock the tells the main thread the task thread is running
+       [_taskLock lock];
+       
+       // set first iteration
+       iteration = 0;
+       returnCode = 1;
+
+       // enter the task loop
+       if ( _target ) {
+               while ( !_doCancelTask && returnCode == 1 ) {
+                       NSAutoreleasePool *loopPool;
+                       
+                       // do the actual work
+                       loopPool = [[NSAutoreleasePool alloc] init];
+                       returnCode = (int)objc_msgSend( _target, _selector, self, iteration );
+                       [loopPool release];
+                       
+                       iteration++;
+               }
+       }
+       else if ( _function ) {
+               while ( !_doCancelTask && returnCode == 1 ) {
+                       NSAutoreleasePool *loopPool;
+                       
+                       // do the actual work
+                       loopPool = [[NSAutoreleasePool alloc] init];
+                       returnCode = (int)_function( self, iteration );
+                       [loopPool release];
+                       
+                       iteration++;
+               }
+       }
+       
+       if ( _doCancelTask ) {
+               // report cancel
+               //[_runloop performSelector:@selector(_taskDidCancel:) target:self argument:nil order:iteration modes:_modes];
+               [self performSelectorOnMainThread:@selector(_taskDidCancel:) withObject:nil waitUntilDone:NO];
+       }
+       else if ( returnCode == 0 ) {
+               // report task completed
+               //[_runloop performSelector:@selector(_taskDidFinish:) target:self argument:nil order:iteration modes:_modes];
+               [self performSelectorOnMainThread:@selector(_taskDidFinish:) withObject:nil waitUntilDone:NO];
+       }
+       else {
+               // report error
+               [_runloop performSelector:@selector(_taskDidFailWithErrorCode:) target:self
+                                                argument:[[NSNumber alloc] initWithInt:returnCode] order:iteration modes:_modes];
+               //[self performSelectorOnMainThread:@selector(_taskDidFailWithErrorCode:)
+               //                                         withObject:[[NSNumber alloc] initWithInt:returnCode] waitUntilDone:NO];
+       }
+       
+       // allow the main thread to continue if it was blocking
+       _isTaskThreadRunning = NO;
+       [_taskLock unlock];
+       
+    [pool release];
+}
+
+
+- (void)_taskReportProgress:(NSNumber *)progress
+{
+       if ( [_delegate respondsToSelector:@selector(threadedTask:reportedProgress:)] ) {
+               [_delegate threadedTask:self reportedProgress:[progress intValue]];
+       }
+       [progress release];
+}
+
+- (void)_taskDidCancel:(id)dummy
+{
+       if ( [_delegate respondsToSelector:@selector(threadedTaskCancelled:)] ) {
+               [_delegate threadedTaskCancelled:self];
+       }
+}
+
+- (void)_taskDidFinish:(id)dummy
+{
+       if ( [_delegate respondsToSelector:@selector(threadedTaskFinished:)] ) {
+               [_delegate threadedTaskFinished:self];
+       }
+}
+
+- (void)_taskDidFailWithErrorCode:(NSNumber *)errorCode
+{
+       if ( [_delegate respondsToSelector:@selector(threadedTask:failedWithErrorCode:)] ) {
+               [_delegate threadedTask:self failedWithErrorCode:[errorCode intValue]];
+       }
+       [errorCode release];
+}
+
+
+@end
diff --git a/TrackerScroller.h b/TrackerScroller.h
new file mode 100644 (file)
index 0000000..17c591d
--- /dev/null
@@ -0,0 +1,28 @@
+//
+//  TrackerScroller.h
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 12/28/04.
+//  Copyright 2004 Chaz McGarvey. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface TrackerScroller : NSScroller
+{
+       id _delegate;
+}
+
+- (id)delegate;
+- (void)setDelegate:(id)delegate;
+
+@end
+
+
+@interface NSObject ( TrackerScrollerDelegate )
+
+- (void)scrollerDidStartScrolling:(TrackerScroller *)scroller;
+- (void)scrollerDidStopScrolling:(TrackerScroller *)scroller;
+
+@end
\ No newline at end of file
diff --git a/TrackerScroller.m b/TrackerScroller.m
new file mode 100644 (file)
index 0000000..3986402
--- /dev/null
@@ -0,0 +1,38 @@
+//
+//  TrackerScroller.m
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 12/28/04.
+//  Copyright 2004 Chaz McGarvey. All rights reserved.
+//
+
+#import "TrackerScroller.h"
+
+
+@implementation TrackerScroller
+
+
+- (id)delegate
+{
+       return _delegate;
+}
+
+- (void)setDelegate:(id)delegate
+{
+       _delegate = delegate;
+}
+
+
+- (void)mouseDown:(NSEvent *)theEvent
+{
+       if ( [_delegate respondsToSelector:@selector(scrollerDidStartScrolling:)] ) {
+               [_delegate scrollerDidStartScrolling:self];
+       }
+       [super mouseDown:theEvent];
+       if ( [_delegate respondsToSelector:@selector(scrollerDidStopScrolling:)] ) {
+               [_delegate scrollerDidStopScrolling:self];
+       }
+}
+
+
+@end
diff --git a/Update.png b/Update.png
new file mode 100644 (file)
index 0000000..fc9b754
Binary files /dev/null and b/Update.png differ
diff --git a/UpdatePrefs.h b/UpdatePrefs.h
new file mode 100644 (file)
index 0000000..bc29a1b
--- /dev/null
@@ -0,0 +1,23 @@
+//
+//  UpdatePrefs.h
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 2/21/05.
+//  Copyright 2005 Chaz McGarvey. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+#import "cheat_global.h"
+
+#import "ChazUpdate.h"
+
+
+@interface UpdatePrefs : NSObject
+{
+       IBOutlet NSButton *ibAutoCheckButton;
+}
+
+- (IBAction)ibAutoCheckButton:(id)sender;
+- (IBAction)ibCheckNowButton:(id)sender;
+
+@end
diff --git a/UpdatePrefs.m b/UpdatePrefs.m
new file mode 100644 (file)
index 0000000..f016234
--- /dev/null
@@ -0,0 +1,33 @@
+//
+//  UpdatePrefs.m
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 2/21/05.
+//  Copyright 2005 Chaz McGarvey. All rights reserved.
+//
+
+#import "UpdatePrefs.h"
+
+
+@implementation UpdatePrefs
+
+
+- (void)awakeFromNib
+{
+       // set initial states
+       [ibAutoCheckButton setState:[[NSUserDefaults standardUserDefaults] boolForKey:TCUpdateCheckPref]];
+}
+
+- (IBAction)ibAutoCheckButton:(id)sender
+{
+       BOOL pref = [sender state];
+       [[NSUserDefaults standardUserDefaults] setBool:pref forKey:TCUpdateCheckPref];
+}
+
+- (IBAction)ibCheckNowButton:(id)sender
+{
+       ChazCheckForUpdate( TCUpdateCheckURL, YES );
+}
+
+
+@end
diff --git a/VMRegion.h b/VMRegion.h
new file mode 100644 (file)
index 0000000..78599de
--- /dev/null
@@ -0,0 +1,194 @@
+
+// 
+// VMRegion 0.1
+// Virtual Memory Wrapper
+// 
+// Copyright (c) 2004, Chaz McGarvey
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+// 
+// 1. Redistributions of source code must retain the above copyright notice, this list
+// of conditions and the following disclaimer.
+// 
+// 2. Redistributions in binary form must reproduce the above copyright notice, this
+// list of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+// 
+// 3. Neither the name of the BrokenZipper nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+// SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+// 
+// Web:   http://www.brokenzipper.com/
+// Email: chaz@brokenzipper.com
+// 
+
+#import <Cocoa/Cocoa.h>
+
+#include <mach/vm_region.h>
+#include <mach/vm_map.h>
+
+
+/* Compiler macros */
+#if defined( __cplusplus )
+#define VMREGION_EXPORT extern "C"
+#define VMREGION_IMPORT extern "C"
+#else
+#define VMREGION_EXPORT extern
+#define VMREGION_IMPORT extern
+#endif
+
+#if !defined( VMREGION_STATIC_INLINE )
+#define VMREGION_STATIC_INLINE static __inline__
+#endif
+
+#if !defined( VMREGION_EXTERN_INLINE )
+#define VMREGION_EXTERN_INLINE extern __inline__
+#endif
+
+
+// attributes of memory regions
+enum _VMRegionAttributes
+{
+       VMREGION_READABLE = 1,
+       VMREGION_WRITABLE = 2,
+       VMREGION_EXECUTABLE = 4
+};
+
+
+#pragma mark -
+#pragma mark VMRegion
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+typedef struct _VMRegion
+{
+       // process information
+       pid_t _process;
+       // region information
+       vm_address_t _address;
+       vm_size_t _size;
+       unsigned _attributes;
+} VMRegion;
+
+// common regions
+VMREGION_EXPORT const VMRegion VMNullRegion; /* <0,0,0> */
+
+
+#pragma mark -
+#pragma mark Utility VM Functions
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+// get the number of regions a process has.
+unsigned VMCountRegions( pid_t process );
+unsigned VMCountRegionsWithAttributes( pid_t process, unsigned attribs );
+
+// these functions return allocated VMRegion objects.
+// use VMReleaseRegion(1) to free up used memory.
+// returns nil on error or if there is no region after prevRegion.
+// pass nil for prevRegion to access the first region.
+VMRegion VMNextRegion( pid_t process, VMRegion previous );
+VMRegion VMNextRegionWithAttributes( pid_t process, VMRegion previous, unsigned attribs );
+
+// UTILITY functions - stop/resume processes
+// returns YES on success, NO on failure
+VMREGION_STATIC_INLINE BOOL VMStopProcess( pid_t process ) { return (kill( process, SIGSTOP ) == 0); }
+VMREGION_STATIC_INLINE BOOL VMContinueProcess( pid_t process ) { return (kill( process, SIGCONT ) == 0); }
+
+// lower-level reading/writing functions
+// the returned NSData object should be retained by the caller.
+NSData *VMReadData( pid_t process, vm_address_t address, vm_size_t size );
+BOOL VMReadBytes( pid_t process, vm_address_t address, void *bytes, vm_size_t *size ); // size is # bytes read after call
+BOOL VMWriteData( pid_t process, vm_address_t address, NSData *data ); // returns YES on success, NO on failure
+BOOL VMWriteBytes( pid_t process, vm_address_t address, const void *bytes, vm_size_t size );
+
+
+#pragma mark -
+#pragma mark Exported VM Functions
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+VMREGION_EXPORT VMRegion VMMakeRegion( pid_t process, vm_address_t address, vm_size_t size );
+
+VMREGION_EXPORT BOOL VMRegionSetData( VMRegion region, NSData *data );
+
+VMREGION_EXPORT NSString *VMStringFromRegion( VMRegion region );
+
+
+#pragma mark -
+#pragma mark Imported VM Functions
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+VMREGION_STATIC_INLINE vm_address_t VMRegionProcess( VMRegion region )
+{
+       return region._process;
+}
+
+VMREGION_STATIC_INLINE vm_address_t VMRegionAddress( VMRegion region )
+{
+       return region._address;
+}
+
+VMREGION_STATIC_INLINE vm_size_t VMRegionSize( VMRegion region )
+{
+       return region._size;
+}
+
+VMREGION_STATIC_INLINE unsigned VMRegionAttributes( VMRegion region )
+{
+       return region._attributes;
+}
+
+VMREGION_STATIC_INLINE BOOL VMRegionReadable( VMRegion region )
+{
+       return region._attributes & VMREGION_READABLE;
+}
+
+VMREGION_STATIC_INLINE BOOL VMRegionWritable( VMRegion region )
+{
+       return region._attributes & VMREGION_WRITABLE;
+}
+
+VMREGION_STATIC_INLINE BOOL VMRegionExecutable( VMRegion region )
+{
+       return region._attributes & VMREGION_EXECUTABLE;
+}
+
+
+VMREGION_STATIC_INLINE NSData *VMRegionData( VMRegion region )
+{
+       return VMReadData( region._process, region._address, region._size );
+}
+
+VMREGION_STATIC_INLINE BOOL VMRegionBytes( VMRegion region, void *bytes, vm_size_t *size )
+{
+       *size = region._size;
+       return VMReadBytes( region._process, region._address, bytes, size );
+}
+
+
+
+VMREGION_STATIC_INLINE BOOL VMRegionIsNotNull( VMRegion region )
+{
+       return (region._process != 0);
+}
+
+VMREGION_STATIC_INLINE BOOL VMEqualRegions( VMRegion region1, VMRegion region2 )
+{
+       return (region1._process == region2._process &&
+                       region1._address == region2._address &&
+                       region1._size == region2._size &&
+                       region1._attributes == region2._attributes);
+}
+
+
diff --git a/VMRegion.m b/VMRegion.m
new file mode 100644 (file)
index 0000000..612327a
--- /dev/null
@@ -0,0 +1,279 @@
+
+// 
+// VMRegion 0.1
+// Virtual Memory Wrapper
+// 
+// Copyright (c) 2004, Chaz McGarvey
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+// 
+// 1. Redistributions of source code must retain the above copyright notice, this list
+// of conditions and the following disclaimer.
+// 
+// 2. Redistributions in binary form must reproduce the above copyright notice, this
+// list of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+// 
+// 3. Neither the name of the BrokenZipper nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+// SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+// 
+// Web:   http://www.brokenzipper.com/
+// Email: chaz@brokenzipper.com
+// 
+
+#import "VMRegion.h"
+
+#include <mach/mach_traps.h> // for task_for_pid(3)
+#include <signal.h> // for stop(2)
+
+
+static __inline__ vm_map_t _VMTaskFromPID( pid_t process )
+{
+       vm_map_t task;
+       
+       if ( task_for_pid( current_task(), process, &task ) == KERN_SUCCESS ) {
+               return task;
+       }
+       return 0;
+}
+
+static __inline__ VMRegion _VMMakeRegionWithAttributes( pid_t process, vm_address_t address, vm_size_t size, unsigned attribs )
+{
+       VMRegion region;
+       region._process = process;
+       region._address = address;
+       region._size = size;
+       region._attributes = attribs;
+       return region;
+}
+
+unsigned _VMAttributesFromAddress( pid_t process, vm_address_t address );
+
+
+const VMRegion VMNullRegion = { 0, 0, 0, 0 };
+
+
+#pragma mark -
+#pragma mark VMRegion Functions
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+VMRegion VMMakeRegion( pid_t process, vm_address_t address, vm_size_t size )
+{
+       VMRegion region;
+       region._process = process;
+       region._address = address;
+       region._size = size;
+       region._attributes = _VMAttributesFromAddress( process, address );
+       return region;
+}
+
+BOOL VMRegionSetData( VMRegion region, NSData *data )
+{
+       // get the size that should be used (to prevent from writing past the region)
+       vm_size_t size = (vm_size_t)[data length];
+       size = (size > region._size)? region._size : size;
+       
+       return VMWriteBytes( region._process, region._address, [data bytes], size );
+}
+
+NSString *VMStringFromRegion( VMRegion region )
+{
+       return [NSString stringWithFormat:@"{pid:%i,%p,%u,}", region._process, region._address, region._size];
+}
+
+
+#pragma mark -
+#pragma mark Utility VM Functions
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+unsigned VMCountRegions( pid_t process )
+{
+       VMRegion region;
+       VMRegion prev = VMNullRegion;
+       unsigned count = 0;
+       
+       while ( VMRegionIsNotNull( region = VMNextRegion( process, prev ) ) )
+       {
+               count++;
+               prev = region;
+       }
+       
+       return count;
+}
+
+unsigned VMCountRegionsWithAttributes( pid_t process, unsigned attribs )
+{
+       VMRegion region;
+       VMRegion prev = VMNullRegion;
+       unsigned count = 0;
+       
+       while ( VMRegionIsNotNull( region = VMNextRegionWithAttributes( process, prev, attribs ) ) )
+       {
+               count++;
+               prev = region;
+       }
+       
+       return count;
+}
+
+
+VMRegion VMNextRegion( pid_t process, VMRegion previous )
+{
+       vm_map_t task = _VMTaskFromPID( process );
+       unsigned attribs = 0;
+       
+       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 = VM_REGION_BASIC_INFO_COUNT;
+       mach_port_t object_name = 0;
+       
+       if ( !VMEqualRegions( previous, VMNullRegion ) ) {
+               address = previous._address + previous._size;
+       }
+       
+       // get the next region
+       result = vm_region( task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name );
+       
+       if ( result == KERN_SUCCESS ) {
+               // get the attributes
+               if ( info.protection & VM_PROT_READ ) {
+                       attribs |= VMREGION_READABLE;
+               }
+               if ( info.protection & VM_PROT_WRITE ) {
+                       attribs |= VMREGION_WRITABLE;
+               }
+               if ( info.protection & VM_PROT_EXECUTE ) {
+                       attribs |= VMREGION_EXECUTABLE;
+               }
+               // return the region
+               return _VMMakeRegionWithAttributes( process, address, size, attribs );
+       }
+       
+       return VMNullRegion;
+}
+
+VMRegion VMNextRegionWithAttributes( pid_t process, VMRegion previous, unsigned attribs )
+{
+       VMRegion region;
+       
+       while ( VMRegionIsNotNull( region = VMNextRegion( process, previous ) ) )
+       {
+               if ( (attribs & region._attributes) == attribs ) {
+                       // pass back this region if the attributes match
+                       return region;
+               }
+               previous = region;
+       }
+       
+       return VMNullRegion;
+}
+
+
+NSData *VMReadData( pid_t process, vm_address_t address, vm_size_t size )
+{
+       vm_map_t task = _VMTaskFromPID( process );
+       kern_return_t result;
+       
+       void *buffer;
+       vm_size_t actualSize;
+       
+       // create a local block to hold the incoming data
+       buffer = (void *)malloc( (size_t)size );
+       if ( !buffer ) {
+               // no buffer, abort
+               return nil;
+       }
+       
+       // perform the read
+       result = vm_read_overwrite( task, address, size, (vm_address_t)buffer, &actualSize );
+       if ( result != KERN_SUCCESS ) {
+               // read error, abort
+               free( buffer );
+               return nil;
+       }
+       
+       // everything seems to be peachy, so return the data
+       return [[[NSData alloc] initWithBytesNoCopy:buffer length:actualSize freeWhenDone:YES] autorelease];
+}
+
+BOOL VMReadBytes( pid_t process, vm_address_t address, void *bytes, vm_size_t *size )
+{
+       vm_map_t task = _VMTaskFromPID( process );
+       kern_return_t result;
+       vm_size_t staticsize = *size;
+       
+       // perform the read
+       result = vm_read_overwrite( task, address, staticsize, (vm_address_t)bytes, size );
+       if ( result != KERN_SUCCESS ) {
+               return NO;
+       }
+       
+       return YES;
+}
+
+BOOL VMWriteData( pid_t process, vm_address_t address, NSData *data )
+{
+       return VMWriteBytes( process, address, [data bytes], [data length] );
+}
+
+BOOL VMWriteBytes( pid_t process, vm_address_t address, const void *bytes, vm_size_t size )
+{
+       vm_map_t task = _VMTaskFromPID( process );
+       kern_return_t result;
+       
+       // attempt to write the bytes and return success/failure
+       result = vm_write( task, address, (vm_address_t)bytes, size );
+       return (result == KERN_SUCCESS);
+}
+
+
+unsigned _VMAttributesFromAddress( pid_t process, vm_address_t address )
+{
+       vm_map_t task = _VMTaskFromPID( process );
+       unsigned attribs = 0;
+       
+       kern_return_t result;
+       
+       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;
+       
+       // get the next region
+       result = vm_region( task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name );
+       
+       if ( result == KERN_SUCCESS ) {
+               // get the attributes
+               if ( info.protection & VM_PROT_READ ) {
+                       attribs |= VMREGION_READABLE;
+               }
+               if ( info.protection & VM_PROT_WRITE ) {
+                       attribs |= VMREGION_WRITABLE;
+               }
+               if ( info.protection & VM_PROT_EXECUTE ) {
+                       attribs |= VMREGION_EXECUTABLE;
+               }
+               // return the region attributes
+               return attribs;
+       }
+       return 0;
+}
+
+
diff --git a/Variable.h b/Variable.h
new file mode 100644 (file)
index 0000000..fc3d83b
--- /dev/null
@@ -0,0 +1,93 @@
+
+// **********************************************************************
+// 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 <Cocoa/Cocoa.h>
+
+#import "CheaterTypes.h"
+
+#include <string.h>
+
+
+#define TC_MAX_VAR_SIZE (256)
+
+
+@interface Variable : NSObject < NSCoding >
+{
+       TCAddress _address;
+       BOOL _isValueValid;
+       BOOL _enabled;
+       
+       int _tag;
+       
+       @public;
+       // use the accessor methods unless you need fast access
+       // do not change these variables directly or things will be screwed.
+       TCVariableType _type;
+       TCIntegerSign _integerSign;
+       unsigned _size;
+       void *_value;
+}
+
+// #############################################################################
+#pragma mark Initialization
+// #############################################################################
+
+// type and sign can't be changed once variable is created.
+
+- (id)init; // default: TCInt32
+- (id)initWithType:(TCVariableType)type; // default: TCSigned
+- (id)initWithType:(TCVariableType)type integerSign:(TCIntegerSign)sign;
+
+// #############################################################################
+#pragma mark NSCoding
+// #############################################################################
+
+- (id)initWithCoder:(NSCoder *)coder;
+- (void)encodeWithCoder:(NSCoder *)coder;
+
+// #############################################################################
+#pragma mark Accessors
+// #############################################################################
+
+- (TCVariableType)type;
+- (TCIntegerSign)integerSign;
+- (NSString *)typeString;
+
+- (TCAddress)address;
+- (void)setAddress:(TCAddress)addr;
+- (NSString *)addressString;
+- (BOOL)setAddressString:(NSString *)string;
+
+- (void const *)value;
+- (void)setValue:(void const *)value;
+- (void)setValue:(void const *)value size:(unsigned)size;
+- (NSString *)stringValue;
+- (BOOL)setStringValue:(NSString *)value;
+
+- (unsigned)valueSize;
+- (BOOL)isValueValid;
+
+- (BOOL)isEnabled;
+- (void)setEnabled:(BOOL)enabled;
+
+- (int)tag;
+- (void)setTag:(int)tag;
+
+@end
diff --git a/Variable.m b/Variable.m
new file mode 100644 (file)
index 0000000..bb3c59e
--- /dev/null
@@ -0,0 +1,358 @@
+
+// **********************************************************************
+// 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 "Variable.h"
+
+
+@interface Variable ( PrivateAPI )
+
+- (void)_setType:(TCVariableType)type;
+- (void)_setIntegerSign:(TCIntegerSign)sign;
+
+@end
+
+
+@implementation Variable
+
+
+- (id)init
+{
+       return [self initWithType:TCInt32 integerSign:TCSigned];
+}
+
+- (id)initWithType:(TCVariableType)type
+{
+       return [self initWithType:type integerSign:TCSigned];
+}
+
+- (id)initWithType:(TCVariableType)type integerSign:(TCIntegerSign)sign // DESIGNATED
+{
+       if ( self = [super init] ) {
+               _isValueValid = YES;
+               _enabled = YES;
+               [self _setType:type];
+               [self _setIntegerSign:sign];
+       }
+       return self;
+}
+
+
+- (void)dealloc
+{
+       if ( _value ) {
+               free( _value );
+       }
+       [super dealloc];
+}
+
+
+// #############################################################################
+#pragma mark NSCoding
+// #############################################################################
+
+- (id)initWithCoder:(NSCoder *)coder
+{
+       if ( self = [super init] ) {
+               [coder decodeValueOfObjCType:@encode(TCVariableType) at:&_type];
+               [coder decodeValueOfObjCType:@encode(TCIntegerSign) at:&_integerSign];
+               [coder decodeValueOfObjCType:@encode(TCAddress) at:&_address];
+               [self setValue:[coder decodeBytesWithReturnedLength:&_size]];
+               [coder decodeValueOfObjCType:@encode(BOOL) at:&_isValueValid];
+               [coder decodeValueOfObjCType:@encode(BOOL) at:&_enabled];
+               [coder decodeValueOfObjCType:@encode(int) at:&_tag];
+       }
+       return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)coder
+{
+       [coder encodeValueOfObjCType:@encode(TCVariableType) at:&_type];
+       [coder encodeValueOfObjCType:@encode(TCIntegerSign) at:&_integerSign];
+       [coder encodeValueOfObjCType:@encode(TCAddress) at:&_address];
+       [coder encodeBytes:_value length:_size];
+       [coder encodeValueOfObjCType:@encode(BOOL) at:&_isValueValid];
+       [coder encodeValueOfObjCType:@encode(BOOL) at:&_enabled];
+       [coder encodeValueOfObjCType:@encode(int) at:&_tag];
+}
+
+
+// #############################################################################
+#pragma mark Accessors
+// #############################################################################
+
+- (TCVariableType)type
+{
+       return _type;
+}
+
+- (void)_setType:(TCVariableType)type
+{
+       _type = type;
+       // set the size of the value
+       switch ( _type ) {
+               case TCInt64:
+               case TCDouble: _size = 8;
+                       break;
+               case TCInt32:
+               case TCFloat: _size = 4;
+                       break;
+               case TCInt16: _size = 2;
+                       break;
+               case TCInt8: _size = 1;
+                       break;
+       }
+       
+       if ( !_value ) {
+               _value = calloc( 1, _size );
+       }
+}
+
+- (TCIntegerSign)integerSign
+{
+       return _integerSign;
+}
+
+- (void)_setIntegerSign:(TCIntegerSign)sign
+{
+       _integerSign = sign;
+}
+
+
+- (NSString *)typeString
+{
+       switch ( _type ) {
+               case TCDouble: return @"Double";
+               case TCFloat: return @"Float";
+               case TCString: return @"ASCII String";
+       }
+       if ( _integerSign == TCUnsigned ) {
+               switch ( _type ) {
+                       case TCInt64: return @"64-bit Unsigned Integer";
+                       case TCInt32: return @"32-bit Unsigned Integer";
+                       case TCInt16: return @"16-bit Unsigned Integer";
+                       case TCInt8: return @"08-bit Unsigned Integer";
+               }
+       }
+       else {
+               switch ( _type ) {
+                       case TCInt64: return @"64-bit Integer";
+                       case TCInt32: return @"32-bit Integer";
+                       case TCInt16: return @"16-bit Integer";
+                       case TCInt8: return @"08-bit Integer";
+               }
+       }
+       return @"";
+}
+
+
+- (TCAddress)address
+{
+       return _address;
+}
+
+- (void)setAddress:(TCAddress)addr
+{
+       _address = addr;
+}
+
+
+- (NSString *)addressString
+{
+       return [NSString stringWithFormat:@"%0.8X", _address];
+}
+
+- (BOOL)setAddressString:(NSString *)string
+{
+       NSScanner *scanner = [NSScanner scannerWithString:string];
+       TCAddress address;
+       
+       if ( [scanner scanHexInt:(unsigned *)(&address)] ) {
+               [self setAddress:address];
+               return YES;
+       }
+       return NO;
+}
+
+
+- (void const *)value
+{
+       return _value;
+}
+
+- (void)setValue:(void const *)value
+{
+       if ( !_value ) {
+               _value = malloc( _size );
+       }
+       
+       _isValueValid = YES;
+       memcpy( _value, value, _size );
+}
+
+- (void)setValue:(void const *)value size:(unsigned)size
+{
+       // make sure the size doesn't exceed the maximum
+       size = MIN( size, TC_MAX_VAR_SIZE );
+       // only string variables can have the value size changed
+       if ( (_type == TCString) && (_size != size) && _value ) {
+               void *newValue = realloc( _value, size );
+               if ( newValue ) {
+                       _value = newValue;
+                       _size = size;
+               }
+       }
+       _size = MIN( _size, size );
+       
+       [self setValue:value];
+}
+
+
+- (NSString *)stringValue
+{
+       switch ( _type ) {
+               case TCDouble: return [NSString stringWithFormat:@"%.1lf", *(double *)[self value]];
+               case TCFloat: return [NSString stringWithFormat:@"%.1f", *(float *)[self value]];
+               case TCString: return [NSString stringWithCString:[self value] length:[self valueSize]];
+       }
+       if ( _integerSign == TCUnsigned ) {
+               switch ( _type ) {
+                       case TCInt64: return [NSString stringWithFormat:@"%llu", *(UInt64 *)[self value]];
+                       case TCInt32: return [NSString stringWithFormat:@"%u", *(UInt32 *)[self value]];
+                       case TCInt16: return [NSString stringWithFormat:@"%u", *(UInt16 *)[self value]];
+                       case TCInt8: return [NSString stringWithFormat:@"%u", *(UInt8 *)[self value]];
+               }
+       }
+       else {
+               switch ( _type ) {
+                       case TCInt64: return [NSString stringWithFormat:@"%lli", *(SInt64 *)[self value]];
+                       case TCInt32: return [NSString stringWithFormat:@"%i", *(SInt32 *)[self value]];
+                       case TCInt16: return [NSString stringWithFormat:@"%i", *(SInt16 *)[self value]];
+                       case TCInt8: return [NSString stringWithFormat:@"%i", *(SInt8 *)[self value]];
+               }
+       }
+       return @"foobar";
+}
+
+- (BOOL)setStringValue:(NSString *)string
+{
+       NSScanner *scanner = [NSScanner scannerWithString:string];
+       
+       // invalid until proven valid
+       _isValueValid = NO;
+       
+       switch ( _type ) {
+               case TCInt64:
+               {
+                       SInt64 value;
+                       if ( [scanner scanLongLong:(long long *)(&value)] ) {
+                               [self setValue:&value];
+                       }
+                       break;
+               }
+               case TCInt32:
+               {
+                       SInt32 value;
+                       if ( [scanner scanInt:(int *)(&value)] ) {
+                               [self setValue:&value];
+                       }
+                       break;
+               }
+               case TCInt16:
+               {
+                       int integer;
+                       SInt16 value;
+                       if ( [scanner scanInt:&integer] ) {
+                               value = integer;
+                               [self setValue:&value];
+                       }
+                       break;
+               }
+               case TCInt8:
+               {
+                       int integer;
+                       SInt8 value;
+                       if ( [scanner scanInt:&integer] ) {
+                               value = integer;
+                               [self setValue:&value];
+                       }
+                       break;
+               }
+               case TCString:
+               {
+                       char *str = (char *)[string lossyCString];
+                       unsigned len = strlen( str );
+                       [self setValue:str size:len];
+                       break;
+               }
+               case TCFloat:
+               {
+                       float value;
+                       if ( [scanner scanFloat:&value] ) {
+                               [self setValue:&value];
+                       }
+                       break;
+               }
+               case TCDouble:
+               {
+                       double value;
+                       if ( [scanner scanDouble:&value] ) {
+                               [self setValue:&value];
+                       }
+                       break;
+               }
+       }
+       return [self isValueValid];
+}
+
+
+- (unsigned)valueSize
+{
+       return _size;
+}
+
+- (BOOL)isValueValid
+{
+       return _isValueValid;
+}
+
+
+- (BOOL)isEnabled
+{
+       return _enabled;
+}
+
+- (void)setEnabled:(BOOL)enabled
+{
+       _enabled = enabled;
+}
+
+
+- (int)tag
+{
+       return _tag;
+}
+
+- (void)setTag:(int)tag
+{
+       _tag = tag;
+}
+
+
+@end
diff --git a/VariableTable.h b/VariableTable.h
new file mode 100644 (file)
index 0000000..de81f4c
--- /dev/null
@@ -0,0 +1,38 @@
+//
+//  VariableTable.h
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 12/28/04.
+//  Copyright 2004 Chaz McGarvey. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+#include "ChazLog.h"
+
+#import "BetterTableView.h"
+
+#import "TrackerScroller.h"
+
+/*
+ * This class lets you get which rows are currently visible and has a delegate
+ * method which is called when the visible rows changes.
+ */
+
+
+@interface VariableTable : BetterTableView
+{
+       BOOL _dontUpdate;
+       BOOL _updatePending;
+       NSRange _visibleRows;
+}
+
+- (NSRange)visibleRows;
+
+@end
+
+
+@interface NSObject ( VariableTableViewDelegate )
+
+- (void)tableView:(NSTableView *)aTableView didChangeVisibleRows:(NSRange)rows;
+
+@end
\ No newline at end of file
diff --git a/VariableTable.m b/VariableTable.m
new file mode 100644 (file)
index 0000000..283b1e8
--- /dev/null
@@ -0,0 +1,132 @@
+//
+//  VariableTable.m
+//  The Cheat
+//
+//  Created by Chaz McGarvey on 12/28/04.
+//  Copyright 2004 Chaz McGarvey. All rights reserved.
+//
+
+#import "VariableTable.h"
+
+
+@interface VariableTable ( PrivateAPI )
+
+- (void)_setVisibleRows:(NSRange)rows;
+
+@end
+
+
+@implementation VariableTable
+
+
+- (void)awakeFromNib
+{
+       NSScrollView *scrollView = (NSScrollView *)[(NSClipView *)[self superview] superview];
+       NSScroller *oldScroller = [[scrollView verticalScroller] retain];
+       
+       TrackerScroller *scroller = [[TrackerScroller alloc] initWithFrame:[oldScroller frame]];
+       
+       [scroller setControlSize:[oldScroller controlSize]];    
+       [scroller setFloatValue:[oldScroller floatValue] knobProportion:[oldScroller knobProportion]];
+       [scroller setControlTint:[oldScroller controlTint]];
+       
+       // set the new scroller
+       [scrollView setHasVerticalScroller:NO];
+       [scrollView setVerticalScroller:scroller];
+       [scrollView setHasVerticalScroller:YES];
+       
+       [scroller setDelegate:self];
+       [scroller release];
+       [oldScroller release];
+       
+       /*if ( [super respondsToSelector:@selector(awakeFromNib)] ) {
+               [super awakeFromNib];
+       }*/
+}
+
+
+- (NSRange)visibleRows
+{
+       return _visibleRows;
+}
+
+- (void)_setVisibleRows:(NSRange)rows
+{
+       _visibleRows = rows;
+}
+
+
+- (void)reloadData
+{
+       if ( _dontUpdate ) {
+               _updatePending = YES;
+               return;
+       }
+       
+       [super reloadData];
+       
+       NSRange range = [self rowsInRect:[(NSClipView *)[self superview] documentVisibleRect]];
+       id delegate = [self delegate];
+       
+       if ( !NSEqualRanges( range, _visibleRows ) ) {
+               [self _setVisibleRows:range];
+               if ( [delegate respondsToSelector:@selector(tableView:didChangeVisibleRows:)] ) {
+                       [delegate tableView:self didChangeVisibleRows:range];
+               }
+       }
+}
+
+
+- (void)keyDown:(NSEvent *)theEvent
+{
+       _dontUpdate = YES;
+       [super keyDown:theEvent];
+}
+
+- (void)keyUp:(NSEvent *)theEvent
+{
+       NSRange range = [self rowsInRect:[(NSClipView *)[self superview] documentVisibleRect]];
+       id delegate = [self delegate];
+       
+       [super keyUp:theEvent];
+       
+       _dontUpdate = NO;
+       
+       if ( !NSEqualRanges( range, _visibleRows ) ) {
+               [self _setVisibleRows:range];
+               if ( [delegate respondsToSelector:@selector(tableView:didChangeVisibleRows:)] ) {
+                       [delegate tableView:self didChangeVisibleRows:range];
+               }
+       }
+       else if ( _updatePending ) {
+               [self reloadData];
+               _updatePending = NO;
+       }
+}
+
+- (void)scrollerDidStartScrolling:(TrackerScroller *)scroller
+{
+       _dontUpdate = YES;
+}
+
+- (void)scrollerDidStopScrolling:(TrackerScroller *)scroller
+{
+       NSRange range = [self rowsInRect:[(NSClipView *)[self superview] documentVisibleRect]];
+       id delegate = [self delegate];
+       
+       _dontUpdate = NO;
+       
+       if ( !NSEqualRanges( range, _visibleRows ) ) {
+               [self _setVisibleRows:range];
+               if ( [delegate respondsToSelector:@selector(tableView:didChangeVisibleRows:)] ) {
+                       [delegate tableView:self didChangeVisibleRows:range];
+               }
+       }
+       else if ( _updatePending ) {
+               [self reloadData];
+               _updatePending = NO;
+       }
+}
+
+
+@end
diff --git a/cheat_global.h b/cheat_global.h
new file mode 100644 (file)
index 0000000..aa3cd96
--- /dev/null
@@ -0,0 +1,69 @@
+
+// **********************************************************************
+// 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.
+// 
+
+#ifndef _cheat_shared_H
+#define _cheat_shared_H
+
+
+// constants
+#define TCDefaultListenPort ( 51835 )
+#define TCUpdateCheckURL ( @"http://www.brokenzipper.com/software.plist" )
+
+#define TCDefaultFadeAnimation (0.15)
+
+
+// globals
+float extern gFadeAnimationDuration;
+
+
+// user default constants
+NSString extern *TCFirstLaunchPref;
+NSString extern *TCWindowsOnTopPref;
+NSString extern *TCUpdateCheckPref;
+NSString extern *TCDisplayValuesPref;
+NSString extern *TCValueUpdatePref;
+NSString extern *TCHitsDisplayedPref;
+NSString extern *TCRunServerPref;
+NSString extern *TCBroadcastNamePref;
+NSString extern *TCListenPortPref;
+NSString extern *TCFadeAnimationPref;
+NSString extern *TCAskForSavePref;
+NSString extern *TCSwitchVariablesPref;
+NSString extern *TCAutoStartEditingVarsPref;
+
+// notification constants
+NSString extern *TCServiceFoundNote;
+NSString extern *TCServiceRemovedNote;
+NSString extern *TCServerStartedNote;
+NSString extern *TCServerStoppedNote;
+NSString extern *TCServerConnectionsChangedNote;
+NSString extern *TCWindowsOnTopChangedNote;
+NSString extern *TCDisplayValuesChangedNote;
+NSString extern *TCHitsDisplayedChangedNote;
+
+
+void LaunchWebsite();
+void LaunchEmail();
+
+int MacOSXVersion();
+NSString *ApplicationVersion( NSString *appPath );
+
+
+#endif
\ No newline at end of file
diff --git a/cheat_global.m b/cheat_global.m
new file mode 100644 (file)
index 0000000..0cf49bb
--- /dev/null
@@ -0,0 +1,135 @@
+
+// **********************************************************************
+// 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 "cheat_global.h"
+
+#import <Carbon/Carbon.h>
+
+
+// globals
+float gFadeAnimationDuration = TCDefaultFadeAnimation;
+
+
+// user default constants
+NSString *TCFirstLaunchPref = nil;
+NSString *TCWindowsOnTopPref = @"TCWindowsOnTopPref";
+NSString *TCUpdateCheckPref = @"TCUpdateCheckPref";
+NSString *TCDisplayValuesPref = @"TCDisplayValuesPref";
+NSString *TCValueUpdatePref = @"TCValueUpdatePref";
+NSString *TCHitsDisplayedPref = @"TCHitsDisplayedPref";
+NSString *TCRunServerPref = @"TCRunServerPref";
+NSString *TCBroadcastNamePref = @"TCBroadcastNamePref";
+NSString *TCListenPortPref = @"TCListenPortPref";
+NSString *TCFadeAnimationPref = @"TCFadeAnimationPref";
+NSString *TCAskForSavePref = @"TCAskForSavePref";
+NSString *TCSwitchVariablesPref = @"TCSwitchVariablesPref";
+NSString *TCAutoStartEditingVarsPref = @"TCAutoStartEditingVarsPref";
+
+
+// notification constants
+NSString *TCServiceFoundNote = @"TCServiceFoundNote";
+NSString *TCServiceRemovedNote = @"TCServiceRemovedNote";
+NSString *TCServerStartedNote = @"TCServerStartedNote";
+NSString *TCServerStoppedNote = @"TCServerStoppedNote";
+NSString *TCServerConnectionsChangedNote = @"TCServerConnectionsChangedNote";
+NSString *TCWindowsOnTopChangedNote = @"TCWindowsOnTopChangedNote";
+NSString *TCDisplayValuesChangedNote = @"TCDisplayValuesChangedNote";
+NSString *TCHitsDisplayedChangedNote = @"TCHitsDisplayedChangedNote";
+
+
+void LaunchWebsite()
+{
+       [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://www.brokenzipper.com/"]];
+}
+
+void LaunchEmail()
+{
+       [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"mailto:chaz@brokenzipper.com?subject=The%20Cheat%20Feedback"]];
+}
+
+
+int MacOSXVersion()
+{
+       SInt32 static           version = -1;
+       
+       if ( version != -1 ) {
+               return (int)version;
+       }
+       
+       // get the version
+       if ( Gestalt( gestaltSystemVersion, &version ) != noErr ) {
+               return -1;
+       }
+       return (int)version;
+}
+
+NSString *ApplicationVersion( NSString *appPath )
+{
+       NSString *tVersion = nil;
+       NSBundle *tBundle = [NSBundle bundleWithPath:appPath];  
+       
+       if ( tBundle ) {
+               NSDictionary            *tInfoDictionary;
+               
+               tInfoDictionary = [tBundle infoDictionary];
+               
+               if ( tInfoDictionary ) {
+                       tVersion = [tInfoDictionary objectForKey:@"CFBundleShortVersionString"];
+                       if ( !tVersion ) {
+                               tVersion = [tInfoDictionary objectForKey:@"CFBundleVersion"];
+                       }
+               }
+       }
+       else {
+               CFBundleRef             tBundleRef;
+               short                   resNum = 0;
+               
+               tBundleRef = CFBundleCreate( NULL, (CFURLRef)[NSURL fileURLWithPath:appPath] );
+               
+               if ( tBundleRef ) {
+                       resNum = CFBundleOpenBundleResourceMap( tBundleRef );
+               }
+               
+               if ( resNum != 0 ) {
+                       VersRecHndl             tVersionHandle;
+                       unsigned long   tNumVersion;
+                       
+                       tVersionHandle = (VersRecHndl)Get1IndResource( 'vers', 1 );
+                       
+                       if ( tVersionHandle ) {
+                               tNumVersion = *((unsigned long *) &((*tVersionHandle)->numericVersion));
+                               
+                               if ( (tNumVersion & 0x00040000) != 0 ) {
+                                       tVersion = [NSString stringWithFormat:@"%d.%d.%d", (tNumVersion & 0xFF000000)>>24, (tNumVersion & 0x00F00000)>>20, (tNumVersion & 0x000F0000)>>16];
+                               }
+                               else {
+                                       tVersion = [NSString stringWithFormat:@"%d.%d", (tNumVersion & 0xFF000000)>>24, (tNumVersion & 0x00F00000)>>20];
+                               }
+                       }
+                       
+               }
+               if ( tBundleRef ) {
+                       CFBundleCloseBundleResourceMap( tBundleRef, resNum );
+                       // Release Memory
+                       CFRelease( tBundleRef );
+               }
+       }
+       return tVersion;        
+}
diff --git a/cheat_globals.h b/cheat_globals.h
deleted file mode 100644 (file)
index 22d748b..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      cheat_globals.h
-// Created:   Fri Sep 19 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#ifndef _cheat_globals_H
-#define _cheat_globals_H
-
-#import <Cocoa/Cocoa.h>
-
-#define                                        TCDefaultListenPort (51835)
-//#define                                      TCDefaultListenPath "/tmp/com.brokenzipper.TheCheat"
-// this path alone would work, but it *should* go in the user's home directory
-char extern                            TCDefaultListenPath[104];
-
-//#define                                      TCMaxSearchResults (100)
-
-int extern                             TCGlobalSessionCount;
-int extern                             TCGlobalAlternateBroadcastNameCount;
-char extern                            TCGlobalListening;
-
-char extern                            TCGlobalPlaySounds;
-char extern                            TCGlobalWindowsOnTop;
-char extern                            TCGlobalUpdateCheck;
-char extern                            TCGlobalAllowRemote;
-int extern                             TCGlobalListenPort;
-#define                                        TCGlobalBroadcastName ([[NSUserDefaults standardUserDefaults] objectForKey:TCBroadcastNamePref])
-int extern                             TCGlobalHitsDisplayed;
-
-NSString extern                        *TCPlaySoundsPref;
-NSString extern                        *TCWindowsOnTopPref;
-NSString extern                        *TCUpdateCheckPref;
-NSString extern                        *TCAllowRemotePref;
-NSString extern                        *TCListenPortPref;
-NSString extern                        *TCBroadcastNamePref;
-NSString extern                        *TCHitsDisplayedPref;
-
-#endif
-
diff --git a/cheat_globals.m b/cheat_globals.m
deleted file mode 100644 (file)
index 019c725..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      cheat_globals.m
-// Created:   Fri Sep 19 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#include "cheat_globals.h"
-
-char                                   TCDefaultListenPath[104] = "/.thecheat_socket";
-
-int                                            TCGlobalSessionCount = 0;
-int                                            TCGlobalAlternateBroadcastNameCount = 2;
-char                                   TCGlobalListening = NO;
-
-char                                   TCGlobalPlaySounds = YES;
-char                                   TCGlobalWindowsOnTop = NO;
-char                                   TCGlobalUpdateCheck = NO;
-char                                   TCGlobalAllowRemote = NO;
-int                                            TCGlobalListenPort = TCDefaultListenPort;
-int                                            TCGlobalHitsDisplayed = 1000;
-
-NSString                               *TCPlaySoundsPref = @"TCPlaySoundsPref";
-NSString                               *TCWindowsOnTopPref = @"TCWindowsOnTopPref";
-NSString                               *TCUpdateCheckPref = @"TCUpdateCheckPref";
-NSString                               *TCAllowRemotePref = @"TCAllowRemotePref";
-NSString                               *TCListenPortPref = @"TCListenPortPref";
-NSString                               *TCBroadcastNamePref = @"TCBroadcastNamePref";
-NSString                               *TCHitsDisplayedPref = @"TCHitsDisplayedPref";
\ No newline at end of file
diff --git a/cheat_net.h b/cheat_net.h
deleted file mode 100644 (file)
index 38718de..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      cheat_net.h
-// Created:   Mon Sep 08 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#ifndef _cheat_net_H
-#define _cheat_net_H
-
-#import <Chaz/Chaz.h>
-
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-
-// macros
-
-#define COPY_TO_BUFFER( to, from, size )       memcpy( to, from, size ), (char *)to += size;
-#define COPY_FROM_BUFFER( to, from, size )     memcpy( to, from, size ), (char *)from += size;
-
-
-struct tagPacketHeader
-{
-       u_int32_t               checksum;
-       u_int32_t               function;
-       u_int32_t               size;
-};
-
-typedef struct tagPacketHeader PacketHeader;
-
-
-u_int32_t RandomChecksum();
-char VerifyChecksum( u_int32_t checksum );
-int CountBits( u_int8_t byte );
-
-int SendBuffer( int socket, char const *buffer, int *length );
-int ReadBuffer( int socket, char *buffer, int length );
-
-
-#endif
-
diff --git a/cheat_net.m b/cheat_net.m
deleted file mode 100644 (file)
index f668f1a..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      cheat_net.m
-// Created:   Mon Sep 08 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#include "cheat_net.h"
-
-
-u_int32_t RandomChecksum()
-{
-       u_int8_t                byte1, byte2, byte3, byte4;
-       char                    *ptr;
-       
-       u_int32_t               checksum;
-       long                    randomValue = random();
-
-       byte1 = randomValue & 0xFF;
-       byte2 = (randomValue >> 8) & 0xFF;
-       byte3 = (randomValue >> 16) & 0xFF;
-       byte4 = CountBits( byte1 ) + CountBits( byte2 ) + CountBits( byte3 );
-       
-       ptr = (char *)(&checksum);
-
-       COPY_TO_BUFFER( ptr, &byte1, sizeof(byte1) );
-       COPY_TO_BUFFER( ptr, &byte2, sizeof(byte2) );
-       COPY_TO_BUFFER( ptr, &byte3, sizeof(byte3) );
-       COPY_TO_BUFFER( ptr, &byte4, sizeof(byte4) );
-
-       return checksum;
-}
-
-char VerifyChecksum( u_int32_t checksum )
-{
-       u_int8_t                byte1, byte2, byte3, byte4;
-       char                    *ptr = (char *)(&checksum);
-
-       COPY_FROM_BUFFER( &byte1, ptr, sizeof(byte1) );
-       COPY_FROM_BUFFER( &byte2, ptr, sizeof(byte2) );
-       COPY_FROM_BUFFER( &byte3, ptr, sizeof(byte3) );
-       COPY_FROM_BUFFER( &byte4, ptr, sizeof(byte4) );
-
-       if ( (CountBits( byte1 ) + CountBits( byte2 ) + CountBits( byte3 )) == byte4 )
-       {
-               return 1;
-       }
-
-       CMLog( @"checksum failed" );
-
-       return 0;
-}
-
-int CountBits( u_int8_t byte )
-{
-       int                             count = 0;
-       int                             i;
-
-       for ( i = 0; i < 8; i++ )
-       {
-               count += byte & 1;
-
-               byte >>= 1;
-       }
-
-       return count;
-}
-
-
-int SendBuffer( int sockfd, char const *buffer, int *length )
-{
-       int                             bytesSent = 0;
-       int                             bytesLeft = *length;
-       int                             n = 0;
-
-       while( bytesSent < *length )
-       {
-               if ( (n = send( sockfd, buffer+bytesSent, bytesLeft, 0 )) == -1 )
-               {
-                       break;
-               }
-
-               bytesSent += n;
-               bytesLeft -= n;
-       }
-
-       *length = bytesSent;
-
-       return (n == -1)? -1:0;
-}
-
-int ReadBuffer( int sockfd, char *buffer, int length )
-{
-       int                             bytesRead = 0;
-       int                             bytesLeft = length;
-       int                             n;
-
-       while( bytesRead < length )
-       {
-               if ( (n = recv( sockfd, buffer+bytesRead, bytesLeft, 0 )) == -1 || n == 0 )
-               {
-                       return (bytesRead > 0)? bytesRead:n;
-               }
-
-               bytesRead += n;
-               bytesLeft -= n;
-       }
-
-       return bytesRead;
-}
\ No newline at end of file
diff --git a/cheat_shared.h b/cheat_shared.h
deleted file mode 100644 (file)
index 43f9dd7..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      cheat_shared.h
-// Created:   Mon Nov 24 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#ifndef _cheat_shared_H
-#define _cheat_shared_H
-
-
-void LaunchWebsite();
-void LaunchEmail();
-
-
-#endif
\ No newline at end of file
diff --git a/cheat_shared.m b/cheat_shared.m
deleted file mode 100644 (file)
index 48062c2..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      cheat_shared.m
-// Created:   Mon Nov 24 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#import "cheat_shared.h"
-
-
-void LaunchWebsite()
-{
-       [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://www.brokenzipper.com/"]];
-}
-
-void LaunchEmail()
-{
-       [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"mailto:thecheat@brokenzipper.com?subject=The%20Cheat%20Feedback"]];
-}
\ No newline at end of file
diff --git a/cheat_types.h b/cheat_types.h
deleted file mode 100644 (file)
index 92a5622..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      cheat_types.h
-// Created:   Thu Sep 11 2003
-//
-// Copyright: 2003 Chaz McGarvey.  All rights reserved.
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#ifndef _cheat_types_H
-#define _cheat_types_H
-
-
-enum tagTCtype
-{
-       TYPE_INTEGER, TYPE_STRING, TYPE_DECIMAL, TYPE_UNKNOWN
-};
-typedef int                    TCtype;
-
-enum tagTCsize
-{
-       SIZE_8_BIT, SIZE_16_BIT, SIZE_32_BIT, SIZE_64_BIT
-};
-typedef int                    TCsize;
-
-enum tagTCstatus
-{
-       STATUS_DISCONNECTED, STATUS_CONNECTED, STATUS_CHEATING, STATUS_SEARCHING, STATUS_CHANGING, STATUS_CHANGING_LATER, STATUS_CHANGING_CONTINUOUSLY, STATUS_UNDOING, STATUS_REDOING
-};
-typedef int                    TCstatus;
-// NOTE: STATUS_CHANGING_LATER should not be used, as this future is not implemented.
-
-
-typedef long unsigned          TCaddress;
-#define                                                TCAddressSize sizeof(TCaddress)
-
-
-#endif
-
diff --git a/disc_session.tif b/disc_session.tif
new file mode 100644 (file)
index 0000000..7f0dcf9
Binary files /dev/null and b/disc_session.tif differ
index fa0c1d0cc52db7e0cde1f5388ff35075f6c5eab4..418b7801cf5531065c7677c2269c4246a8ae8c69 100644 (file)
Binary files a/icon.icns and b/icon.icns differ
index a0f68ef3a7f91f3dc52aa3c20a5a87cab134aa1c..77972d6edd37e8f9efa52c4214f57eee5af3a9d4 100644 (file)
Binary files a/icondoc.icns and b/icondoc.icns differ
diff --git a/main.m b/main.m
index c990b8c8382529e5ae69a8fe4dabf2a871da30e7..6c98a2ddcb9f1043f7428e938fb1890bb0fe3607 100644 (file)
--- a/main.m
+++ b/main.m
@@ -1,22 +1,39 @@
 
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Project:   The Cheat
-//
-// File:      main.m
-// Created:   Sun Sep 07 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 <Cocoa/Cocoa.h>
-
-#include <stdlib.h>
-#include <time.h>
+#include "ChazLog.h"
 
 
 int main( int argc, const char *argv[] )
 {
-       srandom( time(0) );
+       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+       
+       ChazLogDisable();
+       
+       ChazDebugSetup();
+       ChazMapLogToDebug();
+       
+       [pool release];
+       
+    return NSApplicationMain( argc, (const char **) argv );
        
-    return NSApplicationMain( argc, argv );
+       ChazDebugCleanup();
 }
\ No newline at end of file
diff --git a/version.plist b/version.plist
new file mode 100644 (file)
index 0000000..6f3c68c
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>BuildVersion</key>
+       <string>1</string>
+       <key>CFBundleShortVersionString</key>
+       <string>0.1</string>
+       <key>CFBundleVersion</key>
+       <string>0.1</string>
+       <key>ProjectName</key>
+       <string>NibPBTemplates</string>
+       <key>SourceVersion</key>
+       <string>1160200</string>
+</dict>
+</plist>
This page took 0.824263 seconds and 4 git commands to generate.