]> Dogcows Code - chaz/thecheat/blob - DocInterfaceActions.m
The Cheat 1.2.4
[chaz/thecheat] / DocInterfaceActions.m
1
2 // **********************************************************************
3 // The Cheat - A universal game cheater for Mac OS X
4 // (C) 2003-2005 Chaz McGarvey (BrokenZipper)
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 1, or (at your option)
9 // any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 //
20
21
22 #import "CheatDocument.h"
23
24
25 @interface CheatDocument (DocumentActionsPrivateAPI )
26
27 - (void)_confirmTargetChange:(NSWindow *)sheet returnCode:(int)returnCode context:(void *)contextInfo;
28
29 @end
30
31
32 @implementation CheatDocument ( DocumentActions )
33
34
35 - (IBAction)ibSetLocalCheater:(id)sender
36 {
37 ChazLog( @"Selected %@", sender );
38
39 // if this is the current server, don't reconnect
40 if ( ![self shouldConnectWithServer:sender] ) {
41 return;
42 }
43
44 // disconnect and prepare to reconnect
45 [self disconnectFromCheater];
46 [self connectWithServer:sender];
47
48 // create new local cheater
49 _cheater = [[LocalCheater alloc] initWithDelegate:self];
50 [(LocalCheater *)_cheater setShouldCopy:YES];
51
52 // send initial messages
53 [_cheater connect];
54 [_cheater getProcessList];
55
56 // send preferences to the cheater
57 [_cheater limitReturnedResults:[[NSUserDefaults standardUserDefaults] integerForKey:TCHitsDisplayedPref]];
58
59 [ibStatusText setDefaultStatus:[self defaultStatusString]];
60 }
61
62 - (IBAction)ibSetRemoteCheater:(id)sender
63 {
64 ChazLog( @"Selected %@", sender );
65
66 if ( ![self shouldConnectWithServer:sender] ) {
67 return;
68 }
69
70 ChazLog( @"resolving rendezvous service..." );
71
72 _resolvingService = [[sender representedObject] retain];
73 [_resolvingService setDelegate:self];
74 [_resolvingService resolve];
75 }
76
77 - (void)netServiceDidResolveAddress:(NSNetService *)sender
78 {
79 NSArray *addresses;
80
81 ChazLog( @"service resolved!" );
82
83 // stop resolving
84 [sender stop];
85
86 if ( sender != _resolvingService ) {
87 return;
88 }
89
90 [self disconnectFromCheater];
91 [self connectWithServer:(NSMenuItem *)[ibServerPopup itemAtIndex:[ibServerPopup indexOfItemWithRepresentedObject:_resolvingService]]];
92
93 addresses = [_resolvingService addresses];
94
95 _resolvingService = nil;
96
97 // create new remote cheater
98 ChazLog( @"found %i addresses", [addresses count] );
99 _cheater = [[RemoteCheater alloc] initWithDelegate:self];
100 [(RemoteCheater *)_cheater connectToHostWithData:[addresses objectAtIndex:0]];
101
102 // send initial messages
103 [_cheater connect];
104 [_cheater getProcessList];
105
106 // send preferences to the cheater
107 [_cheater limitReturnedResults:[[NSUserDefaults standardUserDefaults] integerForKey:TCHitsDisplayedPref]];
108
109 [ibStatusText setDefaultStatus:[self defaultStatusString]];
110 [self updateInterface];
111 }
112
113 - (void)netService:(NSNetService *)sender didNotResolve:(NSDictionary *)errorDict
114 {
115 [sender stop];
116
117 if ( sender != _resolvingService ) {
118 return;
119 }
120
121 _resolvingService = nil;
122
123 NSBeginInformationalAlertSheet( @"The Cheat can't find the server.", @"OK", nil, nil, ibWindow, self, NULL, NULL, NULL,
124 @"The Cheat can't connect to the server \"%@\" because it can't be found.", [sender name] );
125 }
126
127 - (void)netServiceDidStop:(NSNetService *)sender
128 {
129 [sender release];
130 }
131
132 - (IBAction)ibSetCustomCheater:(id)sender
133 {
134 RemoteCheater *cheater;
135 ChazLog( @"Selected %@", [sender description] );
136
137 if ( ![self shouldConnectWithServer:sender] ) {
138 return;
139 }
140
141 cheater = [[RemoteCheater alloc] initWithDelegate:self];
142 if ( ![(RemoteCheater *)cheater connectToHostWithData:[sender representedObject]] ) {
143 NSBeginInformationalAlertSheet( @"The Cheat can't find the server.", @"OK", nil, nil, ibWindow, self, NULL, NULL, NULL,
144 @"The Cheat can't connect to \"%@\" because there is no server at that address.", [sender title] );
145 [cheater release];
146 [self selectConnectedCheater];
147 return;
148 }
149
150 [self disconnectFromCheater];
151 [self connectWithServer:sender];
152
153 _cheater = cheater;
154
155 // send initial messages
156 [_cheater connect];
157 [_cheater getProcessList];
158
159 // send preferences to the cheater
160 [_cheater limitReturnedResults:[[NSUserDefaults standardUserDefaults] integerForKey:TCHitsDisplayedPref]];
161
162 [ibStatusText setDefaultStatus:[self defaultStatusString]];
163 [self updateInterface];
164 }
165
166 - (IBAction)ibSetNoCheater:(id)sender
167 {
168 [self disconnectFromCheater];
169
170 // nil server object
171 [_serverObject release];
172 _serverObject = nil;
173
174 [ibStatusText setDefaultStatus:[self defaultStatusString]];
175 [self updateInterface];
176 }
177
178 - (IBAction)ibSetProcess:(id)sender
179 {
180 if ( [_process isEqual:(Process *)[sender representedObject]] ) {
181 // this process is already selected, do nothing
182 return;
183 }
184
185 [_cheatData process];
186 if ( [_searchData hasSearchedOnce] ) {
187 NSBeginInformationalAlertSheet( @"Confirm target change.", @"OK", @"Cancel", nil, ibWindow, self, NULL,
188 @selector(_confirmTargetChange:returnCode:context:), [[sender representedObject] retain],
189 @"If you change the target now, your search will be cleared. This cannot be undone. Continue?" );
190 }
191 else {
192 // request the change
193 [_cheater setTarget:(Process *)[sender representedObject]];
194 }
195 }
196
197 - (void)_confirmTargetChange:(NSWindow *)sheet returnCode:(int)returnCode context:(void *)contextInfo
198 {
199 NSMenu *processMenu = [ibProcessPopup menu];
200 Process *process = (Process *)contextInfo;
201
202 if ( returnCode == NSAlertDefaultReturn ) {
203 // clear the search
204 [self ibClearSearch:nil];
205 // request the change
206 [_cheater setTarget:process];
207 }
208 else {
209 // select the correct server menuitem
210 [ibProcessPopup selectItemAtIndex:[processMenu indexOfItemWithRepresentedObject:_process]];
211 }
212
213 [process release];
214 }
215
216
217 - (IBAction)ibSetVariableType:(id)sender
218 {
219 [_searchData setVariableType:[sender tag]];
220 [self updateInterface];
221 }
222
223 - (IBAction)ibSetIntegerSign:(id)sender
224 {
225 [_searchData setIntegerSign:[[sender selectedCell] tag]];
226 }
227
228 - (IBAction)ibSetOperator:(id)sender
229 {
230 [_searchData setSearchOperator:[sender tag]];
231 }
232
233 - (IBAction)ibSetValueUsed:(id)sender
234 {
235 [_searchData setValueUsed:[[sender selectedCell] tag]];
236 [self updateInterface];
237 }
238
239 - (IBAction)ibClearSearch:(id)sender
240 {
241 [_cheater clearSearch];
242 }
243
244 - (IBAction)ibSearch:(id)sender
245 {
246 Variable *variable;
247
248 // do the search
249 if ( [_searchData valueUsed] == TCGivenValue ) {
250 variable = [[Variable alloc] initWithType:[_searchData variableType] integerSign:[_searchData integerSign]];
251 [variable setProcess:_process];
252 [variable setStringValue:[ibSearchValueField stringValue]];
253 if ( [variable isValueValid] && [variable valueSize] > 0 ) {
254 _status = TCSearchingStatus;
255 [ibStatusText setDefaultStatus:[NSString stringWithFormat:@"Searching %@'s memory%C", [_process name], 0x2026]];
256 [ibStatusBar setIndeterminate:NO];
257
258 [_searchData setSearchValue:variable];
259 [_cheater searchForVariable:variable comparison:[_searchData searchOperator]];
260 //[_cheater searchForVariable:[_searchData searchValue] comparison:[_searchData searchOperator]];
261 [variable release];
262 }
263 else {
264 NSBeginAlertSheet( @"Invalid Input", @"OK", nil, nil, ibWindow, nil, NULL, NULL, NULL,
265 @"The search value \"%@\" cannot be used with this type of search.", [ibSearchValueField stringValue] );
266 }
267 }
268 else {
269 _status = TCSearchingStatus;
270 [ibStatusText setDefaultStatus:[NSString stringWithFormat:@"Searching %@'s memory%C", [_process name], 0x2026]];
271 [ibStatusBar setIndeterminate:NO];
272
273 [_cheater searchLastValuesComparison:[_searchData searchOperator]];
274 }
275
276 [self updateInterface];
277 }
278
279 - (IBAction)ibAddSearchVariable:(id)sender
280 {
281 NSArray *rows;
282 int i, top;
283
284 // don't do anything if there is nothing selected
285 if ( [ibSearchVariableTable selectedRow] == -1 ) {
286 return;
287 }
288
289 rows = [ibSearchVariableTable selectedRows];
290 top = [rows count];
291 for ( i = 0; i < top; i++ ) {
292 int rowIndex = [[rows objectAtIndex:i] unsignedIntValue];
293 // transfer the search variable to the cheat data
294 [_cheatData addVariable:[_searchData variableAtIndex:rowIndex]];
295 }
296
297 // update the variable table
298 [ibCheatVariableTable reloadData];
299
300 if ( [[NSUserDefaults standardUserDefaults] boolForKey:TCSwitchVariablesPref] ) {
301 [self switchToCheatMode];
302
303 int rowIndex = [_cheatData variableCount]-1;
304 if ( MacOSXVersion() >= 0x1030 ) {
305 [ibCheatVariableTable selectRowIndexes:[NSIndexSet indexSetWithIndex:rowIndex] byExtendingSelection:NO];
306 }
307 else {
308 [ibCheatVariableTable selectRow:rowIndex byExtendingSelection:NO];
309 }
310 // start editing the last added variable
311 if ( [[NSUserDefaults standardUserDefaults] boolForKey:TCAutoStartEditingVarsPref] ) {
312 if ( top > 1 ) {
313 // edit multiple
314 if ( MacOSXVersion() >= 0x1030 ) {
315 [ibCheatVariableTable selectRowIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(rowIndex-top+1,top-1)]
316 byExtendingSelection:YES];
317 }
318 else {
319 for ( i = 1; i < top; i++ ) {
320 [ibCheatVariableTable selectRow:rowIndex-i byExtendingSelection:YES];
321 }
322 }
323 [ibCheatVariableTable scrollRowToVisible:rowIndex];
324 [self ibRunEditVariablesSheet:nil];
325 }
326 else {
327 // edit one
328 [ibCheatVariableTable editColumn:[ibCheatVariableTable columnWithIdentifier:@"value"]
329 row:rowIndex withEvent:nil select:YES];
330 }
331 }
332 }
333
334 // update interface
335 [self setDocumentChanged];
336 [self updateInterface];
337 }
338
339
340 - (IBAction)ibSetCheatRepeats:(id)sender
341 {
342 [_cheatData setRepeats:[sender state]];
343
344 // update interface
345 [self setDocumentChanged];
346 [self updateInterface];
347 }
348
349 - (IBAction)ibSetRepeatInterval:(id)sender
350 {
351 [_cheatData setRepeatInterval:[sender doubleValue]];
352
353 // update interface
354 [self setDocumentChanged];
355 [self updateInterface];
356 }
357
358 - (IBAction)ibCheat:(id)sender
359 {
360 _status = TCCheatingStatus;
361 [_cheater makeVariableChanges:[_cheatData enabledVariables] repeat:[_cheatData repeats] interval:[_cheatData repeatInterval]];
362
363 // update status description
364 if ( [_cheatData repeats] ) {
365 [ibStatusText setDefaultStatus:[NSString stringWithFormat:@"Applying cheats to %@%C", [_process name], 0x2026]];
366 [ibStatusBar setIndeterminate:YES];
367 [ibStatusBar startAnimation:self];
368
369 [self updateInterface];
370 }
371 }
372
373
374 - (IBAction)ibRunPropertiesSheet:(id)sender
375 {
376 // update fields
377 [ibWindowTitleField setStringValue:[_cheatData windowTitle]];
378 [ibCheatInfoField setStringValue:[_cheatData cheatInfo]];
379
380 // display sheet
381 [NSApp beginSheet:ibPropertiesSheet modalForWindow:ibWindow modalDelegate:nil didEndSelector:NULL contextInfo:nil];
382 }
383
384 - (IBAction)ibEndPropertiesSheet:(id)sender
385 {
386 [ibPropertiesSheet orderOut:sender];
387 [NSApp endSheet:ibPropertiesSheet returnCode:0];
388
389 if ( [sender tag] == 1 ) {
390 // do not update anything if nothing has changed
391 if ( [[ibWindowTitleField stringValue] isEqualToString:[_cheatData windowTitle]] &&
392 [[ibCheatInfoField stringValue] isEqualToString:[_cheatData cheatInfo]] ) {
393 return;
394 }
395 // update data
396 [_cheatData setWindowTitle:[ibWindowTitleField stringValue]];
397 [_cheatData setCheatInfo:[ibCheatInfoField stringValue]];
398
399 [self setDocumentChanged];
400 [self updateInterface];
401 }
402 }
403
404
405 - (IBAction)ibRunPasswordSheet:(id)sender
406 {
407
408 }
409
410 - (IBAction)ibEndPasswordSheet:(id)sender
411 {
412
413 }
414
415
416 - (IBAction)ibRunCustomServerSheet:(id)sender
417 {
418 // update fields
419 [ibServerField setStringValue:@""];
420 [ibPortField setStringValue:[NSString stringWithFormat:@"%i", TCDefaultListenPort]];
421
422 // display sheet
423 [NSApp beginSheet:ibCustomServerSheet modalForWindow:ibWindow modalDelegate:nil didEndSelector:NULL contextInfo:nil];
424 }
425
426 - (IBAction)ibEndCustomServerSheet:(id)sender
427 {
428 NSString *server = [ibServerField stringValue];
429 int port = [[ibPortField stringValue] intValue];
430
431 ChazLog( @"ibEndCustomServerSheet: %@:%i", server, port );
432
433 [ibCustomServerSheet orderOut:sender];
434 [NSApp endSheet:ibCustomServerSheet returnCode:0];
435
436 if ( [sender tag] == 1 ) {
437 [self connectWithURL:[NSString stringWithFormat:@"cheat://%@:%i", server, port]];
438 }
439 }
440
441
442 - (IBAction)ibRunEditVariablesSheet:(id)sender
443 {
444 int row = [ibCheatVariableTable selectedRow];
445 Variable *var;
446
447 // must have selected items
448 if ( row == -1 ) {
449 return;
450 }
451
452 var = [_cheatData variableAtIndex:row];
453
454 // update field
455 [ibNewValueField setStringValue:[var stringValue]];
456
457 // display sheet
458 [NSApp beginSheet:ibEditVariablesSheet modalForWindow:ibWindow modalDelegate:nil didEndSelector:NULL contextInfo:nil];
459 }
460
461 - (IBAction)ibEndEditVariablesSheet:(id)sender
462 {
463 NSString *newValue = [ibNewValueField stringValue];
464 NSArray *rows;
465 int i, top;
466
467 [ibEditVariablesSheet orderOut:sender];
468 [NSApp endSheet:ibEditVariablesSheet returnCode:0];
469
470 if ( [sender tag] == 0 ) {
471 return;
472 }
473 if ( [newValue isEqualToString:@""] ) {
474 newValue = nil;
475 }
476
477 rows = [ibCheatVariableTable selectedRows];
478 top = [rows count];
479
480 // change all selected variables with the new value
481 if ( newValue ) {
482 for ( i = 0; i < top; i++ ) {
483 Variable *var = [_cheatData variableAtIndex:[[rows objectAtIndex:i] unsignedIntValue]];
484 [var setStringValue:newValue];
485 }
486 }
487
488 [ibCheatVariableTable reloadData];
489
490 [self setDocumentChanged];
491 [self updateInterface];
492 }
493
494
495 - (IBAction)ibPauseTarget:(id)sender
496 {
497 [_cheater pauseTarget];
498 }
499
500 - (IBAction)ibResumeTarget:(id)sender
501 {
502 [_cheater resumeTarget];
503 }
504
505
506 - (IBAction)ibCancelSearch:(id)sender
507 {
508 _isCancelingTask = YES;
509 [_cheater cancelSearch];
510
511 [self updateInterface];
512 }
513
514 - (IBAction)ibStopCheat:(id)sender
515 {
516 _isCancelingTask = YES;
517 [_cheater stopChangingVariables];
518
519 [self updateInterface];
520 }
521
522
523 - (IBAction)ibDumpMemory:(id)sender
524 {
525 _status = TCDumpingStatus;
526 [_cheater getMemoryDump];
527
528 // display status
529 [ibStatusText setDefaultStatus:[NSString stringWithFormat:@"Dumping %@'s memory%C", [_process name], 0x2026]];
530 [ibStatusBar setIndeterminate:YES];
531 [ibStatusBar startAnimation:self];
532
533 [self updateInterface];
534 }
535
536 - (IBAction)ibCancelDump:(id)sender
537 {
538 _isCancelingTask = YES;
539 [_cheater cancelMemoryDump];
540
541 [self updateInterface];
542 }
543
544
545 - (IBAction)ibAddCheatVariable:(id)sender
546 {
547 ChazLog( @"ibAddCheatVariable:" );
548 Variable *var = [[Variable alloc] initWithType:[sender tag]];
549 // add the new variable to the doc data
550 [_cheatData addVariable:var];
551 [var release];
552 // update the variable table
553 [ibCheatVariableTable reloadData];
554
555 if ( [[NSUserDefaults standardUserDefaults] boolForKey:TCSwitchVariablesPref] ) {
556 [self switchToCheatMode];
557
558 int row = [_cheatData variableCount]-1;
559 if ( MacOSXVersion() >= 0x1030 ) {
560 [ibCheatVariableTable selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
561 }
562 else {
563 [ibCheatVariableTable selectRow:row byExtendingSelection:NO];
564 }
565 // start editing new variable
566 if ( [[NSUserDefaults standardUserDefaults] boolForKey:TCAutoStartEditingVarsPref] ) {
567 [ibCheatVariableTable editColumn:[ibCheatVariableTable columnWithIdentifier:@"address"] row:row withEvent:nil select:YES];
568 }
569 }
570
571 // update interface
572 [self setDocumentChanged];
573 [self updateInterface];
574 }
575
576 - (IBAction)ibSetVariableEnabled:(id)sender
577 {
578 NSArray *rows;
579 int i, top;
580
581 BOOL flag;
582
583 ChazLog( @"ibSetVariableEnabled: %i", [sender selectedRow] );
584
585 flag = [[_cheatData variableAtIndex:[ibCheatVariableTable selectedRow]] isEnabled];
586
587 rows = [ibCheatVariableTable selectedRows];
588 top = [rows count];
589
590 for ( i = 0; i < top; i++ ) {
591 Variable *var = [_cheatData variableAtIndex:[[rows objectAtIndex:i] unsignedIntValue]];
592 [var setEnabled:!flag];
593 }
594
595 // update interface
596 [ibCheatVariableTable reloadData];
597 [self setDocumentChanged];
598 [self updateInterface];
599 }
600
601
602 - (IBAction)ibToggleSearchCheat:(id)sender
603 {
604 if ( _mode == TCCheatMode ) {
605 [self switchToSearchMode];
606 }
607 else if ( _mode == TCSearchMode ) {
608 [self switchToCheatMode];
609 }
610 }
611
612
613 - (IBAction)ibUndo:(id)sender
614 {
615 [_cheater undo];
616 }
617
618 - (IBAction)ibRedo:(id)sender
619 {
620 [_cheater redo];
621 }
622
623
624 @end
This page took 0.057035 seconds and 4 git commands to generate.