]> Dogcows Code - chaz/thecheat/blobdiff - DocInterfaceActions.m
The Cheat 1.2
[chaz/thecheat] / DocInterfaceActions.m
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
This page took 0.029772 seconds and 4 git commands to generate.