Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
368 lines (311 sloc) 11.8 KB
/*
* The Cheat - The legendary universal game trainer for Mac OS X.
* http://www.brokenzipper.com/trac/wiki/TheCheat
*
* Copyright (c) 2003-2011, Charles McGarvey et al.
*
* Distributable under the terms and conditions of the 2-clause BSD
* license; see the file COPYING for the legal text of the license.
*/
#import "RemoteCheater.h"
@interface RemoteCheater ( PrivateAPI )
- (void)_handlePacket;
@end
@implementation RemoteCheater
- (void)dealloc
{
[self disconnect];
[super dealloc];
}
- (BOOL)connectToHostWithData:(NSData *)data
{
if ( _socket ) {
[self disconnect];
}
_socket = [[MySocket alloc] initWithDelegate:self];
if ( ![_socket connectToAddressWithData:data] ) {
return NO;
}
// start reading from the socket
[_socket readDataToLength:sizeof(TCPacketHeader) tag:0];
return YES;
}
- (NSString *)hostAddress
{
return [_socket remoteHost];
}
// #############################################################################
#pragma mark Cheater Override
// #############################################################################
- (void)connect
{
NSData *params = [NSArchiver archivedDataWithRootObject:[NSString stringWithFormat:@"%@ %@", ChazAppName(), ChazAppVersion()]];
TCPacketHeader header = { TC_NIFTY, [params length], "connect" };
[_socket writeBytes:&header length:sizeof(header) tag:0];
[_socket writeData:params tag:0];
}
- (void)disconnect
{
[_socket setDelegate:nil];
[_socket release];
_socket = nil;
//[_delegate cheaterDidDisconnect:self];
}
- (void)authenticateWithPassword:(NSString *)password
{
NSData *params = [NSArchiver archivedDataWithRootObject:password];
TCPacketHeader header = { TC_NIFTY, [params length], "authenticate" };
[_socket writeBytes:&header length:sizeof(header) tag:0];
[_socket writeData:params tag:0];
}
- (void)getProcessList
{
TCPacketHeader header = { TC_NIFTY, 0, "getproclist" };
ChazLog( @"SENT getproclist" );
[_socket writeBytes:&header length:sizeof(header) tag:0];
}
- (void)setTarget:(Process *)target
{
NSData *params = [NSArchiver archivedDataWithRootObject:target];
TCPacketHeader header = { TC_NIFTY, [params length], "settarget" };
[_socket writeBytes:&header length:sizeof(header) tag:0];
[_socket writeData:params tag:0];
}
- (void)pauseTarget
{
TCPacketHeader header = { TC_NIFTY, 0, "pausetarget" };
[_socket writeBytes:&header length:sizeof(header) tag:0];
}
- (void)resumeTarget
{
TCPacketHeader header = { TC_NIFTY, 0, "resumetarget" };
[_socket writeBytes:&header length:sizeof(header) tag:0];
}
- (void)limitReturnedResults:(unsigned)limit
{
NSData *params = [NSArchiver archivedDataWithRootObject:[NSNumber numberWithUnsignedInt:limit]];
TCPacketHeader header = { TC_NIFTY, [params length], "limitresults" };
[_socket writeBytes:&header length:sizeof(header) tag:0];
[_socket writeData:params tag:0];
}
- (void)searchForVariable:(Variable *)data comparison:(TCSearchOperator)op
{
NSData *params = [NSArchiver archivedDataWithRootObject:[NSArray arrayWithObjects:data, [NSNumber numberWithUnsignedChar:op], nil]];
TCPacketHeader header = { TC_NIFTY, [params length], "search" };
[_socket writeBytes:&header length:sizeof(header) tag:0];
[_socket writeData:params tag:0];
}
- (void)searchLastValuesComparison:(TCSearchOperator)op
{
NSData *params = [NSArchiver archivedDataWithRootObject:[NSNumber numberWithUnsignedChar:op]];
TCPacketHeader header = { TC_NIFTY, [params length], "lastsearch" };
[_socket writeBytes:&header length:sizeof(header) tag:0];
[_socket writeData:params tag:0];
}
- (void)cancelSearch
{
TCPacketHeader header = { TC_NIFTY, 0, "cancelsearch" };
[_socket writeBytes:&header length:sizeof(header) tag:0];
}
- (void)clearSearch
{
TCPacketHeader header = { TC_NIFTY, 0, "clearsearch" };
[_socket writeBytes:&header length:sizeof(header) tag:0];
}
- (void)getMemoryDump
{
TCPacketHeader header = { TC_NIFTY, 0, "dump" };
[_socket writeBytes:&header length:sizeof(header) tag:0];
}
- (void)cancelMemoryDump
{
TCPacketHeader header = { TC_NIFTY, 0, "canceldump" };
[_socket writeBytes:&header length:sizeof(header) tag:0];
}
- (void)makeVariableChanges:(NSArray *)variables repeat:(BOOL)doRepeat interval:(NSTimeInterval)repeatInterval
{
NSData *params = [NSArchiver archivedDataWithRootObject:[NSArray arrayWithObjects:variables,
[NSNumber numberWithBool:doRepeat], [NSNumber numberWithDouble:repeatInterval], nil]];
TCPacketHeader header = { TC_NIFTY, [params length], "changevars" };
[_socket writeBytes:&header length:sizeof(header) tag:0];
[_socket writeData:params tag:0];
}
- (void)stopChangingVariables
{
TCPacketHeader header = { TC_NIFTY, 0, "stopchange" };
[_socket writeBytes:&header length:sizeof(header) tag:0];
}
- (void)undo
{
TCPacketHeader header = { TC_NIFTY, 0, "undo" };
[_socket writeBytes:&header length:sizeof(header) tag:0];
}
- (void)redo
{
TCPacketHeader header = { TC_NIFTY, 0, "redo" };
[_socket writeBytes:&header length:sizeof(header) tag:0];
}
- (void)watchVariablesAtIndex:(unsigned)index count:(unsigned)count interval:(NSTimeInterval)checkInterval
{
NSData *params = [NSArchiver archivedDataWithRootObject:[NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:index],
[NSNumber numberWithUnsignedInt:count], [NSNumber numberWithDouble:checkInterval], nil]];
TCPacketHeader header = { TC_NIFTY, [params length], "watchvars" };
[_socket writeBytes:&header length:sizeof(header) tag:0];
[_socket writeData:params tag:0];
}
- (void)stopWatchingVariables
{
TCPacketHeader header = { TC_NIFTY, 0, "stopwatching" };
[_socket writeBytes:&header length:sizeof(header) tag:0];
}
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#pragma mark MySocketDelegate
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
- (void)socket:(MySocket *)mySocket didReadData:(NSData *)theData tag:(int)tag
{
if ( tag == 0 && [theData length] == sizeof(TCPacketHeader) ) {
// got a packet header
memcpy( &_header, [theData bytes], sizeof(TCPacketHeader) );
if ( _header.size > 0 ) {
// request the rest of the packet
[mySocket readDataToLength:_header.size tag:1];
}
else {
[self _handlePacket];
// start reading the next packet
[mySocket readDataToLength:sizeof(TCPacketHeader) tag:0];
}
}
else if ( tag == 1 && [theData length] == _header.size ) {
// got packet parameter data
_parameters = [theData retain];
[self _handlePacket];
// start reading the next packet
[mySocket readDataToLength:sizeof(TCPacketHeader) tag:0];
}
else {
ChazLog( @"RemoteCheater - read expected data, disconnecting..." );
[self disconnect];
}
}
- (void)socketDidDisconnect:(MySocket *)mySocket
{
[_socket release];
_socket = nil;
[_delegate cheaterDidDisconnect:self];
}
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#pragma mark PrivateAPI
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
- (void)_handlePacket
{
if ( strncmp( "connected", _header.name, sizeof(_header.name) ) == 0 ) {
ChazLog( @"RemoteCheater - connected" );
[_delegate cheaterDidConnect:self];
}
else if ( strncmp( "requireauth", _header.name, sizeof(_header.name) ) == 0 ) {
[_delegate cheaterRequiresAuthentication:self];
}
else if ( strncmp( "rejectedauth", _header.name, sizeof(_header.name) ) == 0 ) {
[_delegate cheaterRejectedPassword:self];
}
else if ( strncmp( "authenticated", _header.name, sizeof(_header.name) ) == 0 ) {
[_delegate cheaterAcceptedPassword:self];
}
else if ( strncmp( "proclist", _header.name, sizeof(_header.name) ) == 0 ) {
[_delegate cheater:self didFindProcesses:[NSUnarchiver unarchiveObjectWithData:_parameters]];
}
else if ( strncmp( "addprocess", _header.name, sizeof(_header.name) ) == 0 ) {
[_delegate cheater:self didAddProcess:[NSUnarchiver unarchiveObjectWithData:_parameters]];
}
else if ( strncmp( "removeprocess", _header.name, sizeof(_header.name) ) == 0 ) {
[_delegate cheater:self didRemoveProcess:[NSUnarchiver unarchiveObjectWithData:_parameters]];
}
else if ( strncmp( "didsettarget", _header.name, sizeof(_header.name) ) == 0 ) {
[_delegate cheater:self didSetTarget:[NSUnarchiver unarchiveObjectWithData:_parameters]];
}
else if ( strncmp( "didpausetarget", _header.name, sizeof(_header.name) ) == 0 ) {
[_delegate cheaterPausedTarget:self];
}
else if ( strncmp( "didresumetarget", _header.name, sizeof(_header.name) ) == 0 ) {
[_delegate cheaterResumedTarget:self];
}
else if ( strncmp( "vars", _header.name, sizeof(_header.name) ) == 0 ) {
struct varInfo {
unsigned count;
unsigned varCount;
unsigned varSize;
} *varInfo;
void *bytes;
TCArray variables;
varInfo = (struct varInfo *)[_parameters bytes];
bytes = (void *)[_parameters bytes] + sizeof(*varInfo);
variables = TCMakeArrayWithBytes( varInfo->varCount, varInfo->varSize, bytes );
[_delegate cheater:self didFindVariables:variables actualAmount:varInfo->count];
}
else if ( strncmp( "values", _header.name, sizeof(_header.name) ) == 0 ) {
struct varInfo {
unsigned varCount;
unsigned varSize;
} *varInfo;
void *bytes;
TCArray values;
varInfo = (struct varInfo *)[_parameters bytes];
bytes = (void *)[_parameters bytes] + sizeof(*varInfo);
values = TCMakeArrayWithBytes( varInfo->varCount, varInfo->varSize, bytes );
[_delegate cheater:self didFindValues:values];
}
else if ( strncmp( "didcancelsearch", _header.name, sizeof(_header.name) ) == 0 ) {
[_delegate cheaterDidCancelSearch:self];
}
else if ( strncmp( "didclearsearch", _header.name, sizeof(_header.name) ) == 0 ) {
[_delegate cheaterDidClearSearch:self];
}
else if ( strncmp( "memdump", _header.name, sizeof(_header.name) ) == 0 ) {
[_delegate cheater:self didDumpMemory:_parameters];
}
else if ( strncmp( "didcanceldump", _header.name, sizeof(_header.name) ) == 0 ) {
[_delegate cheaterDidCancelMemoryDump:self];
}
else if ( strncmp( "changedvars", _header.name, sizeof(_header.name) ) == 0 ) {
[_delegate cheater:self didChangeVariables:[[NSUnarchiver unarchiveObjectWithData:_parameters] unsignedIntValue]];
}
else if ( strncmp( "didstopchanging", _header.name, sizeof(_header.name) ) == 0 ) {
[_delegate cheaterDidStopChangingVariables:self];
}
else if ( strncmp( "progress", _header.name, sizeof(_header.name) ) == 0 ) {
[_delegate cheater:self didReportProgress:[[NSUnarchiver unarchiveObjectWithData:_parameters] intValue]];
}
else if ( strncmp( "revertedto", _header.name, sizeof(_header.name) ) == 0 ) {
struct varInfo {
unsigned count;
unsigned varCount;
unsigned varSize;
} *varInfo;
void *bytes;
TCArray variables;
varInfo = (struct varInfo *)[_parameters bytes];
bytes = (void *)[_parameters bytes] + sizeof(*varInfo);
variables = TCMakeArrayWithBytes( varInfo->varCount, varInfo->varSize, bytes );
[_delegate cheater:self didRevertToVariables:variables actualAmount:varInfo->count];
}
else if ( strncmp( "didundo", _header.name, sizeof(_header.name) ) == 0 ) {
[_delegate cheaterDidUndo:self];
}
else if ( strncmp( "didredo", _header.name, sizeof(_header.name) ) == 0 ) {
[_delegate cheaterDidRedo:self];
}
else if ( strncmp( "varchanged", _header.name, sizeof(_header.name) ) == 0 ) {
NSArray *params = [NSUnarchiver unarchiveObjectWithData:_parameters];
[_delegate cheater:self variableAtIndex:[[params objectAtIndex:0] unsignedIntValue] didChangeTo:[params objectAtIndex:1]];
}
else if ( strncmp( "failed", _header.name, sizeof(_header.name) ) == 0 ) {
[_delegate cheater:self didFailLastRequest:[NSUnarchiver unarchiveObjectWithData:_parameters]];
}
else if ( strncmp( "echo", _header.name, sizeof(_header.name) ) == 0 ) {
[_delegate cheater:self echo:[NSUnarchiver unarchiveObjectWithData:_parameters]];
}
[_parameters release];
_parameters = nil;
}
@end