Experimental TCPObject coding; registered in TS as alt*

This commit is contained in:
Robert MacGregor 2014-09-02 02:13:03 -04:00
parent 3fd5187fd9
commit fa724913e3
24 changed files with 587 additions and 115 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -8,5 +8,8 @@ namespace DX
{
public:
ShapeBase(unsigned int obj);
//! Heat Level
float &heat_level;
};
} // End NameSpace DX

View file

@ -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

View file

@ -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

View file

@ -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[]);

View file

@ -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);
}

View file

@ -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;
}
}
}

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/NetConnection.h>
namespace DX
{
NetConnection::NetConnection(unsigned int obj) : SimObject(obj)
{
}
}

View file

@ -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)
{
}
}

View file

@ -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))
{
}

View file

@ -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;
}
}
}

View file

@ -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))
{
}
}

View file

@ -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;
}
}

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

@ -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++)

View 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;
}

View file

@ -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) =

View file

@ -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;