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