mirror of
https://github.com/Ragora/T2-CPP.git
synced 2026-02-13 03:33:38 +00:00
Experimental TCPObject coding; registered in TS as alt*
This commit is contained in:
parent
3fd5187fd9
commit
fa724913e3
24 changed files with 587 additions and 115 deletions
|
|
@ -27,17 +27,12 @@
|
|||
#include <DXAPI/StaticShape.h>
|
||||
#include <DXAPI/GrenadeProjectile.h>
|
||||
#include <DXAPI/FlyingVehicle.h>
|
||||
#include <DXAPI/GameConnection.h>
|
||||
#include <DXAPI/NetConnection.h>
|
||||
#include <DXAPI/TCPObject.h>
|
||||
|
||||
namespace DX
|
||||
{
|
||||
//! A typedef referring to some type of unresolved object in the game.
|
||||
typedef void* UnresolvedObject;
|
||||
|
||||
//! Structure representing a static shape in the game.
|
||||
//typedef struct
|
||||
//{
|
||||
|
||||
// } StaticShape;
|
||||
|
||||
void Projectile_explode(Projectile *obj, const Point3F &position, const Point3F &normal, const unsigned int collideType);
|
||||
} // End NameSpace DX
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include <DXAPI/Point3F.h>
|
||||
#include <DXAPI/NetConnection.h>
|
||||
|
||||
#include <DXAPI/ShapeBase.h>
|
||||
|
||||
namespace DX
|
||||
{
|
||||
class GameConnection : public NetConnection
|
||||
{
|
||||
public:
|
||||
GameConnection(unsigned int obj);
|
||||
|
||||
ShapeBase getControlObject(void);
|
||||
};
|
||||
} // End NameSpace DX
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <DXAPI/Point3F.h>
|
||||
#include <DXAPI/SimObject.h>
|
||||
|
||||
namespace DX
|
||||
{
|
||||
class NetConnection : public SimObject
|
||||
{
|
||||
public:
|
||||
NetConnection(unsigned int obj);
|
||||
};
|
||||
} // End NameSpace DX
|
||||
|
|
@ -4,9 +4,19 @@
|
|||
|
||||
namespace DX
|
||||
{
|
||||
enum NetFlags
|
||||
{
|
||||
IsGhost = 1,
|
||||
ScopeAlways = 1 << 6,
|
||||
ScopeLocal = 1 << 7,
|
||||
Ghostable = 1 << 8
|
||||
};
|
||||
|
||||
class NetObject : public SimObject
|
||||
{
|
||||
public:
|
||||
NetObject(unsigned int obj);
|
||||
|
||||
unsigned int &net_flags;
|
||||
};
|
||||
} // End NameSpace DX
|
||||
|
|
|
|||
|
|
@ -22,5 +22,8 @@ namespace DX
|
|||
const bool &is_jumping;
|
||||
//! Player Object Using Toggable Pack
|
||||
bool &is_using_toggledpack;
|
||||
|
||||
//! Player Velocity.
|
||||
Point3F velocity;
|
||||
};
|
||||
} // End NameSpace DX
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <DXAPI/Point3F.h>
|
||||
#include <DXAPI/GameBase.h>
|
||||
|
||||
#include <LinkerAPI.h>
|
||||
|
||||
namespace DX
|
||||
{
|
||||
class Projectile : public GameBase
|
||||
|
|
@ -9,6 +12,8 @@ namespace DX
|
|||
public:
|
||||
Projectile(unsigned int obj);
|
||||
|
||||
void explode(const Linker::Point3F &position, const Linker::Point3F &normal, const unsigned int collideType);
|
||||
|
||||
//! Velocity. It is constant because modifying it directly breaks the sim.
|
||||
const Point3F velocity;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,5 +8,8 @@ namespace DX
|
|||
{
|
||||
public:
|
||||
ShapeBase(unsigned int obj);
|
||||
|
||||
//! Heat Level
|
||||
float &heat_level;
|
||||
};
|
||||
} // End NameSpace DX
|
||||
|
|
@ -8,8 +8,9 @@ namespace DX
|
|||
SimObject(unsigned int obj);
|
||||
|
||||
void deleteObject(void);
|
||||
const char *TSCall(const char *name, unsigned int argc, ...);
|
||||
|
||||
protected:
|
||||
const unsigned int &identifier;
|
||||
const unsigned int base_pointer_value;
|
||||
};
|
||||
} // End NameSpace DX
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include <DXAPI/SimObject.h>
|
||||
|
||||
namespace DX
|
||||
{
|
||||
class TCPObject : public SimObject
|
||||
{
|
||||
public:
|
||||
TCPObject(unsigned int obj);
|
||||
|
||||
unsigned int &state;
|
||||
};
|
||||
} // End NameSpace DX
|
||||
|
|
@ -15,19 +15,27 @@
|
|||
#include <LinkerAPI.h>
|
||||
|
||||
// Returns the address of an object in memory
|
||||
const char* conGetAddress(SimObject *obj, S32 argc, const char *argv[]);
|
||||
const char* conGetAddress(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||
|
||||
// Player Commands -----------------------------------
|
||||
bool conPlayerGetJumpingState(SimObject *obj, S32 argc, const char* argv[]);
|
||||
bool conPlayerGetJettingState(SimObject *obj, S32 argc, const char* argv[]);
|
||||
bool conPlayerGetJumpingState(Linker::SimObject *obj, S32 argc, const char* argv[]);
|
||||
bool conPlayerGetJettingState(Linker::SimObject *obj, S32 argc, const char* argv[]);
|
||||
|
||||
bool conGameConnectionSetHeatLevel(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||
|
||||
// GrenadeProjectile Commands ------------------------
|
||||
const char* conGrenadeProjectileGetPosition(SimObject *obj, S32 argc, const char* argv[]);
|
||||
const char* conGrenadeProjectileGetVelocity(SimObject *obj, S32 argc, const char* argv[]);
|
||||
const char* conGrenadeProjectileGetPosition(Linker::SimObject *obj, S32 argc, const char* argv[]);
|
||||
const char* conGrenadeProjectileGetVelocity(Linker::SimObject *obj, S32 argc, const char* argv[]);
|
||||
|
||||
// Projectile explode -------------------------------
|
||||
bool conProjectileExplode(SimObject *obj, S32 argc, const char* argv[]);
|
||||
bool conProjectileMakeNerf(SimObject *obj, S32 argc, const char* argv[]);
|
||||
bool conProjectileExplode(Linker::SimObject *obj, S32 argc, const char* argv[]);
|
||||
bool conProjectileMakeNerf(Linker::SimObject *obj, S32 argc, const char* argv[]);
|
||||
|
||||
// TCPObject Commands -------------------------------
|
||||
const char* conTCPObjectConnect(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||
bool conTCPObjectSend(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||
bool conTCPObjectDisconnect(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||
|
||||
// General Commands ---------------------------------
|
||||
const char* conSprintf(SimObject *obj, S32 argc, const char* argv[]);
|
||||
const char* conSprintf(Linker::SimObject *obj, S32 argc, const char* argv[]);
|
||||
bool conTSExtensionUpdate(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||
|
|
@ -22,74 +22,76 @@ inline dsize_t dStrlen(const char *str)
|
|||
return (dsize_t)strlen(str);
|
||||
}
|
||||
|
||||
class Namespace
|
||||
{
|
||||
const char* mName;
|
||||
};
|
||||
//class Namespace
|
||||
//{
|
||||
// const char* mName;
|
||||
//};
|
||||
|
||||
struct SimObject
|
||||
{
|
||||
SimObject* group;
|
||||
const char* objectName; //04h: objectName
|
||||
SimObject* nextNameObject; //8
|
||||
SimObject* nextManagerNameObject; //c
|
||||
SimObject* nextIdObject; //10h: nextIdObject
|
||||
U32 stuff; //14
|
||||
U32 mFlags; //18h
|
||||
U32 mNotifyList; //actually a pointer
|
||||
U32 mId; //20h: mId
|
||||
//more stuff
|
||||
};
|
||||
//class SimIdDictionary
|
||||
//{
|
||||
//enum
|
||||
//{
|
||||
// DefaultTableSize = 4096,
|
||||
// TableBitMask = 4095
|
||||
// };
|
||||
// Linker::SimObject *table[DefaultTableSize];
|
||||
//};
|
||||
//extern SimIdDictionary* gIdDictionary;
|
||||
|
||||
class SimIdDictionary
|
||||
namespace Linker
|
||||
{
|
||||
enum
|
||||
{
|
||||
DefaultTableSize = 4096,
|
||||
TableBitMask = 4095
|
||||
};
|
||||
SimObject *table[DefaultTableSize];
|
||||
};
|
||||
extern SimIdDictionary* gIdDictionary;
|
||||
|
||||
class Point3F
|
||||
{
|
||||
public:
|
||||
Point3F(F32 *x, F32 *y, F32 *z)
|
||||
class Point3F
|
||||
{
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->z = z;
|
||||
}
|
||||
public:
|
||||
Point3F(F32 *x, F32 *y, F32 *z)
|
||||
{
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->z = z;
|
||||
}
|
||||
|
||||
Point3F(void)
|
||||
Point3F(void)
|
||||
{
|
||||
this->x = 0;
|
||||
this->y = 0;
|
||||
this->z = 0;
|
||||
}
|
||||
|
||||
F32 *x;
|
||||
F32 *y;
|
||||
F32 *z;
|
||||
};
|
||||
|
||||
struct SimObject
|
||||
{
|
||||
this->x = 0;
|
||||
this->y = 0;
|
||||
this->z = 0;
|
||||
}
|
||||
|
||||
F32 *x;
|
||||
F32 *y;
|
||||
F32 *z;
|
||||
};
|
||||
|
||||
SimObject* group;
|
||||
const char* objectName; //04h: objectName
|
||||
SimObject* nextNameObject; //8
|
||||
SimObject* nextManagerNameObject; //c
|
||||
SimObject* nextIdObject; //10h: nextIdObject
|
||||
U32 stuff; //14
|
||||
U32 mFlags; //18h
|
||||
U32 mNotifyList; //actually a pointer
|
||||
U32 mId; //20h: mId
|
||||
//more stuff
|
||||
};
|
||||
}
|
||||
|
||||
//GuiTSCtrl
|
||||
class GuiTSCtrl {};
|
||||
void GuiTSCtrl_project(GuiTSCtrl *obj, const Point3F &pt, Point3F *dest); //fake
|
||||
void GuiTSCtrl_project(GuiTSCtrl *obj, const Linker::Point3F &pt, Linker::Point3F *dest); //fake
|
||||
|
||||
namespace Sim {
|
||||
extern SimObject* (*findObject)(U32 id);
|
||||
extern Linker::SimObject* (*findObject)(U32 id);
|
||||
}
|
||||
|
||||
//console
|
||||
|
||||
typedef const char * (*StringCallback)(SimObject *obj, S32 argc, const char *argv[]);
|
||||
typedef S32 (*IntCallback)(SimObject *obj, S32 argc, const char *argv[]);
|
||||
typedef F32 (*FloatCallback)(SimObject *obj, S32 argc, const char *argv[]);
|
||||
typedef void (*VoidCallback)(SimObject *obj, S32 argc, const char *argv[]);
|
||||
typedef bool (*BoolCallback)(SimObject *obj, S32 argc, const char *argv[]);
|
||||
typedef const char * (*StringCallback)(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||
typedef S32 (*IntCallback)(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||
typedef F32 (*FloatCallback)(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||
typedef void (*VoidCallback)(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||
typedef bool (*BoolCallback)(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||
|
||||
|
||||
//functions
|
||||
|
|
@ -109,7 +111,7 @@ extern void (*errorf)(U32 type, const char* fmt,...);
|
|||
extern const char * (*getVariable)(const char *name);
|
||||
extern const char * (*execute)(S32 argc, const char *argv[]);
|
||||
extern const char * (*executef)(S32 argc, ...);
|
||||
extern const char * (*executem)(SimObject *object, S32 argc, const char *argv[]);
|
||||
extern const char * (*executem)(Linker::SimObject *object, S32 argc, const char *argv[]);
|
||||
extern const char * (*evaluate)(const char* string, bool echo, const char *fileName, bool cf);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,20 +19,5 @@
|
|||
|
||||
namespace DX
|
||||
{
|
||||
void Projectile_explode(Projectile *obj, const Point3F &position, const Point3F &normal, const unsigned int collideType)
|
||||
{
|
||||
typedef void (__cdecl *explodeFunc)(const Point3F &position, const Point3F &normal, const unsigned int collideType);
|
||||
static explodeFunc function_call = (explodeFunc)0x62DC30;
|
||||
|
||||
__asm
|
||||
{
|
||||
push collideType;
|
||||
push normal;
|
||||
push position;
|
||||
mov ecx,obj;
|
||||
lea eax, function_call;
|
||||
mov eax, [eax];
|
||||
call eax;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#include <DXAPI/NetConnection.h>
|
||||
|
||||
namespace DX
|
||||
{
|
||||
NetConnection::NetConnection(unsigned int obj) : SimObject(obj)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
namespace DX
|
||||
{
|
||||
NetObject::NetObject(unsigned int obj) : SimObject(obj)
|
||||
NetObject::NetObject(unsigned int obj) : net_flags(*(unsigned int*)(obj + 64)),
|
||||
SimObject(obj)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,8 @@ namespace DX
|
|||
name(0x00), id(*(unsigned int*)(obj + 32)),
|
||||
is_jetting(*(bool*)(obj + 735)),
|
||||
is_jumping(*(bool*)(obj + 734)),
|
||||
is_using_toggledpack(*(bool*)(obj + 1172))
|
||||
is_using_toggledpack(*(bool*)(obj + 1172)),
|
||||
velocity(*(float*)(obj + 2392), *(float*)(obj + 2396), *(float*)(obj + 2400))
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,23 @@ namespace DX
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
namespace DX
|
||||
{
|
||||
ShapeBase::ShapeBase(unsigned int obj) : GameBase(obj)
|
||||
ShapeBase::ShapeBase(unsigned int obj) : GameBase(obj),
|
||||
heat_level(*(float*)(obj + 1972))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,13 @@
|
|||
#include <cstdarg>
|
||||
|
||||
#include <DXAPI/SimObject.h>
|
||||
|
||||
#include <LinkerAPI.h>
|
||||
|
||||
namespace DX
|
||||
{
|
||||
SimObject::SimObject(unsigned int obj) : base_pointer_value(obj)
|
||||
SimObject::SimObject(unsigned int obj) : identifier(*(unsigned int*)(obj + 32)),
|
||||
base_pointer_value(obj)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -11,7 +16,7 @@ namespace DX
|
|||
void *pointer = (void*)this->base_pointer_value;
|
||||
|
||||
typedef void (__cdecl *deleteObjectFunc)(void);
|
||||
static deleteObjectFunc function_call = (deleteObjectFunc)0x439DE0;
|
||||
static deleteObjectFunc function_call = (deleteObjectFunc)0x4268D0;
|
||||
|
||||
__asm
|
||||
{
|
||||
|
|
@ -21,4 +26,23 @@ namespace DX
|
|||
call eax;
|
||||
}
|
||||
}
|
||||
|
||||
const char *SimObject::TSCall(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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#include <DXAPI/TCPObject.h>
|
||||
|
||||
namespace DX
|
||||
{
|
||||
TCPObject::TCPObject(unsigned int obj): state(*(unsigned int*)(obj + 56)),
|
||||
SimObject(obj)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
#include <LinkerAPI.h>
|
||||
#include <DXAPI/DXAPI.h>
|
||||
|
||||
const char *conGetAddress(SimObject *obj, S32 argc, const char *argv[])
|
||||
const char *conGetAddress(Linker::SimObject *obj, S32 argc, const char *argv[])
|
||||
{
|
||||
// Hmm...
|
||||
char result[256];
|
||||
|
|
@ -13,39 +13,42 @@ const char *conGetAddress(SimObject *obj, S32 argc, const char *argv[])
|
|||
return result;
|
||||
}
|
||||
|
||||
bool conPlayerGetJumpingState(SimObject *obj, S32 argc, const char* argv[])
|
||||
bool conPlayerGetJumpingState(Linker::SimObject *obj, S32 argc, const char* argv[])
|
||||
{
|
||||
DX::Player operand = DX::Player((unsigned int)obj);
|
||||
|
||||
return operand.is_jumping;
|
||||
}
|
||||
|
||||
bool conPlayerGetJettingState(SimObject *obj, S32 argc, const char* argv[])
|
||||
bool conPlayerGetJettingState(Linker::SimObject *obj, S32 argc, const char* argv[])
|
||||
{
|
||||
DX::Player operand = DX::Player((unsigned int)obj);
|
||||
|
||||
return operand.is_jetting;
|
||||
}
|
||||
|
||||
bool conProjectileExplode(SimObject *obj, S32 argc, const char* argv[])
|
||||
bool conGameConnectionSetHeatLevel(Linker::SimObject *obj, S32 argc, const char *argv[])
|
||||
{
|
||||
Point3F position;
|
||||
position.x = 0;
|
||||
position.y = 0;
|
||||
position.z = 0;
|
||||
DX::GameConnection operand = DX::GameConnection((unsigned int)obj);
|
||||
operand.getControlObject().heat_level = atof(argv[1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
Point3F normal;
|
||||
normal.x = 0;
|
||||
normal.y = 0;
|
||||
normal.z = 0;
|
||||
bool conProjectileExplode(Linker::SimObject *obj, S32 argc, const char* argv[])
|
||||
{
|
||||
Linker::Point3F position(0,0,0);
|
||||
Linker::Point3F normal(0,0,0);
|
||||
|
||||
unsigned int collideType = atoi(argv[4]);
|
||||
//DX::Projectile_explode((DX::Projectile*)obj, position, normal, collideType);
|
||||
DX::Projectile projectile((unsigned int)obj);
|
||||
|
||||
projectile.net_flags |= DX::NetFlags::ScopeAlways;
|
||||
projectile.explode(position, normal, collideType);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool conProjectileMakeNerf(SimObject *obj, S32 argc, const char* argv[])
|
||||
bool conProjectileMakeNerf(Linker::SimObject *obj, S32 argc, const char* argv[])
|
||||
{
|
||||
DX::GrenadeProjectile grenade = DX::GrenadeProjectile((unsigned int)obj);
|
||||
grenade.hidden = true;
|
||||
|
|
@ -53,7 +56,7 @@ bool conProjectileMakeNerf(SimObject *obj, S32 argc, const char* argv[])
|
|||
return true;
|
||||
}
|
||||
|
||||
const char* conGrenadeProjectileGetPosition(SimObject *obj, S32 argc, const char* argv[])
|
||||
const char* conGrenadeProjectileGetPosition(Linker::SimObject *obj, S32 argc, const char* argv[])
|
||||
{
|
||||
char result[256];
|
||||
|
||||
|
|
@ -62,7 +65,7 @@ const char* conGrenadeProjectileGetPosition(SimObject *obj, S32 argc, const char
|
|||
return result;
|
||||
}
|
||||
|
||||
const char* conGrenadeProjectileGetVelocity(SimObject *obj, S32 argc, const char* argv[])
|
||||
const char* conGrenadeProjectileGetVelocity(Linker::SimObject *obj, S32 argc, const char* argv[])
|
||||
{
|
||||
char result[256];
|
||||
|
||||
|
|
@ -77,7 +80,7 @@ const char* conGrenadeProjectileGetVelocity(SimObject *obj, S32 argc, const char
|
|||
#include <vector>
|
||||
#include <string.h>
|
||||
|
||||
const char* conSprintf(SimObject *obj, S32 argc, const char* argv[])
|
||||
const char* conSprintf(Linker::SimObject *obj, S32 argc, const char* argv[])
|
||||
{
|
||||
std::vector<const char*> input;
|
||||
for (unsigned int i = 2; i < argc; i++)
|
||||
|
|
|
|||
308
Mod Sources/TSExtension/TSExtension/source/DXTCPObjects.cpp
Normal file
308
Mod Sources/TSExtension/TSExtension/source/DXTCPObjects.cpp
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
#include <LinkerAPI.h>
|
||||
#include <DXAPI/DXAPI.h>
|
||||
|
||||
#include <WinSock.h>
|
||||
#include <WinDNS.h>
|
||||
|
||||
#define TCPOBJECT_MAXCOUNT 256
|
||||
|
||||
static unsigned int TSEXTENSION_RUNNINGTCPOBJECTCOUNT = 0;
|
||||
static DX::TCPObject *TSEXTENSION_RUNNINGTCPOBJECTS[TCPOBJECT_MAXCOUNT];
|
||||
|
||||
inline DX::TCPObject *TCPObject_Find(unsigned int identifier)
|
||||
{
|
||||
// Make sure it's in our list of objects
|
||||
for (unsigned int iteration = 0; iteration < TSEXTENSION_RUNNINGTCPOBJECTCOUNT; iteration++)
|
||||
if (TSEXTENSION_RUNNINGTCPOBJECTS[iteration]->identifier == identifier)
|
||||
return TSEXTENSION_RUNNINGTCPOBJECTS[iteration];
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *target_hostname;
|
||||
unsigned int target_port;
|
||||
|
||||
unsigned int buffer_length;
|
||||
char *buffer;
|
||||
|
||||
bool send_retry;
|
||||
|
||||
SOCKET socket;
|
||||
} ConnectionInformation;
|
||||
|
||||
|
||||
inline bool TCPObject_Disconnect(unsigned int identifier)
|
||||
{
|
||||
DX::TCPObject *obj = TCPObject_Find(identifier);
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
ConnectionInformation *connection = (ConnectionInformation*)obj->state;
|
||||
|
||||
closesocket(connection->socket);
|
||||
connection->socket = 0;
|
||||
|
||||
// Find us in the array
|
||||
unsigned int target_index = 0;
|
||||
for (unsigned int iteration = 0; iteration < TSEXTENSION_RUNNINGTCPOBJECTCOUNT; iteration++)
|
||||
if (TSEXTENSION_RUNNINGTCPOBJECTS[iteration] == obj)
|
||||
{
|
||||
target_index = iteration;
|
||||
break;
|
||||
}
|
||||
|
||||
// Fix the array
|
||||
for (unsigned int iteration = target_index; iteration < TSEXTENSION_RUNNINGTCPOBJECTCOUNT; iteration++)
|
||||
TSEXTENSION_RUNNINGTCPOBJECTS[iteration] = TSEXTENSION_RUNNINGTCPOBJECTS[iteration + 1];
|
||||
TSEXTENSION_RUNNINGTCPOBJECTCOUNT--;
|
||||
|
||||
obj->TSCall("onDisconnect", 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
#define TCPOBJECT_BUFFERSIZE 256
|
||||
enum TCPObjectEvent
|
||||
{
|
||||
TCPObjectEvent_FailedDNSLookup = 1,
|
||||
TCPObjectEvent_FailedConnection = 2,
|
||||
TCPObjectEvent_FailedConnectionNoPort = 3,
|
||||
TCPObjectEvent_FailedSocketCreation = 4,
|
||||
TCPObjectEvent_FailedRecv = 5,
|
||||
TCPObjectEvent_NULL = 6, // Should be the first Good Identifier
|
||||
TCPObjectEvent_GoodDNSLookup = 7,
|
||||
TCPObjectEvent_GoodConnection = 8,
|
||||
TCPObjectEvent_ReceivedData = 9,
|
||||
};
|
||||
|
||||
const char* conTCPObjectConnect(Linker::SimObject *obj, S32 argc, const char *argv[])
|
||||
{
|
||||
DX::TCPObject *operand = new DX::TCPObject((unsigned int)obj);
|
||||
DX::TCPObject *search_object = TCPObject_Find(operand->identifier);
|
||||
if (search_object)
|
||||
{
|
||||
delete operand;
|
||||
operand = search_object;
|
||||
TCPObject_Disconnect(search_object->identifier);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Copy the hostname over
|
||||
char *desired_hostname = (char*)malloc(strlen(argv[2]) + 1);
|
||||
memcpy(desired_hostname, argv[2], strlen(argv[2]) + 1);
|
||||
|
||||
// Create the connection info
|
||||
ConnectionInformation *connection = new ConnectionInformation;
|
||||
connection->target_hostname = desired_hostname;
|
||||
connection->buffer = 0x00;
|
||||
connection->buffer_length = 0;
|
||||
connection->send_retry = false;
|
||||
connection->socket = 10;
|
||||
|
||||
// Hack: Store the Ptr to our connection information struct in the old unused state value
|
||||
operand->state = (unsigned int)connection;
|
||||
|
||||
//ConnectionInformation *connection = (ConnectionInformation*)parameters;
|
||||
char *target_hostname = strlwr(connection->target_hostname);
|
||||
|
||||
// Is it an IP we got?
|
||||
bool needs_dns_translation = false;
|
||||
if (strstr(target_hostname, "ip:"))
|
||||
target_hostname += 3; // Chop off the 'ip:' segment
|
||||
else
|
||||
needs_dns_translation = true;
|
||||
|
||||
// Did we get a port #?
|
||||
unsigned int desired_port = 0;
|
||||
char *port_delineator = strstr(target_hostname, ":");
|
||||
if (port_delineator)
|
||||
{
|
||||
port_delineator[0] = 0x00; // NULL Terminate the IP Segment
|
||||
port_delineator += 1;
|
||||
desired_port = atoi(port_delineator);
|
||||
}
|
||||
else
|
||||
{
|
||||
Con::errorf(0, "No Port");
|
||||
operand->TSCall("onConnectFailed", 0);
|
||||
return "NO_PORT";
|
||||
}
|
||||
|
||||
// Perform a DNS Lookup if we need to
|
||||
if (needs_dns_translation)
|
||||
{
|
||||
wchar_t hostname_dns[128];
|
||||
std::mbstowcs(hostname_dns, target_hostname, strlen(target_hostname) + 1);
|
||||
|
||||
PDNS_RECORD dns_record;
|
||||
if (DnsQuery(hostname_dns, DNS_TYPE_A, DNS_QUERY_BYPASS_CACHE, NULL, &dns_record, NULL))
|
||||
{
|
||||
Con::errorf(0, "DNS Resolution Failed");
|
||||
operand->TSCall("onDNSFailed", 0);
|
||||
return "FAILED_DNS";
|
||||
}
|
||||
IN_ADDR result_address;
|
||||
result_address.S_un.S_addr = dns_record->Data.A.IpAddress;
|
||||
|
||||
// Free the DNS List
|
||||
DNS_FREE_TYPE freetype;
|
||||
DnsRecordListFree(dns_record, freetype);
|
||||
|
||||
target_hostname = inet_ntoa(result_address);
|
||||
}
|
||||
|
||||
SOCKADDR_IN target_host;
|
||||
target_host.sin_family = AF_INET;
|
||||
target_host.sin_port = htons(desired_port);
|
||||
target_host.sin_addr.s_addr = inet_addr(target_hostname);
|
||||
|
||||
Con::errorf(0, "Target %s on port %u SimID %u", target_hostname, desired_port, operand->identifier);
|
||||
|
||||
// Create the Socket
|
||||
connection->socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (connection->socket == INVALID_SOCKET)
|
||||
{
|
||||
Con::errorf(0, "Failed to create Socket!");
|
||||
operand->TSCall("onSocketCreationFailed", 0);
|
||||
return "FAILED_SOCKET_CREATION";
|
||||
}
|
||||
|
||||
// Attempt the Connection
|
||||
if(connect(connection->socket, (SOCKADDR*)&target_host, sizeof(target_host)) != 0)
|
||||
{
|
||||
Con::errorf(0, "Failed to connect!");
|
||||
operand->TSCall("onConnectFailed", 0);
|
||||
return "CANNOT_CONNECT";
|
||||
}
|
||||
else
|
||||
operand->TSCall("onConnected", 0);
|
||||
|
||||
// Set Blocking Mode
|
||||
u_long imode = 1;
|
||||
ioctlsocket(connection->socket, FIONBIO, &imode);
|
||||
|
||||
// Stick us in the TCPObject array
|
||||
TSEXTENSION_RUNNINGTCPOBJECTS[TSEXTENSION_RUNNINGTCPOBJECTCOUNT] = operand;
|
||||
TSEXTENSION_RUNNINGTCPOBJECTCOUNT++;
|
||||
|
||||
return "unknown_error";
|
||||
}
|
||||
|
||||
bool conTCPObjectSend(Linker::SimObject *obj, S32 argc, const char *argv[])
|
||||
{
|
||||
DX::TCPObject operand((unsigned int)obj);
|
||||
|
||||
Con::errorf(0, "Should Send? - SimID %u", operand.identifier);
|
||||
//if (!TCPObject_Find(operand.identifier))
|
||||
// return false;
|
||||
|
||||
Con::errorf(0, "Sending");
|
||||
|
||||
ConnectionInformation *connection = (ConnectionInformation*)operand.state;
|
||||
|
||||
// Pause the thread as we're doing an recv in the main thread
|
||||
if (send(connection->socket, argv[2], strlen(argv[2]), 0) == SOCKET_ERROR)
|
||||
{
|
||||
Con::errorf(0, "Failed to send: %u (Socket: %u, SimID: %u)", WSAGetLastError(), connection->socket, operand.identifier);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool conTCPObjectDisconnect(Linker::SimObject *obj, S32 argc, const char *argv[])
|
||||
{
|
||||
DX::TCPObject operand((unsigned int)obj);
|
||||
return TCPObject_Disconnect(operand.identifier);
|
||||
}
|
||||
|
||||
bool conTSExtensionUpdate(Linker::SimObject *obj, S32 argc, const char *argv[])
|
||||
{
|
||||
// Iterate through any active sockets
|
||||
static char *character_buffer = (char*)malloc(TCPOBJECT_BUFFERSIZE);
|
||||
|
||||
// List of objects to D/C
|
||||
//TCPObject_Disconnect
|
||||
unsigned int disconnected_object_count = 0;
|
||||
static DX::TCPObject **disconnected_objects = (DX::TCPObject**)malloc(sizeof(DX::TCPObject*) * TCPOBJECT_MAXCOUNT);
|
||||
|
||||
for (unsigned int iteration = 0; iteration < TSEXTENSION_RUNNINGTCPOBJECTCOUNT; iteration++)
|
||||
{
|
||||
DX::TCPObject *current_connection = TSEXTENSION_RUNNINGTCPOBJECTS[iteration];
|
||||
ConnectionInformation *connection_information = (ConnectionInformation*)current_connection->state;
|
||||
|
||||
// TODO: Kill the TCPObject
|
||||
if (connection_information->socket == 0)
|
||||
continue;
|
||||
|
||||
unsigned int data_length = recv(connection_information->socket, character_buffer, TCPOBJECT_BUFFERSIZE, 0);
|
||||
|
||||
int currentError = WSAGetLastError();
|
||||
if (currentError != WSAEWOULDBLOCK && currentError != 0)
|
||||
Con::errorf(0, "Got an error! %u", currentError);
|
||||
else if (data_length == 0)
|
||||
{
|
||||
Con::errorf(0, "Finished receiving?");
|
||||
|
||||
// Put us on the D/C list
|
||||
disconnected_objects[disconnected_object_count] = current_connection;
|
||||
disconnected_object_count++;
|
||||
|
||||
// Stream the data into ::onLine
|
||||
unsigned int current_start = 0;
|
||||
for (unsigned int split_iteration = 0; split_iteration < connection_information->buffer_length; split_iteration++)
|
||||
if (connection_information->buffer[split_iteration] == '\n' || split_iteration == connection_information->buffer_length - 1)
|
||||
{
|
||||
unsigned int desired_length = (split_iteration - current_start);
|
||||
char *current_line = (char*)malloc(desired_length + 1);
|
||||
memset(current_line, 0x00, desired_length + 1);
|
||||
memcpy(current_line, &connection_information->buffer[current_start], desired_length);
|
||||
|
||||
current_start = split_iteration + 1;
|
||||
current_connection->TSCall("onLine", 1, current_line);
|
||||
free(current_line);
|
||||
}
|
||||
|
||||
closesocket(connection_information->socket);
|
||||
connection_information->socket = 0;
|
||||
free(connection_information->buffer);
|
||||
}
|
||||
else if (data_length <= TCPOBJECT_BUFFERSIZE)
|
||||
{
|
||||
Con::errorf(0, "Received Data: %u", data_length);
|
||||
|
||||
// If our connection hasn't buffered anything yet
|
||||
if (connection_information->buffer == 0x00)
|
||||
{
|
||||
connection_information->buffer = (char*)malloc(data_length);
|
||||
memset(connection_information->buffer, 0x00, data_length);
|
||||
|
||||
connection_information->buffer_length = data_length;
|
||||
memcpy(connection_information->buffer, character_buffer, data_length);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int new_buffer_length = data_length + connection_information->buffer_length;
|
||||
char *new_buffer = (char*)malloc(new_buffer_length);
|
||||
memset(new_buffer, 0x00, new_buffer_length);
|
||||
|
||||
// Copy the two halves
|
||||
memcpy(new_buffer, connection_information->buffer, connection_information->buffer_length);
|
||||
memcpy(&new_buffer[connection_information->buffer_length], character_buffer, data_length);
|
||||
|
||||
connection_information->buffer = new_buffer;
|
||||
connection_information->buffer_length = new_buffer_length;
|
||||
}
|
||||
|
||||
memset(character_buffer, 0x00, TCPOBJECT_BUFFERSIZE);
|
||||
}
|
||||
}
|
||||
|
||||
// Process Disconnect list
|
||||
for (unsigned int iteration = 0; iteration < disconnected_object_count; iteration++)
|
||||
TCPObject_Disconnect(disconnected_objects[iteration]->identifier);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1,17 +1,17 @@
|
|||
#include <LinkerAPI.h>
|
||||
|
||||
SimIdDictionary* gIdDictionary = reinterpret_cast<SimIdDictionary*>(0x009E9194);
|
||||
//SimIdDictionary* gIdDictionary = reinterpret_cast<SimIdDictionary*>(0x009E9194);
|
||||
|
||||
//439550
|
||||
namespace Sim {
|
||||
SimObject* (*findObject)(U32 id) =
|
||||
(SimObject* (_cdecl *)(U32 id) )
|
||||
Linker::SimObject* (*findObject)(U32 id) =
|
||||
(Linker::SimObject* (_cdecl *)(U32 id) )
|
||||
0x439550;
|
||||
}
|
||||
|
||||
//hackey way to do member functions, ....
|
||||
void GuiTSCtrl_project(GuiTSCtrl *obj, const Point3F &pt, Point3F *dest) {
|
||||
typedef void (__cdecl *projFunc)(const Point3F &pt, Point3F *dest);
|
||||
void GuiTSCtrl_project(GuiTSCtrl *obj, const Linker::Point3F &pt, Linker::Point3F *dest) {
|
||||
typedef void (__cdecl *projFunc)(const Linker::Point3F &pt, Linker::Point3F *dest);
|
||||
static projFunc p = (projFunc)0x4d0b40;
|
||||
|
||||
__asm {
|
||||
|
|
@ -55,8 +55,8 @@ const char * (*evaluate)(const char* string, bool echo, const char *fileName, bo
|
|||
(const char * (__cdecl *)(const char* string, bool echo, const char *fileName, bool cf))
|
||||
0x426690;
|
||||
|
||||
const char * (*executem)(SimObject *object, S32 argc, const char *argv[]) =
|
||||
(const char * (__cdecl *)(SimObject *object, S32 argc, const char *argv[]))
|
||||
const char * (*executem)(Linker::SimObject *object, S32 argc, const char *argv[]) =
|
||||
(const char * (__cdecl *)(Linker::SimObject *object, S32 argc, const char *argv[]))
|
||||
0x426800;
|
||||
|
||||
const char * (*getVariable)(const char *name) =
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ extern "C"
|
|||
{
|
||||
Con::addMethodB("Player", "isjumping", &conPlayerGetJumpingState,"Returns whether or not the player is jumping", 2, 2);
|
||||
Con::addMethodB("Player", "isjetting", &conPlayerGetJettingState,"Returns whether or not the player is jetting", 2, 2);
|
||||
Con::addMethodB("GameConnection", "setheat", &conGameConnectionSetHeatLevel,"Sets the heat level", 3, 3);
|
||||
|
||||
Con::addMethodB("GrenadeProjectile", "explode", &conProjectileExplode,"Explodes the given projectile", 5, 5);
|
||||
Con::addMethodB("Projectile", "explode", &conProjectileExplode,"Explodes the given projectile", 5, 5);
|
||||
|
|
@ -37,7 +38,14 @@ extern "C"
|
|||
Con::addMethodS("GrenadeProjectile", "getvelocity", &conGrenadeProjectileGetVelocity,"Gets the velocity of the GrenadeProjectile", 2, 2);
|
||||
Con::addMethodB("Projectile", "makeNerf", &conProjectileMakeNerf,"Makes the Projectile deal no damage", 2, 2);
|
||||
|
||||
// TCPObject
|
||||
Con::addMethodS("TCPObject", "altConnect", &conTCPObjectConnect, "Connects to a remote server", 3, 3);
|
||||
Con::addMethodB("TCPObject", "altSend", &conTCPObjectSend, "Sends data to the remote server", 3, 3);
|
||||
Con::addMethodB("TCPObject", "altDisconnect", &conTCPObjectDisconnect, "Disconnects from the remote server", 2, 2);
|
||||
|
||||
// General
|
||||
Con::addMethodS(NULL, "sprintf", &conSprintf,"Formats a string. See the C sprintf.", 2, 20);
|
||||
Con::addMethodB(NULL, "tsExtensionUpdate", &conTSExtensionUpdate,"Updates the TSExtension.", 1, 1);
|
||||
|
||||
// Add this Gvar to signify that TSExtension is active
|
||||
static bool is_active = true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue