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