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