Restructured project structure to use a singular SLN; made the T2API common to all projects; adjusted watchdog timer to 8 seconds

This commit is contained in:
Robert MacGregor 2015-06-27 13:36:30 -04:00
parent e1c5d1dead
commit 527474ff24
79 changed files with 469 additions and 626 deletions

View file

@ -0,0 +1,126 @@
/**
* @file DXAPI.cpp
* @brief The DXAPI is an API that allows you to manipulate various game objects
* in Tribes 2 from raw C++ code. It dynamically resolves the addresses of member
* variables as you can't really trust the compiler to produce binary compatible classes,
* especially with all the inheritance involved in the original Tribes 2 codebase.
*
* This code wouldn't be possible without Linker's original gift on the-construct.net forums,
* whose files are appropriately labelled in this codebase. These files have been edited where
* appropriate in order to make that code play better with the DXAPI.
*
* @copyright (c) 2014 Robert MacGregor
*/
#include <DXAPI/Point3F.h>
#include <DXAPI/DXAPI.h>
#include <LinkerAPI.h>
namespace DX
{
const char *GetModPaths(void)
{
int pointer = *(int*)0x9E8690;
pointer = *(int*)(pointer + 2048);
return (const char*)pointer;
}
bool IsFile(const char *filename)
{
typedef bool (*IsFileFuncPtr)(void*, const char *filename, int);
static IsFileFuncPtr IsFileFunc = (IsFileFuncPtr)0x440DF0;
// File Manager Object or something?
void *unknown = *(void**)0x9E8690;
int unknown_int = 0; // Not sure what this is
int result = 0;
__asm
{
push unknown_int;
push filename;
mov ecx, unknown;
lea eax, IsFileFunc;
mov eax, [eax];
call eax;
mov result, eax;
}
return result != 0;
}
bool GetRelativePath(const char *filename, char *ret, int buffer_length)
{
// Make sure T2 can see it first off, we don't want to be loading
// arbitrary files on disk
if (!IsFile(filename))
return false;
const char *modpaths = GetModPaths();
int modpaths_len = strlen(modpaths);
char *modpaths_temp = new char[modpaths_len + 1];
memcpy(modpaths_temp, modpaths, modpaths_len + 1);
// Now we process all the modpaths
int last_start = 0;
for (int iteration = 0; iteration < modpaths_len + 1; iteration++)
if (modpaths_temp[iteration] == ';' || iteration == modpaths_len)
{
memset(ret, 0x00, buffer_length);
modpaths_temp[iteration] = 0x00;
char *modname = &modpaths_temp[last_start];
sprintf_s(ret, buffer_length, "%s/%s", modname, filename);
// Check if it exists
FILE *handle = fopen(ret, "r");
if (handle)
{
fclose(handle);
delete[] modpaths_temp;
return true;
}
last_start = iteration + 1;
}
delete[] modpaths_temp;
return false;
}
bool GetRunningMod(char *ret, int buffer_length)
{
const char *modpaths = GetModPaths();
unsigned int start_point = (unsigned int)modpaths;
unsigned int end_point = (unsigned int)strstr(modpaths, ";");
// FIXME: Potential Buffer overflow
if (end_point == 0)
memcpy(ret, modpaths, strlen(modpaths));
else
memcpy(ret, modpaths, end_point - start_point);
// FIXME: Attackers can use setModPath() to attempt to trick my code into loading files
// outside of Tribes 2's reach
return SanitizeFileName(ret, buffer_length);
}
bool SanitizeFileName(char *ret, int buffer_length)
{
bool was_dirty = false;
for (unsigned int iteration = 0; iteration < strlen(ret); iteration++)
if (ret[iteration] == '.' || ret[iteration] == '\\' || ret[iteration] == '/' || ret[iteration] == '~')
{
was_dirty = true;
ret[iteration] == 0x20; // In the event the occurence is at the very end
for (unsigned int replace_iteration = iteration; replace_iteration < strlen(ret); replace_iteration++)
ret[replace_iteration] = ret[replace_iteration + 1];
}
return was_dirty;
}
}

View file

@ -0,0 +1,8 @@
#include <DXAPI/FlyingVehicle.h>
namespace DX
{
FlyingVehicle::FlyingVehicle(unsigned int obj) : Vehicle(obj)
{
}
}

View file

@ -0,0 +1,10 @@
#include <DXAPI/GameBase.h>
namespace DX
{
GameBase::GameBase(unsigned int obj) : SceneObject(obj)
{
}
} // End NameSpace DX

View file

@ -0,0 +1,34 @@
#include <DXAPI/GameConnection.h>
namespace DX
{
GameConnection::GameConnection(unsigned int obj) : NetConnection(obj)
{
}
ShapeBase GameConnection::getControlObject(void)
{
unsigned int result_ptr = 0;
unsigned int my_ptr = this->base_pointer_value;
__asm
{
mov ecx, my_ptr;
add ecx, 3404928;
test ecx, ecx;
mov edx, ecx;
jz loc_5FDA60_sim;
add edx, 4294967136;
loc_5FDA60_sim:
mov eax, [edx + 33372];
test eax, eax;
jnz got_valid_ptr;
got_valid_ptr:
mov result_ptr, eax;
}
return ShapeBase(result_ptr);
}
} // End NameSpace DX

View file

@ -0,0 +1,8 @@
#include <DXAPI/GrenadeProjectile.h>
namespace DX
{
GrenadeProjectile::GrenadeProjectile(unsigned int obj) : Projectile(obj)
{
}
}

View file

@ -0,0 +1,55 @@
#include <DXAPI/NetConnection.h>
#include <DXAPI/NetObject.h>
#include <LinkerAPI.h>
namespace DX
{
unsigned char NetConnection::getGhostFrom() {
return *(unsigned char *)((this->actualbaseptr)+0x8204);
}
unsigned char NetConnection::getGhostTo() {
return *(unsigned char *)((this->actualbaseptr)+0x8205);
}
S32 NetConnection::getGhostIndex(NetObject obj) {
unsigned int object_ptr = (unsigned int)obj.base_pointer_value;
unsigned int my_ptr = this->base_pointer_value-0xA0;
unsigned int ghostid=0;
unsigned int function=0x584FB0;
__asm
{
mov ecx,my_ptr
mov edx,object_ptr
push edx
call function
mov ghostid, eax
}
return ghostid;
}
NetObject NetConnection::resolveGhostParent(S32 id) {
if (this->getGhostFrom()) {
if (this->mGhostRefs[id].obj)
{
return NetObject((unsigned int)(this->mGhostRefs[id].obj));
}
}
return NULL;
}
NetObject NetConnection::resolveGhost(S32 id) {
if (this->getGhostTo()) {
return NetObject((unsigned int)this->mLocalGhosts[id]);
}
return NULL;
}
NetConnection::NetConnection(unsigned int obj) : SimObject(obj)
{
unsigned int ptr=((this->base_pointer_value)-(0xA0));
this->actualbaseptr=ptr;
unsigned int * ginfoptrptr=0;
ginfoptrptr=(unsigned int *) (this->actualbaseptr+(0x8210));
this->mGhostRefs = (GhostInfo *) *ginfoptrptr;
this->mLocalGhosts = (NetObject **) *(unsigned int *) ((this->actualbaseptr+(0x820C)));
}
}

View file

@ -0,0 +1,9 @@
#include <DXAPI/NetObject.h>
namespace DX
{
NetObject::NetObject(unsigned int obj) : net_flags(*(unsigned int*)(obj + 64)),
SimObject(obj)
{
}
}

View file

@ -0,0 +1,14 @@
#include <DXAPI/Player.h>
namespace DX
{
Player::Player(unsigned int obj) : ShapeBase(obj),
name(0x00), id(*(unsigned int*)(obj + 32)),
is_jetting(*(bool*)(obj + 735)),
is_jumping(*(bool*)(obj + 734)),
is_using_toggledpack(*(bool*)(obj + 1172)),
velocity(*(float*)(obj + 2392), *(float*)(obj + 2396), *(float*)(obj + 2400))
{
}
}

View file

@ -0,0 +1,8 @@
#include <DXAPI/Point3F.h>
namespace DX
{
Point3F::Point3F(float &X, float &Y, float &Z) : x(X), y(Y), z(Z)
{
}
}

View file

@ -0,0 +1,29 @@
#include <DXAPI/Projectile.h>
namespace DX
{
Projectile::Projectile(unsigned int obj) : velocity(*(float*)(obj + 892), *(float*)(obj + 896), *(float*)(obj + 900)),
hidden(*(bool*)(obj + 796)),
GameBase(obj)
{
}
void Projectile::explode(const Linker::Point3F &position, const Linker::Point3F &normal, const unsigned int collideType)
{
void *pointer = (void*)this->base_pointer_value;
typedef void (__cdecl *explodeFunc)(const Linker::Point3F &position, const Linker::Point3F &normal, const unsigned int collideType);
static explodeFunc function_call = (explodeFunc)0x62DC30;
__asm
{
push collideType;
push normal;
push position;
mov ecx,pointer;
lea eax, function_call;
mov eax, [eax];
call eax;
}
}
}

View file

@ -0,0 +1,10 @@
#include <DXAPI/SceneObject.h>
namespace DX
{
SceneObject::SceneObject(unsigned int obj) : position(*(float*)(obj + 168), *(float*)(obj + 184), *(float*)(obj + 200)),
scale(*(float*)(obj + 284), *(float*)(obj + 288), *(float*)(obj + 292)),
NetObject(obj)
{
}
}

View file

@ -0,0 +1,8 @@
#include <DXAPI/ScriptObject.h>
namespace DX
{
ScriptObject::ScriptObject(unsigned int obj) : SimObject(obj)
{
}
}

View file

@ -0,0 +1,21 @@
#include <DXAPI/ShapeBase.h>
#define CloakMask 0x40
namespace DX
{
ShapeBase::ShapeBase(unsigned int obj) : GameBase(obj),
heat_level(*(float*)(obj + 1972)), cloak_level(*(float*)(obj+0x810)), cloaked(*(bool*)(obj+0x80D))
{
}
void ShapeBase::setMaskBits(int value){
unsigned int addr=this->base_pointer_value;
unsigned int bits=value;
unsigned int funcaddr=0x585BE0;
__asm {
mov eax,bits
push eax
mov ecx,addr
mov eax,funcaddr
call eax
};
}
}

View file

@ -0,0 +1,48 @@
#include <cstdarg>
#include <DXAPI/SimObject.h>
#include <LinkerAPI.h>
namespace DX
{
SimObject::SimObject(unsigned int obj) : identifier(*(unsigned int*)(obj + 32)),
base_pointer_value(obj)
{
}
void SimObject::deleteObject(void)
{
void *pointer = (void*)this->base_pointer_value;
typedef void (__cdecl *deleteObjectFunc)(void);
static deleteObjectFunc function_call = (deleteObjectFunc)0x4268D0;
__asm
{
mov ecx, pointer;
lea eax, function_call;
mov eax, [eax];
call eax;
}
}
const char *SimObject::CallMethod(const char *name, unsigned int argc, ...)
{
char **argv = (char**)malloc(sizeof(char*) * (2 + argc));
argv[0]= (char*)name;
argv[1] = "";
va_list vargs;
va_start(vargs, argc);
for (unsigned int iteration = 0; iteration < argc; iteration++)
argv[2 + iteration] = va_arg(vargs, char*);
va_end(vargs);
const char *result = Con::executem((Linker::SimObject*)this->base_pointer_value, 2 + argc, (const char**)argv);
free(argv);
return result;
}
}

View file

@ -0,0 +1,10 @@
#include <DXAPI/StaticShape.h>
namespace DX
{
StaticShape::StaticShape(unsigned int obj) : ShapeBase(obj)
//name(0x00),
//position(*(float*)(obj + 200), *(float*)(obj + 200), *(float*)(obj + 200))
{
}
}

View file

@ -0,0 +1,9 @@
#include <DXAPI/TCPObject.h>
namespace DX
{
TCPObject::TCPObject(unsigned int obj): state(*(unsigned int*)(obj + 56)),
SimObject(obj)
{
}
}

View file

@ -0,0 +1,8 @@
#include <DXAPI/Vehicle.h>
namespace DX
{
Vehicle::Vehicle(unsigned int obj) : ShapeBase(obj)
{
}
}