X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fthecheat;a=blobdiff_plain;f=DocInterfaceActions.m;fp=DocInterfaceActions.m;h=f53ddf3e512aa6a0d612aeb899166c99a49aeae3;hp=0000000000000000000000000000000000000000;hb=d27548f80fe411fda2ee69c74a24eab4292267e9;hpb=e8d51183acdd2410a38dcf8f0efbf7c30cd6c581 diff --git a/DocInterfaceActions.m b/DocInterfaceActions.m new file mode 100644 index 0000000..f53ddf3 --- /dev/null +++ b/DocInterfaceActions.m @@ -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