3 * The Cheat - The legendary universal game trainer for Mac OS X.
4 * http://www.dogcows.com/chaz/wiki/TheCheat
6 * Copyright (c) 2003-2010, Charles McGarvey et al.
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.
12 #import "RemoteCheater.h"
15 @interface RemoteCheater ( PrivateAPI
)
17 - (void)_handlePacket
;
23 @implementation RemoteCheater
33 - (BOOL)connectToHostWithData
:(NSData
*)data
38 _socket
= [[MySocket alloc
] initWithDelegate
:self];
39 if ( ![_socket connectToAddressWithData
:data
] ) {
43 // start reading from the socket
44 [_socket readDataToLength
:sizeof(TCPacketHeader
) tag
:0];
49 - (NSString
*)hostAddress
51 return [_socket remoteHost
];
55 // #############################################################################
56 #pragma mark Cheater Override
57 // #############################################################################
61 NSData
*params
= [NSArchiver archivedDataWithRootObject
:[NSString stringWithFormat
:@
"%@ %@", ChazAppName(), ChazAppVersion()]];
62 TCPacketHeader header
= { TC_NIFTY
, [params length
], "connect" };
63 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
64 [_socket writeData
:params tag
:0];
69 [_socket setDelegate
:nil];
72 //[_delegate cheaterDidDisconnect:self];
75 - (void)authenticateWithPassword
:(NSString
*)password
77 NSData
*params
= [NSArchiver archivedDataWithRootObject
:password
];
78 TCPacketHeader header
= { TC_NIFTY
, [params length
], "authenticate" };
79 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
80 [_socket writeData
:params tag
:0];
84 - (void)getProcessList
86 TCPacketHeader header
= { TC_NIFTY
, 0, "getproclist" };
87 ChazLog( @
"SENT getproclist" );
88 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
92 - (void)setTarget
:(Process
*)target
94 NSData
*params
= [NSArchiver archivedDataWithRootObject
:target
];
95 TCPacketHeader header
= { TC_NIFTY
, [params length
], "settarget" };
96 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
97 [_socket writeData
:params tag
:0];
102 TCPacketHeader header
= { TC_NIFTY
, 0, "pausetarget" };
103 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
108 TCPacketHeader header
= { TC_NIFTY
, 0, "resumetarget" };
109 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
113 - (void)limitReturnedResults
:(unsigned)limit
115 NSData
*params
= [NSArchiver archivedDataWithRootObject
:[NSNumber numberWithUnsignedInt
:limit
]];
116 TCPacketHeader header
= { TC_NIFTY
, [params length
], "limitresults" };
117 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
118 [_socket writeData
:params tag
:0];
121 - (void)searchForVariable
:(Variable
*)data comparison
:(TCSearchOperator
)op
123 NSData
*params
= [NSArchiver archivedDataWithRootObject
:[NSArray arrayWithObjects
:data
, [NSNumber numberWithUnsignedChar
:op
], nil]];
124 TCPacketHeader header
= { TC_NIFTY
, [params length
], "search" };
125 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
126 [_socket writeData
:params tag
:0];
129 - (void)searchLastValuesComparison
:(TCSearchOperator
)op
131 NSData
*params
= [NSArchiver archivedDataWithRootObject
:[NSNumber numberWithUnsignedChar
:op
]];
132 TCPacketHeader header
= { TC_NIFTY
, [params length
], "lastsearch" };
133 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
134 [_socket writeData
:params tag
:0];
139 TCPacketHeader header
= { TC_NIFTY
, 0, "cancelsearch" };
140 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
145 TCPacketHeader header
= { TC_NIFTY
, 0, "clearsearch" };
146 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
149 - (void)getMemoryDump
151 TCPacketHeader header
= { TC_NIFTY
, 0, "dump" };
152 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
155 - (void)cancelMemoryDump
157 TCPacketHeader header
= { TC_NIFTY
, 0, "canceldump" };
158 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
162 - (void)makeVariableChanges
:(NSArray
*)variables repeat
:(BOOL)doRepeat interval
:(NSTimeInterval
)repeatInterval
164 NSData
*params
= [NSArchiver archivedDataWithRootObject
:[NSArray arrayWithObjects
:variables
,
165 [NSNumber numberWithBool
:doRepeat
], [NSNumber numberWithDouble
:repeatInterval
], nil]];
166 TCPacketHeader header
= { TC_NIFTY
, [params length
], "changevars" };
167 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
168 [_socket writeData
:params tag
:0];
171 - (void)stopChangingVariables
173 TCPacketHeader header
= { TC_NIFTY
, 0, "stopchange" };
174 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
180 TCPacketHeader header
= { TC_NIFTY
, 0, "undo" };
181 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
186 TCPacketHeader header
= { TC_NIFTY
, 0, "redo" };
187 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
191 - (void)watchVariablesAtIndex
:(unsigned)index count
:(unsigned)count interval
:(NSTimeInterval
)checkInterval
193 NSData
*params
= [NSArchiver archivedDataWithRootObject
:[NSArray arrayWithObjects
:[NSNumber numberWithUnsignedInt
:index
],
194 [NSNumber numberWithUnsignedInt
:count
], [NSNumber numberWithDouble
:checkInterval
], nil]];
195 TCPacketHeader header
= { TC_NIFTY
, [params length
], "watchvars" };
196 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
197 [_socket writeData
:params tag
:0];
200 - (void)stopWatchingVariables
202 TCPacketHeader header
= { TC_NIFTY
, 0, "stopwatching" };
203 [_socket writeBytes
:&header length
:sizeof(header
) tag
:0];
207 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
208 #pragma mark MySocketDelegate
209 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
211 - (void)socket
:(MySocket
*)mySocket didReadData
:(NSData
*)theData tag
:(int)tag
213 if ( tag
== 0 && [theData length
] == sizeof(TCPacketHeader
) ) {
214 // got a packet header
215 memcpy( &_header
, [theData bytes
], sizeof(TCPacketHeader
) );
216 if ( _header.size
> 0 ) {
217 // request the rest of the packet
218 [mySocket readDataToLength
:_header.size tag
:1];
221 [self _handlePacket
];
222 // start reading the next packet
223 [mySocket readDataToLength
:sizeof(TCPacketHeader
) tag
:0];
226 else if ( tag
== 1 && [theData length
] == _header.size
) {
227 // got packet parameter data
228 _parameters
= [theData retain
];
229 [self _handlePacket
];
230 // start reading the next packet
231 [mySocket readDataToLength
:sizeof(TCPacketHeader
) tag
:0];
234 ChazLog( @
"RemoteCheater - read expected data, disconnecting..." );
239 - (void)socketDidDisconnect
:(MySocket
*)mySocket
244 [_delegate cheaterDidDisconnect
:self];
248 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
249 #pragma mark PrivateAPI
250 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
252 - (void)_handlePacket
254 if ( strncmp( "connected", _header.name
, sizeof(_header.name
) ) == 0 ) {
255 ChazLog( @
"RemoteCheater - connected" );
256 [_delegate cheaterDidConnect
:self];
258 else if ( strncmp( "requireauth", _header.name
, sizeof(_header.name
) ) == 0 ) {
259 [_delegate cheaterRequiresAuthentication
:self];
261 else if ( strncmp( "rejectedauth", _header.name
, sizeof(_header.name
) ) == 0 ) {
262 [_delegate cheaterRejectedPassword
:self];
264 else if ( strncmp( "authenticated", _header.name
, sizeof(_header.name
) ) == 0 ) {
265 [_delegate cheaterAcceptedPassword
:self];
267 else if ( strncmp( "proclist", _header.name
, sizeof(_header.name
) ) == 0 ) {
268 [_delegate cheater
:self didFindProcesses
:[NSUnarchiver unarchiveObjectWithData
:_parameters
]];
270 else if ( strncmp( "addprocess", _header.name
, sizeof(_header.name
) ) == 0 ) {
271 [_delegate cheater
:self didAddProcess
:[NSUnarchiver unarchiveObjectWithData
:_parameters
]];
273 else if ( strncmp( "removeprocess", _header.name
, sizeof(_header.name
) ) == 0 ) {
274 [_delegate cheater
:self didRemoveProcess
:[NSUnarchiver unarchiveObjectWithData
:_parameters
]];
276 else if ( strncmp( "didsettarget", _header.name
, sizeof(_header.name
) ) == 0 ) {
277 [_delegate cheater
:self didSetTarget
:[NSUnarchiver unarchiveObjectWithData
:_parameters
]];
279 else if ( strncmp( "didpausetarget", _header.name
, sizeof(_header.name
) ) == 0 ) {
280 [_delegate cheaterPausedTarget
:self];
282 else if ( strncmp( "didresumetarget", _header.name
, sizeof(_header.name
) ) == 0 ) {
283 [_delegate cheaterResumedTarget
:self];
285 else if ( strncmp( "vars", _header.name
, sizeof(_header.name
) ) == 0 ) {
293 varInfo
= (struct varInfo
*)[_parameters bytes
];
294 bytes
= (void *)[_parameters bytes
] + sizeof(*varInfo
);
295 variables
= TCMakeArrayWithBytes( varInfo
->varCount
, varInfo
->varSize
, bytes
);
296 [_delegate cheater
:self didFindVariables
:variables actualAmount
:varInfo
->count
];
298 else if ( strncmp( "values", _header.name
, sizeof(_header.name
) ) == 0 ) {
305 varInfo
= (struct varInfo
*)[_parameters bytes
];
306 bytes
= (void *)[_parameters bytes
] + sizeof(*varInfo
);
307 values
= TCMakeArrayWithBytes( varInfo
->varCount
, varInfo
->varSize
, bytes
);
308 [_delegate cheater
:self didFindValues
:values
];
310 else if ( strncmp( "didcancelsearch", _header.name
, sizeof(_header.name
) ) == 0 ) {
311 [_delegate cheaterDidCancelSearch
:self];
313 else if ( strncmp( "didclearsearch", _header.name
, sizeof(_header.name
) ) == 0 ) {
314 [_delegate cheaterDidClearSearch
:self];
316 else if ( strncmp( "memdump", _header.name
, sizeof(_header.name
) ) == 0 ) {
317 [_delegate cheater
:self didDumpMemory
:_parameters
];
319 else if ( strncmp( "didcanceldump", _header.name
, sizeof(_header.name
) ) == 0 ) {
320 [_delegate cheaterDidCancelMemoryDump
:self];
322 else if ( strncmp( "changedvars", _header.name
, sizeof(_header.name
) ) == 0 ) {
323 [_delegate cheater
:self didChangeVariables
:[[NSUnarchiver unarchiveObjectWithData
:_parameters
] unsignedIntValue
]];
325 else if ( strncmp( "didstopchanging", _header.name
, sizeof(_header.name
) ) == 0 ) {
326 [_delegate cheaterDidStopChangingVariables
:self];
328 else if ( strncmp( "progress", _header.name
, sizeof(_header.name
) ) == 0 ) {
329 [_delegate cheater
:self didReportProgress
:[[NSUnarchiver unarchiveObjectWithData
:_parameters
] intValue
]];
331 else if ( strncmp( "revertedto", _header.name
, sizeof(_header.name
) ) == 0 ) {
339 varInfo
= (struct varInfo
*)[_parameters bytes
];
340 bytes
= (void *)[_parameters bytes
] + sizeof(*varInfo
);
341 variables
= TCMakeArrayWithBytes( varInfo
->varCount
, varInfo
->varSize
, bytes
);
342 [_delegate cheater
:self didRevertToVariables
:variables actualAmount
:varInfo
->count
];
344 else if ( strncmp( "didundo", _header.name
, sizeof(_header.name
) ) == 0 ) {
345 [_delegate cheaterDidUndo
:self];
347 else if ( strncmp( "didredo", _header.name
, sizeof(_header.name
) ) == 0 ) {
348 [_delegate cheaterDidRedo
:self];
350 else if ( strncmp( "varchanged", _header.name
, sizeof(_header.name
) ) == 0 ) {
351 NSArray
*params
= [NSUnarchiver unarchiveObjectWithData
:_parameters
];
352 [_delegate cheater
:self variableAtIndex
:[[params objectAtIndex
:0] unsignedIntValue
] didChangeTo
:[params objectAtIndex
:1]];
354 else if ( strncmp( "failed", _header.name
, sizeof(_header.name
) ) == 0 ) {
355 [_delegate cheater
:self didFailLastRequest
:[NSUnarchiver unarchiveObjectWithData
:_parameters
]];
357 else if ( strncmp( "echo", _header.name
, sizeof(_header.name
) ) == 0 ) {
358 [_delegate cheater
:self echo
:[NSUnarchiver unarchiveObjectWithData
:_parameters
]];
361 [_parameters release
];