]> Dogcows Code - chaz/thecheat/blob - SessionController.m
The Cheat 1.1.2
[chaz/thecheat] / SessionController.m
1
2 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 // Project: The Cheat
4 //
5 // File: SessionController.m
6 // Created: Sun Sep 07 2003
7 //
8 // Copyright: 2003 Chaz McGarvey. All rights reserved.
9 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10
11 #import "SessionController.h"
12
13 #import "AppController.h"
14
15 #import "CheatClient.h"
16
17
18 // Internal Functions
19 void TCPlaySound( NSString *name );
20
21
22 @implementation SessionController
23
24 - (id)init
25 {
26 if ( self = [super initWithWindowNibName:@"Session"] )
27 {
28 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
29
30 // initialize stuff
31 sockfd = -1;
32 addressList = [[NSMutableArray alloc] init];
33
34 // notifications to receive
35 [nc addObserver:self selector:@selector(listenerStarted:) name:@"TCListenerStarted" object:nil];
36 [nc addObserver:self selector:@selector(listenerStopped:) name:@"TCListenerStopped" object:nil];
37 [nc addObserver:self selector:@selector(windowsOnTopChanged:) name:@"TCWindowsOnTopChanged" object:nil];
38
39 serverList = [(NSArray *)[NSApp serverList] retain];
40
41 // register to recieve notes from the global browser
42 [nc addObserver:self selector:@selector(browserServerFound:) name:@"TCServerFound" object:nil];
43 [nc addObserver:self selector:@selector(browserServerLost:) name:@"TCServerLost" object:nil];
44
45 [self connectToLocal];
46 }
47
48 return self;
49 }
50
51 /*- (NSString *)windowNibName
52 {
53 return @"MyDocument";
54 }
55
56 - (NSString *)displayName
57 {
58 return [NSString stringWithFormat:@"The Cheat %i", TCGlobalDocumentCount++];
59 }
60
61 - (void)windowControllerDidLoadNib:(NSWindowController *)controller
62 {
63 [super windowControllerDidLoadNib:controller];
64
65 [self initialInterfaceSetup];
66 }*/
67
68 - (void)windowDidLoad
69 {
70 [cheatWindow setTitle:[NSString stringWithFormat:@"The Cheat %i", ++TCGlobalSessionCount]];
71
72 [self initialInterfaceSetup];
73 }
74
75 - (void)windowWillClose:(NSNotification *)aNotification
76 {
77 // closing the window will automatically disconnect the client from the server,
78 // but if the application is quitting, the client may not get a chance to exit.
79 // this _should_ be OK.
80 [self disconnect];
81
82 // clean up status timer stuff.
83 // we do this here because we don't want the timer to fire after the window is gone
84 // since we need to use the window in that method.
85 [savedStatusColor release], savedStatusColor = nil;
86 [savedStatusText release], savedStatusText = nil;
87 [statusTextTimer invalidate];
88 [statusTextTimer release], statusTextTimer = nil;
89
90 // we keep track of ourselves so we have to release ourself.
91 [self release];
92 }
93
94
95 - (void)initialInterfaceSetup
96 {
97 NSString *localName = @"Local"; //[NSString stringWithFormat:@"%@ (local)", TCGlobalBroadcastName];
98
99 NSMenuItem *menuItem;
100 int i, top = [serverList count];
101
102 // misc window settings
103 [cheatWindow useOptimizedDrawing:YES];
104 [cheatWindow setFrameAutosaveName:@"TCCheatWindow"];
105
106 // set options
107 if ( TCGlobalWindowsOnTop )
108 {
109 [cheatWindow setLevel:NSPopUpMenuWindowLevel];
110 }
111
112 // set up the server menu default items
113 [serverMenu removeAllItems];
114 [serverMenu addItemWithTitle:@"Not Connected" action:@selector(serverMenuDisconnect:) keyEquivalent:@""];
115 [serverMenu addItemWithTitle:localName action:@selector(serverMenuLocal:) keyEquivalent:@""];
116 [processMenu removeAllItems];
117
118 // update server menu
119 for ( i = 0; i < top; i++ )
120 {
121 menuItem = [[NSMenuItem alloc] initWithTitle:[(NSNetService *)[serverList objectAtIndex:i] name] action:@selector(serverMenuItem:) keyEquivalent:@""];
122
123 [menuItem setTag:i];
124
125 // if this is the first server, add a divider.
126 if ( [serverMenu numberOfItems] <= 2 )
127 {
128 [serverMenu addItem:[NSMenuItem separatorItem]];
129 }
130
131 [serverMenu addItem:[menuItem autorelease]];
132 }
133
134 // give tags to the menu items.
135 [[typeMenu itemWithTitle:@"Integer"] setTag:TYPE_INTEGER];
136 [[typeMenu itemWithTitle:@"String"] setTag:TYPE_STRING];
137 [[typeMenu itemWithTitle:@"Decimal"] setTag:TYPE_DECIMAL];
138 [[typeMenu itemWithTitle:@"Unknown Value"] setTag:TYPE_UNKNOWN];
139 [[stringSizeMenu itemWithTitle:@"8-bit"] setTag:SIZE_8_BIT];
140 [[integerSizeMenu itemWithTitle:@"char"] setTag:SIZE_8_BIT];
141 [[integerSizeMenu itemWithTitle:@"short"] setTag:SIZE_16_BIT];
142 [[integerSizeMenu itemWithTitle:@"long"] setTag:SIZE_32_BIT];
143 [[decimalSizeMenu itemWithTitle:@"float"] setTag:SIZE_32_BIT];
144 [[decimalSizeMenu itemWithTitle:@"double"] setTag:SIZE_64_BIT];
145
146 // set default state
147 [statusText setStringValue:@""];
148 [self setStatusDisconnected];
149
150 // display the initial description text
151 [self updateDescriptionText];
152
153 // change sheet initial interface.
154 [changeSecondsCombo setEnabled:NO];
155 }
156
157 - (void)updateSearchButton
158 {
159 TCtype type = [typePopup indexOfSelectedItem];
160
161 if ( type != TYPE_UNKNOWN )
162 {
163 if ( [[searchTextField stringValue] isEqualToString:@""] )
164 {
165 [searchButton setEnabled:NO];
166 }
167 else
168 {
169 [searchButton setEnabled:YES];
170 }
171 }
172 else
173 {
174 [searchButton setEnabled:YES];
175 }
176 }
177
178 - (void)updatePauseButton
179 {
180 if ( !targetPaused )
181 {
182 [pauseButton setTitle:@"Pause Target"];
183 }
184 else
185 {
186 [pauseButton setTitle:@"Resume Target"];
187 }
188 }
189
190 - (void)updateSearchBoxes
191 {
192 TCtype type = [typePopup indexOfSelectedItem];
193
194 if ( type != TYPE_UNKNOWN )
195 {
196 [searchTextField setEnabled:YES];
197 [searchRadioMatrix setEnabled:NO];
198 }
199 else
200 {
201 [searchTextField setEnabled:NO];
202 [searchRadioMatrix setEnabled:YES];
203 }
204 }
205
206 - (void)updateChangeButton
207 {
208 if ( addressSelected )
209 {
210 [changeButton setEnabled:YES];
211 }
212 else
213 {
214 [changeButton setEnabled:NO];
215 }
216 }
217
218 - (void)updateDescriptionText
219 {
220 TCtype type = [[typePopup selectedItem] tag];
221 TCsize size = [[sizePopup selectedItem] tag];
222
223 switch ( type )
224 {
225 case TYPE_STRING:
226 [descriptionText setStringValue:@"A string is a series of characters.\n\nThis search allows you to find and change words and phrases. Numbers can also be stored as strings, but they aren't recognized as numbers by the computer. Changing strings probably won't change the game in a big way."];
227 break;
228
229 case TYPE_INTEGER:
230 switch ( size )
231 {
232 case SIZE_8_BIT:
233 [descriptionText setStringValue:@"An integer is a non-fraction number.\n\nExamples: 0, 1, 2, 3, 4\nRange: 0 - 255\n\nIntegers usually store variables like score, lives, and remaining ammo."];
234 break;
235
236 case SIZE_16_BIT:
237 [descriptionText setStringValue:@"An integer is a non-fraction number.\n\nExamples: -1, 0, 1, 2, 3\nRange: -32,768 - 32,767\n\nIntegers usually store variables like score, lives, and remaining ammo."];
238 break;
239
240 case SIZE_32_BIT:
241 [descriptionText setStringValue:@"An integer is a non-fraction number.\n\nExamples: -1, 0, 1, 2, 3\nRange: about -2 billion - 2 billion\n\nIntegers usually store variables like score, lives, and remaining ammo. This is the most common size for integer variables."];
242 break;
243 }
244 break;
245
246 case TYPE_DECIMAL:
247 [descriptionText setStringValue:@"A decimal is a fraction number.\n\nFloats and doubles are not often used as variables in games, but there may be other uses for cheating them. Type in as many digits after the decimal place as possible to ensure that your input is matched with the variable you are looking for."];
248 break;
249 }
250 }
251
252
253 - (void)setStatusDisconnected
254 {
255 if ( status == STATUS_DISCONNECTED ) return;
256 lastStatus = status;
257 status = STATUS_DISCONNECTED;
258
259 [serverPopup setEnabled:YES];
260 [pauseButton setTitle:@"Pause Target"];
261 [pauseButton setEnabled:NO];
262 [processPopup setEnabled:NO];
263 [typePopup setEnabled:NO];
264 [sizePopup setEnabled:NO];
265 [searchTextField setEnabled:NO];
266 [searchRadioMatrix setEnabled:NO];
267 [searchButton setEnabled:NO];
268 [clearSearchButton setEnabled:NO];
269 [statusText addStatus:@"Not Connected" duration:CM_STATUS_FOREVER];
270 [statusText setToolTip:@""];
271 [statusBar stopAnimation:self];
272 [addressTable setEnabled:NO];
273 [changeButton setTitle:@"Change..."];
274 [changeButton setEnabled:NO];
275
276 [[serverMenu itemAtIndex:0] setTitle:@"Not Connected"];
277 }
278
279 - (void)setStatusConnected
280 {
281 if ( status == STATUS_CONNECTED ) return;
282 lastStatus = status;
283 status = STATUS_CONNECTED;
284
285 [serverPopup setEnabled:YES];
286 [self updatePauseButton];
287 [pauseButton setEnabled:YES];
288 [processPopup setEnabled:YES];
289 [typePopup setEnabled:YES];
290 [sizePopup setEnabled:YES];
291 [self updateSearchBoxes];
292 [self updateSearchButton];
293 [clearSearchButton setEnabled:NO];
294 [statusText addStatus:@"Connected" duration:CM_STATUS_FOREVER];
295 [statusText setToolTip:@""];
296 [statusBar stopAnimation:self];
297 [addressTable setEnabled:NO];
298 [changeButton setTitle:@"Change..."];
299 [changeButton setEnabled:NO];
300
301 [[serverMenu itemAtIndex:0] setTitle:@"Disconnect"];
302 }
303
304 - (void)setStatusCheating
305 {
306 if ( status == STATUS_CHEATING ) return;
307 lastStatus = status;
308 status = STATUS_CHEATING;
309
310 [serverPopup setEnabled:YES];
311 [self updatePauseButton];
312 [pauseButton setEnabled:YES];
313 [processPopup setEnabled:NO];
314 [typePopup setEnabled:NO];
315 [sizePopup setEnabled:NO];
316 [self updateSearchBoxes];
317 [self updateSearchButton];
318 [clearSearchButton setEnabled:YES];
319 if ( searchResultsAmount <= searchResultsAmountDisplayed )
320 {
321 if ( searchResultsAmount == 1 )
322 {
323 [statusText addStatus:@"One Result" color:[NSColor colorWithCalibratedRed:0.0f green:0.5f blue:0.0f alpha:1.0f] duration:CM_STATUS_FOREVER];
324 }
325 else if ( searchResultsAmount == 0 )
326 {
327 [statusText addStatus:@"No Results" color:[NSColor colorWithCalibratedRed:0.5f green:0.0f blue:0.0f alpha:1.0f] duration:CM_STATUS_FOREVER];
328 }
329 else
330 {
331 [statusText addStatus:[NSString stringWithFormat:@"Results: %i", searchResultsAmount] duration:CM_STATUS_FOREVER];
332 }
333 [statusText setToolTip:@""];
334 }
335 else
336 {
337 [statusText addStatus:[NSString stringWithFormat:@"Results: >%i", searchResultsAmountDisplayed] duration:CM_STATUS_FOREVER];
338 [statusText setToolTip:[NSString stringWithFormat:@"Results: %i", searchResultsAmount]];
339 }
340 [statusBar stopAnimation:self];
341 [addressTable setEnabled:YES];
342 [changeButton setTitle:@"Change..."];
343 [self updateChangeButton];
344
345 [[serverMenu itemAtIndex:0] setTitle:@"Disconnect"];
346 }
347
348 - (void)setStatusSearching
349 {
350 if ( status == STATUS_SEARCHING ) return;
351 lastStatus = status;
352 status = STATUS_SEARCHING;
353
354 [serverPopup setEnabled:NO];
355 [self updatePauseButton];
356 [pauseButton setEnabled:NO];
357 [processPopup setEnabled:NO];
358 [typePopup setEnabled:NO];
359 [sizePopup setEnabled:NO];
360 [searchTextField setEnabled:NO];
361 [searchRadioMatrix setEnabled:NO];
362 [searchButton setEnabled:NO];
363 [clearSearchButton setEnabled:NO];
364 [statusText addStatus:@"Searching..." duration:CM_STATUS_FOREVER];
365 [statusText setToolTip:@""];
366 [statusBar startAnimation:self];
367 [addressTable setEnabled:NO];
368 [changeButton setTitle:@"Change..."];
369 [changeButton setEnabled:NO];
370
371 [[serverMenu itemAtIndex:0] setTitle:@"Disconnect"];
372 }
373
374 - (void)setStatusChanging
375 {
376 if ( status == STATUS_CHANGING ) return;
377 lastStatus = status;
378 status = STATUS_CHANGING;
379
380 if ( lastStatus != STATUS_CHANGING_CONTINUOUSLY )
381 {
382 [serverPopup setEnabled:NO];
383 [self updatePauseButton];
384 [pauseButton setEnabled:NO];
385 [processPopup setEnabled:NO];
386 [typePopup setEnabled:NO];
387 [sizePopup setEnabled:NO];
388 [searchTextField setEnabled:NO];
389 [searchRadioMatrix setEnabled:NO];
390 [searchButton setEnabled:NO];
391 [clearSearchButton setEnabled:NO];
392 [statusBar startAnimation:self];
393 [addressTable setEnabled:NO];
394 [changeButton setEnabled:NO];
395
396 [[serverMenu itemAtIndex:0] setTitle:@"Disconnect"];
397 }
398 }
399
400 - (void)setStatusChangingLater
401 {
402 if ( status == STATUS_CHANGING_LATER ) return;
403 lastStatus = status;
404 status = STATUS_CHANGING_LATER;
405
406 [serverPopup setEnabled:NO];
407 [self updatePauseButton];
408 [pauseButton setEnabled:NO];
409 [processPopup setEnabled:NO];
410 [typePopup setEnabled:NO];
411 [sizePopup setEnabled:NO];
412 [searchTextField setEnabled:NO];
413 [searchRadioMatrix setEnabled:NO];
414 [searchButton setEnabled:NO];
415 [clearSearchButton setEnabled:NO];
416 [statusText addStatus:@"Changing Later..." duration:CM_STATUS_FOREVER];
417 [statusText setToolTip:@""];
418 [statusBar startAnimation:self];
419 [addressTable setEnabled:NO];
420 [changeButton setTitle:@"Cancel Change"];
421 [changeButton setEnabled:YES];
422
423 [[serverMenu itemAtIndex:0] setTitle:@"Disconnect"];
424 }
425
426 - (void)setStatusChangingContinuously
427 {
428 if ( status == STATUS_CHANGING_CONTINUOUSLY ) return;
429 lastStatus = status;
430 status = STATUS_CHANGING_CONTINUOUSLY;
431
432 [serverPopup setEnabled:NO];
433 [self updatePauseButton];
434 [pauseButton setEnabled:YES];
435 [processPopup setEnabled:NO];
436 [typePopup setEnabled:NO];
437 [sizePopup setEnabled:NO];
438 [searchTextField setEnabled:NO];
439 [searchRadioMatrix setEnabled:NO];
440 [searchButton setEnabled:NO];
441 [clearSearchButton setEnabled:NO];
442 [statusText addStatus:@"Repeating Change..." duration:CM_STATUS_FOREVER];
443 [statusText setToolTip:@""];
444 [statusBar startAnimation:self];
445 [addressTable setEnabled:NO];
446 [changeButton setTitle:@"Stop Change"];
447 [changeButton setEnabled:YES];
448
449 [[serverMenu itemAtIndex:0] setTitle:@"Disconnect"];
450 }
451
452 - (void)setStatusUndoing
453 {
454 if ( status == STATUS_UNDOING ) return;
455 lastStatus = status;
456 status = STATUS_UNDOING;
457
458 [serverPopup setEnabled:NO];
459 [self updatePauseButton];
460 [pauseButton setEnabled:NO];
461 [processPopup setEnabled:NO];
462 [typePopup setEnabled:NO];
463 [sizePopup setEnabled:NO];
464 [searchTextField setEnabled:NO];
465 [searchRadioMatrix setEnabled:NO];
466 [searchButton setEnabled:NO];
467 [clearSearchButton setEnabled:NO];
468 [statusText addStatus:@"Undoing..." duration:CM_STATUS_FOREVER];
469 [statusBar startAnimation:self];
470 [addressTable setEnabled:NO];
471 [changeButton setTitle:@"Change..."];
472 [changeButton setEnabled:NO];
473
474 [[serverMenu itemAtIndex:0] setTitle:@"Disconnect"];
475 }
476
477 - (void)setStatusRedoing
478 {
479 if ( status == STATUS_REDOING ) return;
480 lastStatus = status;
481 status = STATUS_REDOING;
482
483 [serverPopup setEnabled:NO];
484 [self updatePauseButton];
485 [pauseButton setEnabled:NO];
486 [processPopup setEnabled:NO];
487 [typePopup setEnabled:NO];
488 [sizePopup setEnabled:NO];
489 [searchTextField setEnabled:NO];
490 [searchRadioMatrix setEnabled:NO];
491 [searchButton setEnabled:NO];
492 [clearSearchButton setEnabled:NO];
493 [statusText addStatus:@"Redoing..." duration:CM_STATUS_FOREVER];
494 [statusText setToolTip:@""];
495 [statusBar startAnimation:self];
496 [addressTable setEnabled:NO];
497 [changeButton setTitle:@"Change..."];
498 [changeButton setEnabled:NO];
499
500 [[serverMenu itemAtIndex:0] setTitle:@"Disconnect"];
501 }
502
503 /*- (void)setStatusToLast
504 {
505 switch ( lastStatus )
506 {
507 case STATUS_DISCONNECTED:
508 [self setStatusDisconnected];
509 break;
510
511 case STATUS_CONNECTED:
512 [self setStatusConnected];
513 break;
514
515 case STATUS_CHEATING:
516 [self setStatusCheating];
517 break;
518
519 case STATUS_SEARCHING:
520 [self setStatusSearching];
521 break;
522
523 case STATUS_CHANGING:
524 [self setStatusChanging];
525 break;
526
527 case STATUS_CHANGING_LATER:
528 [self setStatusChangingLater];
529 break;
530
531 case STATUS_CHANGING_CONTINUOUSLY:
532 [self setStatusChangingContinuously];
533 break;
534
535 case STATUS_UNDOING:
536 [self setStatusUndoing];
537 break;
538
539 case STATUS_REDOING:
540 [self setStatusRedoing];
541 break;
542 }
543 }*/
544
545 /*
546 - (void)setStatusText:(NSString *)msg duration:(NSTimeInterval)seconds
547 {
548 [self setStatusText:msg duration:seconds color:[NSColor blackColor]];
549 }
550
551 - (void)setStatusText:(NSString *)msg duration:(NSTimeInterval)seconds color:(NSColor *)color
552 {
553 if ( statusTextTimer )
554 {
555 [statusTextTimer invalidate];
556 [statusTextTimer release], statusTextTimer = nil;
557 }
558 else
559 {
560 [savedStatusText release];
561 [savedStatusColor release];
562 savedStatusText = [[statusText stringValue] retain];
563 savedStatusColor = [[statusText textColor] retain];
564 }
565
566 [statusText setTextColor:color];
567 [statusText setStringValue:msg];
568
569 if ( seconds != 0.0 )
570 {
571 statusTextTimer = [[NSTimer scheduledTimerWithTimeInterval:seconds target:self selector:@selector(statusTextTimer:) userInfo:nil repeats:NO] retain];
572 }
573 }
574
575 - (void)statusTextTimer:(NSTimer *)timer
576 {
577 [statusText setTextColor:savedStatusColor];
578 [statusText setStringValue:savedStatusText];
579
580 [savedStatusColor release], savedStatusColor = nil;
581 [savedStatusText release], savedStatusText = nil;
582 [statusTextTimer invalidate];
583 [statusTextTimer release], statusTextTimer = nil;
584 }*/
585
586
587 - (void)connectToLocal
588 {
589 NSString *localName = @"Local"; //[NSString stringWithFormat:@"%@ (local)", TCGlobalBroadcastName];
590
591 // depending on how the listener is listening, we need to use different means to connect to local
592 if ( TCGlobalListening )
593 {
594 if ( TCGlobalAllowRemote )
595 {
596 struct sockaddr_in addr;
597
598 addr.sin_family = AF_INET;
599 addr.sin_port = htonl( TCGlobalListenPort );
600 addr.sin_addr.s_addr = INADDR_ANY;
601
602 [self connectToServer:[NSData dataWithBytes:&addr length:sizeof(addr)] name:localName];
603 }
604 else
605 {
606 struct sockaddr_un addr;
607
608 addr.sun_family = AF_UNIX;
609 strncpy( addr.sun_path, TCDefaultListenPath, 103 );
610
611 [self connectToServer:[NSData dataWithBytes:&addr length:sizeof(addr)] name:localName];
612 }
613 }
614 }
615
616 - (void)connectToServer:(NSData *)addr name:(NSString *)name
617 {
618 everConnected = YES;
619
620 if ( connection )
621 {
622 [self disconnect];
623
624 waitingToConnect = YES;
625 connectionAddress = [addr retain];
626 connectionName = [name retain];
627 }
628 else
629 {
630 connection = [[CheatClient clientWithDelegate:self server:addr name:name] retain];
631 connectionAddress = [addr retain];
632 connectionName = [name retain];
633 }
634
635 [self setStatusConnected];
636 }
637
638 - (void)disconnect
639 {
640 if ( connection )
641 {
642 [connection release], connection = nil;
643 close( sockfd );
644
645 [self clearSearch];
646
647 [connectionAddress release], connectionAddress = nil;
648 [connectionName release], connectionName = nil;
649
650 [processMenu removeAllItems];
651
652 [serverPopup selectItemAtIndex:0];
653 [self setStatusDisconnected];
654 }
655 }
656
657
658 - (void)sendProcessListRequest
659 {
660 PacketHeader header;
661 int length = sizeof(header);
662
663 header.checksum = RandomChecksum();
664 header.function = 1;
665 header.size = 0;
666
667 if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
668 {
669 CMLog( @"sendProcessListRequest failed on socket %i", sockfd );
670 }
671 }
672
673 - (void)sendClearSearch
674 {
675 PacketHeader header;
676 int length = sizeof(header);
677
678 header.checksum = RandomChecksum();
679 header.function = 3;
680 header.size = 0;
681
682 if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
683 {
684 CMLog( @"sendClearSearch failed on socket %i", sockfd );
685 }
686 }
687
688 - (void)sendSearch:(char const *)data size:(int)size
689 {
690 PacketHeader header;
691 int length = sizeof(header) + size;
692 int lengthAfter = length;
693
694 char *buffer, *ptr;
695
696 header.checksum = RandomChecksum();
697 header.function = 5;
698 header.size = size;
699
700 if ( (buffer = (char *)malloc( length )) == NULL )
701 {
702 CMLog( @"sendSearch:size: failed" );
703 }
704
705 ptr = buffer;
706
707 COPY_TO_BUFFER( ptr, &header, sizeof(header) );
708 COPY_TO_BUFFER( ptr, data, size );
709
710 if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
711 {
712 CMLog( @"sendSearch:size: failed" );
713 }
714
715 free( buffer );
716 }
717
718 - (void)sendChange:(char const *)data size:(int)size
719 {
720 PacketHeader header;
721 int length = sizeof(header) + size;
722 int lengthAfter = length;
723
724 char *buffer, *ptr;
725
726 header.checksum = RandomChecksum();
727 header.function = 8;
728 header.size = size;
729
730 if ( (buffer = (char *)malloc( length )) == NULL )
731 {
732 CMLog( @"sendChange:size: failed" );
733 }
734
735 ptr = buffer;
736
737 COPY_TO_BUFFER( ptr, &header, sizeof(header) );
738 COPY_TO_BUFFER( ptr, data, size );
739
740 if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
741 {
742 CMLog( @"sendChange:size: failed" );
743 }
744
745 free( buffer );
746 }
747
748 - (void)sendPauseTarget;
749 {
750 PacketHeader header;
751 int length = sizeof(header);
752
753 header.checksum = RandomChecksum();
754 header.function = 10;
755 header.size = 0;
756
757 if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
758 {
759 CMLog( @"sendPauseTarget failed" );
760 }
761 }
762
763 - (void)sendVariableValueRequest
764 {
765
766 }
767
768 - (void)sendUndoRequest
769 {
770 PacketHeader header;
771 int length = sizeof(header);
772
773 header.checksum = RandomChecksum();
774 header.function = 14;
775 header.size = 0;
776
777 if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
778 {
779 CMLog( @"sendUndoRequest failed" );
780 }
781 }
782
783 - (void)sendRedoRequest
784 {
785 PacketHeader header;
786 int length = sizeof(header);
787
788 header.checksum = RandomChecksum();
789 header.function = 16;
790 header.size = 0;
791
792 if ( SendBuffer( sockfd, (char *)(&header), &length ) == -1 || length != sizeof(header) )
793 {
794 CMLog( @"sendRedoRequest failed" );
795 }
796 }
797
798 - (void)sendSetTargetPID:(int)pid
799 {
800 PacketHeader header;
801 int length = sizeof(header) + sizeof(u_int32_t);
802 int lengthAfter = length;
803
804 u_int32_t tarPID = (u_int32_t)pid;
805
806 char *buffer, *ptr;
807
808 header.checksum = RandomChecksum();
809 header.function = 18;
810 header.size = sizeof(u_int32_t);
811
812 if ( (buffer = (char *)malloc( length )) == NULL )
813 {
814 CMLog( @"sendSetTargetPID: failed" );
815 }
816
817 ptr = buffer;
818
819 COPY_TO_BUFFER( ptr, &header, sizeof(header) );
820 COPY_TO_BUFFER( ptr, &tarPID, sizeof(tarPID) );
821
822 if ( SendBuffer( sockfd, buffer, &lengthAfter ) == -1 || lengthAfter != length )
823 {
824 CMLog( @"sendSetTargetPID: failed" );
825 }
826
827 free( buffer );
828 }
829
830
831 - (void)receivedProcessList:(NSData *)data
832 {
833 NSMenuItem *item;
834 u_int32_t processCount = 0;
835
836 char *ptr = (char *)[data bytes];
837 int i, max;
838
839 COPY_FROM_BUFFER( &processCount, ptr, sizeof(processCount) );
840
841 max = (int)processCount;
842
843 for ( i = 0; i < max; i++ )
844 {
845 u_int32_t pid;
846 NSString *name;
847
848 COPY_FROM_BUFFER( &pid, ptr, sizeof(pid) );
849 name = [NSString stringWithCString:ptr], ptr += [name length] + 1;
850
851 item = [[NSMenuItem alloc] initWithTitle:name action:@selector(processMenuItem:) keyEquivalent:@""];
852 [item setTag:(int)pid];
853
854 [processMenu addItem:[item autorelease]];
855 }
856 }
857
858 - (void)receivedSearchFinished
859 {
860 if ( searchResultsAmount == 1 )
861 {
862 TCPlaySound( @"Submarine" );
863 }
864 else if ( searchResultsAmount == 0 )
865 {
866 TCPlaySound( @"Basso" );
867 }
868
869 [self setStatusCheating];
870 //[self setStatusText:@"Search Finished" duration:1.5];
871 [cheatWindow makeFirstResponder:searchTextField];
872 }
873
874 - (void)receivedVariableList:(NSData *)data
875 {
876 char *ptr = (char *)[data bytes];
877
878 [self destroyResults];
879
880 COPY_FROM_BUFFER( &searchResultsAmount, ptr, sizeof(searchResultsAmount) );
881 COPY_FROM_BUFFER( &searchResultsAmountDisplayed, ptr, sizeof(searchResultsAmountDisplayed) );
882
883 if ( searchResultsAmountDisplayed > 0 )
884 {
885 int memSize = TCAddressSize * searchResultsAmountDisplayed;
886 // TCAddressSize*maxSearchResultsAmount;
887
888 if ( (searchResults = (TCaddress *)malloc( memSize )) == NULL )
889 {
890 CMLog( @"receivedVariableList failed: malloc failed" );
891 searchResultsAmount = 0;
892 searchResultsAmountDisplayed = 0;
893 return;
894 }
895 CMLog( @"CLIENT setting display amount to %i", searchResultsAmountDisplayed );
896
897 COPY_FROM_BUFFER( searchResults, ptr, memSize );
898 }
899
900 [addressTable reloadData];
901 }
902
903 - (void)receivedChangeFinished
904 {
905 if ( status != STATUS_CHANGING_CONTINUOUSLY )
906 {
907 TCPlaySound( @"Tink" );
908 [self setStatusCheating];
909 }
910 }
911
912 - (void)receivedError:(NSData *)data
913 {
914 u_int32_t fatal;
915 NSString *msg;
916
917 char *ptr = (char *)[data bytes];
918
919 COPY_FROM_BUFFER( &fatal, ptr, sizeof(fatal) );
920
921 msg = [NSString stringWithCString:ptr];
922
923 // alert the user.
924 [self handleErrorMessage:msg fatal:fatal];
925 }
926
927 - (void)receivedUndoFinished
928 {
929 [self setStatusCheating];
930 }
931
932 - (void)receivedRedoFinished
933 {
934 [self setStatusCheating];
935 }
936
937 - (void)receivedUndoRedoStatus:(NSData *)data
938 {
939 char *ptr = (char *)[data bytes];
940
941 COPY_FROM_BUFFER( &undoCount, ptr, sizeof(undoCount) );
942 COPY_FROM_BUFFER( &redoCount, ptr, sizeof(redoCount) );
943
944 CMLog( @"UNDO: %i, REDO: %i", undoCount, redoCount );
945 }
946
947 - (void)receivedAppLaunched:(NSData *)data
948 {
949 NSMenuItem *item;
950
951 char *ptr = (char *)[data bytes];
952
953 u_int32_t pid;
954 NSString *name;
955
956 COPY_FROM_BUFFER( &pid, ptr, sizeof(pid) );
957 name = [NSString stringWithCString:ptr], ptr += [name length] + 1;
958
959 item = [[NSMenuItem alloc] initWithTitle:name action:@selector(processMenuItem:) keyEquivalent:@""];
960 [item setTag:(int)pid];
961
962 [processMenu addItem:[item autorelease]];
963 }
964
965 - (void)receivedAppQuit:(NSData *)data
966 {
967 u_int32_t pid;
968
969 char *ptr = (char *)[data bytes];
970
971 COPY_FROM_BUFFER( &pid, ptr, sizeof(pid) );
972
973 [processMenu removeItemWithTag:pid];
974 }
975
976 - (void)receivedTargetQuit
977 {
978 [self clearSearch];
979 [self sendClearSearch];
980
981 // tell the server that the first app is now the target.
982 targetPID = [[processMenu itemAtIndex:0] tag];
983 [self sendSetTargetPID:targetPID];
984
985 // alert the user.
986 TCPlaySound( @"Frog" );
987 //[self handleErrorMessage:@"The application that was being cheated has quit." fatal:NO];
988
989 [statusText addStatus:@"Target Quit"];
990 [self setStatusConnected];
991 }
992
993 - (void)receivedPauseFinished:(NSData *)data
994 {
995 char *ptr = (char *)[data bytes];
996
997 COPY_FROM_BUFFER( &targetPaused, ptr, sizeof(targetPaused) );
998
999 [self updatePauseButton];
1000 }
1001
1002
1003 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1004 %%%%%%%%%%%%%%%%%%%%%% Searching & Changing
1005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1006
1007
1008 - (void)search
1009 {
1010 TCtype type = [[typePopup selectedItem] tag];
1011 TCsize size = [[sizePopup selectedItem] tag];
1012
1013 char *data, *ptr;
1014 int dataSize = sizeof(type) + sizeof(size) + sizeof(TCGlobalHitsDisplayed);
1015
1016 data = (char *)malloc( dataSize );
1017 ptr = data;
1018
1019 // copy the size and type of the variable.
1020 COPY_TO_BUFFER( ptr, &type, sizeof(type) );
1021 COPY_TO_BUFFER( ptr, &size, sizeof(size) );
1022
1023 // copy the number of results to return.
1024 COPY_TO_BUFFER( ptr, &TCGlobalHitsDisplayed, sizeof(TCGlobalHitsDisplayed) );
1025
1026 CMLog( @"type: %i, size: %i", type, size );
1027
1028 // switch to cheating mode if this is the first search.
1029 if ( status == STATUS_CONNECTED )
1030 {
1031 [self setStatusCheating];
1032 }
1033
1034 // copy the value to search for.
1035 switch ( type )
1036 {
1037 case TYPE_STRING:
1038 {
1039 switch ( size )
1040 {
1041 case SIZE_8_BIT:
1042 {
1043 NSString *string = [searchTextField stringValue];
1044 int stringLength = [string length] + 1;
1045
1046 data = (char *)realloc( data, dataSize + stringLength );
1047 ptr = data + dataSize;
1048 dataSize += stringLength;
1049
1050 COPY_TO_BUFFER( ptr, [string cString], stringLength );
1051 }
1052 break;
1053 }
1054 }
1055 break;
1056
1057 case TYPE_INTEGER:
1058 {
1059 switch ( size )
1060 {
1061 case SIZE_8_BIT:
1062 {
1063 int8_t value = [searchTextField intValue];
1064
1065 data = (char *)realloc( data, dataSize + sizeof(value) );
1066 ptr = data + dataSize;
1067 dataSize += sizeof(value);
1068
1069 COPY_TO_BUFFER( ptr, &value, sizeof(value) );
1070 }
1071 break;
1072
1073 case SIZE_16_BIT:
1074 {
1075 int16_t value = [searchTextField intValue];
1076
1077 data = (char *)realloc( data, dataSize + sizeof(value) );
1078 ptr = data + dataSize;
1079 dataSize += sizeof(value);
1080
1081 COPY_TO_BUFFER( ptr, &value, sizeof(value) );
1082 }
1083 break;
1084
1085 case SIZE_32_BIT:
1086 {
1087 int32_t value = [searchTextField intValue];
1088
1089 data = (char *)realloc( data, dataSize + sizeof(value) );
1090 ptr = data + dataSize;
1091 dataSize += sizeof(value);
1092
1093 COPY_TO_BUFFER( ptr, &value, sizeof(value) );
1094 }
1095 break;
1096 }
1097 }
1098 break;
1099
1100 case TYPE_DECIMAL:
1101 {
1102 switch ( size )
1103 {
1104 case SIZE_32_BIT:
1105 {
1106 float value = [searchTextField floatValue];
1107
1108 data = (char *)realloc( data, dataSize + sizeof(value) );
1109 ptr = data + dataSize;
1110 dataSize += sizeof(value);
1111
1112 COPY_TO_BUFFER( ptr, &value, sizeof(value) );
1113 }
1114 break;
1115
1116 case SIZE_64_BIT:
1117 {
1118 double value = [searchTextField doubleValue];
1119
1120 data = (char *)realloc( data, dataSize + sizeof(value) );
1121 ptr = data + dataSize;
1122 dataSize += sizeof(value);
1123
1124 COPY_TO_BUFFER( ptr, &value, sizeof(value) );
1125 }
1126 break;
1127 }
1128 }
1129 break;
1130
1131 case TYPE_UNKNOWN:
1132 {
1133 u_int32_t value = 0;//[searchTextField intValue];
1134
1135 data = (char *)realloc( data, dataSize + sizeof(value) );
1136 ptr = data + dataSize;
1137 dataSize += sizeof(value);
1138
1139 COPY_TO_BUFFER( ptr, &value, sizeof(value) );
1140 }
1141 break;
1142 }
1143
1144 [self sendSearch:data size:dataSize];
1145 free( data );
1146
1147 [self setStatusSearching];
1148 }
1149
1150 - (void)change
1151 {
1152 TCtype type = [[typePopup selectedItem] tag];
1153 TCsize size = [[sizePopup selectedItem] tag];
1154
1155 int i, addressCount = [changeSelectedItems count];
1156
1157 char *data, *ptr;
1158 int dataSize = sizeof(type) + sizeof(size) + sizeof(addressCount) + TCAddressSize*addressCount;
1159
1160 data = (char *)malloc( dataSize );
1161 ptr = data;
1162
1163 // copy the size and type of the variable.
1164 COPY_TO_BUFFER( ptr, &type, sizeof(type) );
1165 COPY_TO_BUFFER( ptr, &size, sizeof(size) );
1166
1167 // copy the amount and the list of addresses to change.
1168 COPY_TO_BUFFER( ptr, &addressCount, sizeof(addressCount) );
1169 for ( i = 0; i < addressCount; i++ )
1170 {
1171 COPY_TO_BUFFER( ptr, &((TCaddress *)searchResults)[ [[changeSelectedItems objectAtIndex:i] intValue] ], sizeof(TCaddress) );
1172 }
1173
1174 // copy the new value.
1175 switch ( type )
1176 {
1177 case TYPE_STRING:
1178 {
1179 switch ( size )
1180 {
1181 case SIZE_8_BIT:
1182 {
1183 NSString *string = [changeTextField stringValue];
1184 int stringLength = [string length] + 1;
1185
1186 data = (char *)realloc( data, dataSize + stringLength );
1187 ptr = data + dataSize;
1188 dataSize += stringLength;
1189
1190 COPY_TO_BUFFER( ptr, [string cString], stringLength );
1191 }
1192 break;
1193 }
1194 }
1195 break;
1196
1197 case TYPE_INTEGER:
1198 {
1199 switch ( size )
1200 {
1201 case SIZE_8_BIT:
1202 {
1203 int8_t value = [changeTextField intValue];
1204
1205 data = (char *)realloc( data, dataSize + sizeof(value) );
1206 ptr = data + dataSize;
1207 dataSize += sizeof(value);
1208
1209 COPY_TO_BUFFER( ptr, &value, sizeof(value) );
1210 }
1211 break;
1212
1213 case SIZE_16_BIT:
1214 {
1215 int16_t value = [changeTextField intValue];
1216
1217 data = (char *)realloc( data, dataSize + sizeof(value) );
1218 ptr = data + dataSize;
1219 dataSize += sizeof(value);
1220
1221 COPY_TO_BUFFER( ptr, &value, sizeof(value) );
1222 }
1223 break;
1224
1225 case SIZE_32_BIT:
1226 {
1227 int32_t value = [changeTextField intValue];
1228
1229 data = (char *)realloc( data, dataSize + sizeof(value) );
1230 ptr = data + dataSize;
1231 dataSize += sizeof(value);
1232
1233 COPY_TO_BUFFER( ptr, &value, sizeof(value) );
1234 }
1235 break;
1236 }
1237 }
1238 break;
1239
1240 case TYPE_DECIMAL:
1241 {
1242 switch ( size )
1243 {
1244 case SIZE_32_BIT:
1245 {
1246 float value = [changeTextField floatValue];
1247
1248 data = (char *)realloc( data, dataSize + sizeof(value) );
1249 ptr = data + dataSize;
1250 dataSize += sizeof(value);
1251
1252 COPY_TO_BUFFER( ptr, &value, sizeof(value) );
1253 }
1254 break;
1255
1256 case SIZE_64_BIT:
1257 {
1258 double value = [changeTextField doubleValue];
1259
1260 data = (char *)realloc( data, dataSize + sizeof(value) );
1261 ptr = data + dataSize;
1262 dataSize += sizeof(value);
1263
1264 COPY_TO_BUFFER( ptr, &value, sizeof(value) );
1265 }
1266 break;
1267 }
1268 }
1269 break;
1270
1271 case TYPE_UNKNOWN:
1272 {
1273 u_int32_t value = 0;//[searchTextField intValue];
1274
1275 data = (char *)realloc( data, dataSize + sizeof(value) );
1276 ptr = data + dataSize;
1277 dataSize += sizeof(value);
1278
1279 COPY_TO_BUFFER( ptr, &value, sizeof(value) );
1280 }
1281 break;
1282 }
1283
1284 [self sendChange:data size:dataSize];
1285 free( data );
1286 }
1287
1288
1289 - (void)changeSheet:(NSWindow *)sheet returned:(int)returned context:(void *)context
1290 {
1291 if ( returned == 1 )
1292 {
1293 [changeSelectedItems release], changeSelectedItems = [[[addressTable selectedRowEnumerator] allObjects] retain];
1294
1295 if ( [recurringChangeButton state] == NSOnState )
1296 {
1297 float seconds = [changeSecondsCombo floatValue];
1298
1299 [self setStatusChangingContinuously];
1300
1301 [self change];
1302
1303 changeTimer = [[NSTimer scheduledTimerWithTimeInterval:seconds target:self selector:@selector(changeTimer:) userInfo:nil repeats:YES] retain];
1304 }
1305 else
1306 {
1307 [self change];
1308 }
1309 }
1310 }
1311
1312
1313 - (void)changeTimer:(NSTimer *)timer
1314 {
1315 [self change];
1316 }
1317
1318
1319 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1320 %%%%%%%%%%%%%%%%%%%%%% Cheat Window Interface
1321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1322
1323
1324 - (IBAction)typePopup:(id)sender
1325 {
1326 switch ( [typePopup indexOfSelectedItem] )
1327 {
1328 case TYPE_STRING:
1329 [sizePopup setMenu:stringSizeMenu];
1330 break;
1331
1332 case TYPE_INTEGER:
1333 case TYPE_UNKNOWN:
1334 [sizePopup setMenu:integerSizeMenu];
1335 break;
1336
1337 case TYPE_DECIMAL:
1338 [sizePopup setMenu:decimalSizeMenu];
1339 break;
1340 }
1341
1342 [self updateSearchBoxes];
1343 [self updateSearchButton];
1344 [self updateDescriptionText];
1345 }
1346
1347 - (IBAction)sizePopup:(id)sender
1348 {
1349 [self updateDescriptionText];
1350 }
1351
1352
1353 - (IBAction)searchButton:(id)sender
1354 {
1355 /*if ( [searchTextField intValue] == 0 )
1356 {
1357 if ( NSRunAlertPanel( @"Warning", @"Performing a search with this value will probably take a long time. You should try to search for the variable at a different value.", @"Search Anyway", @"Cancel", nil ) == NSAlertAlternateReturn )
1358 {
1359 return;
1360 }
1361 }*/
1362
1363 [self search];
1364 }
1365
1366 - (IBAction)clearSearchButton:(id)sender
1367 {
1368 [self clearSearch];
1369
1370 [statusText addStatus:@"Search Cleared" duration:1.5];
1371 [self setStatusConnected];
1372
1373 [self sendClearSearch];
1374 }
1375
1376
1377 - (IBAction)changeButton:(id)sender
1378 {
1379 [changeTimer invalidate];
1380 [changeTimer release], changeTimer = nil;
1381
1382 if ( status == STATUS_CHANGING_CONTINUOUSLY )
1383 {
1384 [changeSelectedItems release], changeSelectedItems = nil;
1385
1386 [self setStatusCheating];
1387 }
1388 else if ( status == STATUS_CHEATING )
1389 {
1390 [NSApp beginSheet:changeSheet modalForWindow:cheatWindow modalDelegate:self didEndSelector:@selector(changeSheet:returned:context:) contextInfo:NULL];
1391 //[NSApp runModalForWindow:changeSheet];
1392 //[NSApp endSheet:changeSheet];
1393 //[changeSheet orderOut:self];
1394 }
1395 }
1396
1397
1398 - (IBAction)serverMenuItem:(id)sender
1399 {
1400 NSData *data = [[[serverList objectAtIndex:[sender tag]] addresses] objectAtIndex:0];
1401 /* struct sockaddr_in addr;
1402
1403 [data getBytes:&addr];*/
1404
1405 [self connectToServer:data name:[serverPopup titleOfSelectedItem]];
1406 }
1407
1408 - (IBAction)serverMenuDisconnect:(id)sender
1409 {
1410 [self disconnect];
1411 }
1412
1413 - (IBAction)serverMenuLocal:(id)sender
1414 {
1415 [self connectToLocal];
1416 }
1417
1418 - (IBAction)processMenuItem:(id)sender
1419 {
1420 targetPID = [sender tag];
1421
1422 [self sendSetTargetPID:targetPID];
1423
1424 [statusText addStatus:[NSString stringWithFormat:@"PID: %i", targetPID] duration:CM_STATUS_FOREVER];
1425 }
1426
1427
1428 - (IBAction)pauseButton:(id)sender
1429 {
1430 [self sendPauseTarget];
1431 }
1432
1433
1434 - (void)undoMenu:(id)sender
1435 {
1436 if ( undoCount == 1 )
1437 {
1438 [self clearSearchButton:self];
1439 }
1440 else
1441 {
1442 [self sendUndoRequest];
1443
1444 [self setStatusUndoing];
1445 }
1446 }
1447
1448 - (void)redoMenu:(id)sender
1449 {
1450 [self sendRedoRequest];
1451
1452 [self setStatusRedoing];
1453 }
1454
1455 - (BOOL)respondsToSelector:(SEL)aSelector
1456 {
1457 if ( aSelector == @selector(undoMenu:) )
1458 {
1459 if ( status == STATUS_CHEATING && undoCount > 0 )
1460 {
1461 return YES;
1462 }
1463 else
1464 {
1465 return NO;
1466 }
1467 }
1468
1469 if ( aSelector == @selector(redoMenu:) )
1470 {
1471 if ( status == STATUS_CHEATING && redoCount > 0 )
1472 {
1473 return YES;
1474 }
1475 else
1476 {
1477 return NO;
1478 }
1479 }
1480
1481 return [super respondsToSelector:aSelector];
1482 }
1483
1484
1485 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1486 %%%%%%%%%%%%%%%%%%%%%% Change Sheet Interface
1487 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1488
1489
1490 - (IBAction)cancelButton:(id)sender
1491 {
1492 [changeSheet orderOut:sender];
1493 [NSApp endSheet:changeSheet returnCode:0];
1494 //[NSApp stopModal];
1495 }
1496
1497 - (IBAction)okButton:(id)sender
1498 {
1499 [changeSheet orderOut:sender];
1500 [NSApp endSheet:changeSheet returnCode:1];
1501 if ( [recurringChangeButton state] == NSOnState )
1502 {
1503 [self setStatusChangingContinuously];
1504 }
1505 else
1506 {
1507 [self setStatusChanging];
1508 }
1509 //[NSApp stopModal];
1510 }
1511
1512
1513 - (IBAction)recurringChangeButton:(id)sender
1514 {
1515 if ( [recurringChangeButton state] == NSOnState )
1516 {
1517 [changeSecondsCombo setEnabled:YES];
1518 }
1519 else
1520 {
1521 [changeSecondsCombo setEnabled:NO];
1522 }
1523 }
1524
1525
1526 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1527 %%%%%%%%%%%%%%%%%%%%%% Cleaning Up
1528 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1529
1530
1531 - (void)clearSearch
1532 {
1533 undoCount = 0;
1534 redoCount = 0;
1535
1536 targetPaused = NO;
1537
1538 [changeTimer invalidate];
1539 [changeTimer release], changeTimer = nil;
1540
1541 [self destroyResults];
1542 [addressTable reloadData];
1543 }
1544
1545 - (void)destroyResults
1546 {
1547 if ( searchResultsAmountDisplayed > 0 )
1548 {
1549 free( searchResults );
1550
1551 searchResultsAmount = 0;
1552 searchResultsAmountDisplayed = 0;
1553 }
1554 }
1555
1556
1557 - (void)dealloc
1558 {
1559 [[NSNotificationCenter defaultCenter] removeObserver:self];
1560
1561 [self disconnect];
1562
1563 // clean up status timer stuff
1564 [savedStatusColor release];
1565 [savedStatusText release];
1566 [statusTextTimer invalidate];
1567 [statusTextTimer release];
1568
1569 [changeTimer invalidate];
1570 [changeTimer release];
1571
1572 [self destroyResults];
1573
1574 [changeSelectedItems release];
1575
1576 [serverList release];
1577 [addressList release];
1578
1579 [super dealloc];
1580 }
1581
1582
1583 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1584 %%%%%%%%%%%%%%%%%%%%%% TCListener Notifications
1585 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1586
1587
1588 - (void)listenerStarted:(NSNotification *)note
1589 {
1590 if ( !everConnected )
1591 {
1592 [self connectToLocal];
1593 }
1594 }
1595
1596 - (void)listenerStopped:(NSNotification *)note
1597 {
1598
1599 }
1600
1601
1602 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1603 %%%%%%%%%%%%%%%%%%%%%% TCWindowsOnTopChanged Notification
1604 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1605
1606
1607 - (void)windowsOnTopChanged:(NSNotification *)note
1608 {
1609 if ( [[note object] boolValue] )
1610 {
1611 [cheatWindow setLevel:NSPopUpMenuWindowLevel];
1612 }
1613 else
1614 {
1615 [cheatWindow setLevel:NSNormalWindowLevel];
1616 }
1617 }
1618
1619
1620 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1621 %%%%%%%%%%%%%%%%%%%%%% TCWindowsOnTopChanged Notification
1622 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1623
1624
1625 - (void)handleErrorMessage:(NSString *)msg fatal:(BOOL)fatal
1626 {
1627 CMLog( @"error received" );
1628 // close the change sheet if it's open.
1629 if ( [cheatWindow attachedSheet] )
1630 {
1631 [changeSheet orderOut:self];
1632 [NSApp endSheet:changeSheet returnCode:0];
1633 }
1634
1635 // show message.
1636 NSBeginAlertSheet( fatal? @"Fatal Error":@"Error", @"OK", nil, nil, cheatWindow, nil, nil, nil, 0, msg );
1637 }
1638
1639
1640 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1641 %%%%%%%%%%%%%%%%%%%%%% Cheat Window Delegate
1642 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1643
1644
1645 - (BOOL)windowShouldClose:(id)sender
1646 {
1647 if ( sender == cheatWindow && ( status == STATUS_SEARCHING || status == STATUS_CHANGING ) )
1648 {
1649 NSBeep();
1650 return NO;
1651 }
1652
1653 return YES;
1654 }
1655
1656
1657 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1658 %%%%%%%%%%%%%%%%%%%%%% ClientDelegate
1659 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1660
1661
1662 - (void)clientConnectedWithSocket:(int)sock name:(NSString *)name
1663 {
1664 // the client is reporting that a connection has been made.
1665 sockfd = sock;
1666
1667 [self sendProcessListRequest];
1668
1669 [serverPopup selectItemWithTitle:name];
1670
1671 [self setStatusConnected];
1672 }
1673
1674 - (void)clientDisconnected
1675 {
1676 // if there is a pending connection, connect now.
1677 if ( waitingToConnect )
1678 {
1679 waitingToConnect = NO;
1680 connection = [[CheatClient clientWithDelegate:self server:connectionAddress name:connectionName] retain];
1681 }
1682 // if our connection variable is still valid, we were disconnected unexpectedly.
1683 else if ( connection )
1684 {
1685 [self disconnect];
1686 NSBeginAlertSheet( @"Network Failure", @"OK", nil, nil, cheatWindow, nil, nil, nil, 0, @"The server has disconnected you." );
1687 }
1688 }
1689
1690 - (void)clientError:(NSString *)error message:(NSString *)message
1691 {
1692 NSBeginAlertSheet( error, @"OK", nil, nil, cheatWindow, nil, nil, nil, 0, message );
1693 }
1694
1695
1696 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1697 %%%%%%%%%%%%%%%%%%%%%% NSToolbar Delegate
1698 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1699
1700 /*
1701 *** A toolbar is no longer used, but the code still remains for possible future use. ***
1702
1703 - (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag
1704 {
1705 NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
1706
1707 if ( [itemIdentifier isEqualToString:@"Disconnect"] )
1708 {
1709 disconnectButton = item;
1710
1711 [item setLabel:@"Disconnect"];
1712 [item setPaletteLabel:[item label]];
1713 [item setImage:[NSImage imageNamed:@"disconnect"]];
1714 [item setTarget:self];
1715 [item setToolTip:@"Click here to pause or unpause the program being cheated."];
1716 }
1717 else if ( [itemIdentifier isEqualToString:@"ServerPopup"] )
1718 {
1719 NSRect fRect = [typePopup frame];
1720 NSSize fSize = NSMakeSize( FLT_MAX, fRect.size.height );
1721 NSMenuItem *menu = [[NSMenuItem alloc] initWithTitle:@"Server" action:@selector(serverPopup:) keyEquivalent:@""];
1722
1723 [menu setSubmenu:[serverPopup menu]];
1724
1725 [item setLabel:@"Server"];
1726 [item setPaletteLabel:[item label]];
1727 [item setView:serverPopup];
1728 [item setMinSize:fRect.size];
1729 [item setMaxSize:fSize];
1730 [item setMenuFormRepresentation:[menu autorelease]];
1731 [item autorelease];
1732 }
1733
1734 return item;
1735 }
1736
1737 - (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar
1738 {
1739 return [NSArray arrayWithObjects:NSToolbarSeparatorItemIdentifier,
1740 NSToolbarSpaceItemIdentifier,
1741 NSToolbarFlexibleSpaceItemIdentifier,
1742 NSToolbarCustomizeToolbarItemIdentifier,
1743 @"Disconnect", @"ServerPopup", nil];
1744 }
1745
1746 - (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar
1747 {
1748 return [NSArray arrayWithObjects:@"Disconnect", @"ServerPopup", nil];
1749 }*/
1750
1751
1752 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1753 %%%%%%%%%%%%%%%%%%%%%% NSTableView Data Source/Delegate
1754 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1755
1756
1757 - (void)controlTextDidChange:(NSNotification *)aNotification
1758 {
1759 [self updateSearchButton];
1760 }
1761
1762
1763 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1764 %%%%%%%%%%%%%%%%%%%%%% NSTableView Data Source/Delegate
1765 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1766
1767
1768 - (int)numberOfRowsInTableView:(NSTableView *)table
1769 {
1770 return searchResultsAmountDisplayed;
1771 }
1772
1773 - (id)tableView:(NSTableView *)table objectValueForTableColumn:(NSTableColumn *)column row:(int)row
1774 {
1775 return [NSString stringWithFormat:@"%0.8X", ((TCaddress *)searchResults)[row]];
1776 }
1777
1778 - (void)tableView:(NSTableView *) setObjectValue:(id)object forTableColumn:(NSTableColumn *)column row:(int)row
1779 {
1780 return;
1781 }
1782
1783 - (void)tableViewSelectionDidChange:(NSNotification *)note
1784 {
1785 if ( [addressTable selectedRow] != -1 )
1786 {
1787 addressSelected = YES;
1788 }
1789 else
1790 {
1791 addressSelected = NO;
1792 }
1793
1794 [self updateChangeButton];
1795 }
1796
1797
1798 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1799 %%%%%%%%%%%%%%%%%%%%%% Global Browser Notifications
1800 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1801
1802
1803 - (void)browserServerFound:(NSNotification *)note
1804 {
1805 NSNetService *service = (NSNetService *)[note object];
1806
1807 NSString *name = [service name];
1808 int tag = [serverList count] - 1;
1809 NSMenuItem *item;
1810
1811 CMLog( @"server found" );
1812
1813 if ( [serverMenu itemWithTitle:name] == nil )
1814 {
1815 item = [[NSMenuItem alloc] initWithTitle:[service name] action:@selector(serverMenuItem:) keyEquivalent:@""];
1816
1817 [item setTag:tag];
1818
1819 // if this is the first server, add a divider.
1820 if ( [serverMenu numberOfItems] <= 2 )
1821 {
1822 [serverMenu addItem:[NSMenuItem separatorItem]];
1823 }
1824
1825 //[serverList addObject:service];
1826 [serverMenu addItem:[item autorelease]];
1827
1828 // select the item if we are already connected to the server.
1829 // this could happen if the server rebroadcast as a different name.
1830 if ( connection && [[[service addresses] objectAtIndex:0] isEqualToData:connectionAddress] )
1831 {
1832 [serverPopup selectItemWithTitle:[service name]];
1833 }
1834 }
1835 }
1836
1837 - (void)browserServerLost:(NSNotification *)note
1838 {
1839 NSNetService *service = (NSNetService *)[note object];
1840 NSString *name = [service name];
1841
1842 int i, top = [serverMenu numberOfItems];
1843
1844 for ( i = [serverMenu indexOfItemWithTitle:name] + 1; i < top; i++ )
1845 {
1846 [[serverMenu itemWithTitle:name] setTag:[[serverMenu itemWithTitle:name] tag] - 1];
1847 }
1848
1849 [serverMenu removeAllItemsWithTitle:name];
1850
1851 // if this is the last broadcast server, take away the divider.
1852 if ( [serverMenu numberOfItems] == 3 )
1853 {
1854 [serverMenu removeItemAtIndex:2];
1855 }
1856 }
1857
1858
1859 @end
1860
1861
1862 // Internal Functions
1863 void TCPlaySound( NSString *name )
1864 {
1865 if ( TCGlobalPlaySounds )
1866 {
1867 [[NSSound soundNamed:name] play];
1868 }
1869 }
This page took 0.121344 seconds and 4 git commands to generate.