mirror of
https://github.com/Ragora/T2-CPP.git
synced 2026-07-16 09:44:33 +00:00
Experimental BinaryObject implementation -- Only Read support; unfinished
This commit is contained in:
parent
4c0f51b22b
commit
b0702cf70f
9 changed files with 458 additions and 1 deletions
|
|
@ -15,32 +15,42 @@
|
||||||
<ClCompile Include="source\DXAPI\DXAPI.cpp" />
|
<ClCompile Include="source\DXAPI\DXAPI.cpp" />
|
||||||
<ClCompile Include="source\DXAPI\FlyingVehicle.cpp" />
|
<ClCompile Include="source\DXAPI\FlyingVehicle.cpp" />
|
||||||
<ClCompile Include="source\DXAPI\GameBase.cpp" />
|
<ClCompile Include="source\DXAPI\GameBase.cpp" />
|
||||||
|
<ClCompile Include="source\DXAPI\GameConnection.cpp" />
|
||||||
<ClCompile Include="source\DXAPI\GrenadeProjectile.cpp" />
|
<ClCompile Include="source\DXAPI\GrenadeProjectile.cpp" />
|
||||||
|
<ClCompile Include="source\DXAPI\NetConnection.cpp" />
|
||||||
<ClCompile Include="source\DXAPI\NetObject.cpp" />
|
<ClCompile Include="source\DXAPI\NetObject.cpp" />
|
||||||
<ClCompile Include="source\DXAPI\Player.cpp" />
|
<ClCompile Include="source\DXAPI\Player.cpp" />
|
||||||
<ClCompile Include="source\DXAPI\Point3F.cpp" />
|
<ClCompile Include="source\DXAPI\Point3F.cpp" />
|
||||||
<ClCompile Include="source\DXAPI\Projectile.cpp" />
|
<ClCompile Include="source\DXAPI\Projectile.cpp" />
|
||||||
<ClCompile Include="source\DXAPI\SceneObject.cpp" />
|
<ClCompile Include="source\DXAPI\SceneObject.cpp" />
|
||||||
|
<ClCompile Include="source\DXAPI\ScriptObject.cpp" />
|
||||||
<ClCompile Include="source\DXAPI\ShapeBase.cpp" />
|
<ClCompile Include="source\DXAPI\ShapeBase.cpp" />
|
||||||
<ClCompile Include="source\DXAPI\SimObject.cpp" />
|
<ClCompile Include="source\DXAPI\SimObject.cpp" />
|
||||||
<ClCompile Include="source\DXAPI\StaticShape.cpp" />
|
<ClCompile Include="source\DXAPI\StaticShape.cpp" />
|
||||||
|
<ClCompile Include="source\DXAPI\TCPObject.cpp" />
|
||||||
<ClCompile Include="source\DXAPI\Vehicle.cpp" />
|
<ClCompile Include="source\DXAPI\Vehicle.cpp" />
|
||||||
|
<ClCompile Include="source\DXBinaryObjects.cpp" />
|
||||||
<ClCompile Include="source\DXConCmds.cpp" />
|
<ClCompile Include="source\DXConCmds.cpp" />
|
||||||
|
<ClCompile Include="source\DXTCPObjects.cpp" />
|
||||||
<ClCompile Include="source\LinkerAPI.cpp" />
|
<ClCompile Include="source\LinkerAPI.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="include\DXAPI\DXAPI.h" />
|
<ClInclude Include="include\DXAPI\DXAPI.h" />
|
||||||
<ClInclude Include="include\DXAPI\FlyingVehicle.h" />
|
<ClInclude Include="include\DXAPI\FlyingVehicle.h" />
|
||||||
<ClInclude Include="include\DXAPI\GameBase.h" />
|
<ClInclude Include="include\DXAPI\GameBase.h" />
|
||||||
|
<ClInclude Include="include\DXAPI\GameConnection.h" />
|
||||||
<ClInclude Include="include\DXAPI\GrenadeProjectile.h" />
|
<ClInclude Include="include\DXAPI\GrenadeProjectile.h" />
|
||||||
|
<ClInclude Include="include\DXAPI\NetConnection.h" />
|
||||||
<ClInclude Include="include\DXAPI\NetObject.h" />
|
<ClInclude Include="include\DXAPI\NetObject.h" />
|
||||||
<ClInclude Include="include\DXAPI\Player.h" />
|
<ClInclude Include="include\DXAPI\Player.h" />
|
||||||
<ClInclude Include="include\DXAPI\Point3F.h" />
|
<ClInclude Include="include\DXAPI\Point3F.h" />
|
||||||
<ClInclude Include="include\DXAPI\Projectile.h" />
|
<ClInclude Include="include\DXAPI\Projectile.h" />
|
||||||
<ClInclude Include="include\DXAPI\SceneObject.h" />
|
<ClInclude Include="include\DXAPI\SceneObject.h" />
|
||||||
|
<ClInclude Include="include\DXAPI\ScriptObject.h" />
|
||||||
<ClInclude Include="include\DXAPI\ShapeBase.h" />
|
<ClInclude Include="include\DXAPI\ShapeBase.h" />
|
||||||
<ClInclude Include="include\DXAPI\SimObject.h" />
|
<ClInclude Include="include\DXAPI\SimObject.h" />
|
||||||
<ClInclude Include="include\DXAPI\StaticShape.h" />
|
<ClInclude Include="include\DXAPI\StaticShape.h" />
|
||||||
|
<ClInclude Include="include\DXAPI\TCPObject.h" />
|
||||||
<ClInclude Include="include\DXAPI\Vehicle.h" />
|
<ClInclude Include="include\DXAPI\Vehicle.h" />
|
||||||
<ClInclude Include="include\DXConCmds.h" />
|
<ClInclude Include="include\DXConCmds.h" />
|
||||||
<ClInclude Include="include\LinkerAPI.h" />
|
<ClInclude Include="include\LinkerAPI.h" />
|
||||||
|
|
@ -91,6 +101,7 @@
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>ws2_32.lib;Dnsapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
|
@ -107,6 +118,7 @@
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<AdditionalDependencies>ws2_32.lib;Dnsapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,19 @@
|
||||||
#include <DXAPI/GameConnection.h>
|
#include <DXAPI/GameConnection.h>
|
||||||
#include <DXAPI/NetConnection.h>
|
#include <DXAPI/NetConnection.h>
|
||||||
#include <DXAPI/TCPObject.h>
|
#include <DXAPI/TCPObject.h>
|
||||||
|
#include <DXAPI/ScriptObject.h>
|
||||||
|
|
||||||
namespace DX
|
namespace DX
|
||||||
{
|
{
|
||||||
//! A typedef referring to some type of unresolved object in the game.
|
//! A typedef referring to some type of unresolved object in the game.
|
||||||
typedef void* UnresolvedObject;
|
typedef void* UnresolvedObject;
|
||||||
|
|
||||||
|
const char *GetModPaths(void);
|
||||||
|
|
||||||
|
bool IsFile(const char *filename);
|
||||||
|
|
||||||
|
bool GetRelativePath(const char *filename, char *ret, int buffer_length);
|
||||||
|
bool GetRunningMod(char *ret, int buffer_length);
|
||||||
|
|
||||||
|
bool SanitizeFileName(char *ret, int buffer_length);
|
||||||
} // End NameSpace DX
|
} // End NameSpace DX
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <DXAPI/SimObject.h>
|
||||||
|
|
||||||
|
namespace DX
|
||||||
|
{
|
||||||
|
class ScriptObject : public SimObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScriptObject(unsigned int obj);
|
||||||
|
};
|
||||||
|
} // End NameSpace DX
|
||||||
|
|
@ -39,6 +39,17 @@ bool conTCPObjectDisconnect(Linker::SimObject *obj, S32 argc, const char *argv[]
|
||||||
// HTTPObject Commands ------------------------------
|
// HTTPObject Commands ------------------------------
|
||||||
bool conHTTPObjectDoNothing(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
bool conHTTPObjectDoNothing(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||||
|
|
||||||
|
// BinaryObject Commands ----------------------------
|
||||||
|
bool conBinaryObjectOpenForRead(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||||
|
const char *conBinaryObjectReadU32(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||||
|
const char *conBinaryObjectReadF32(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||||
|
const char *conBinaryObjectReadU8(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||||
|
const char *conBinaryObjectGetBufferLength(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||||
|
bool conBinaryObjectSetBufferPointer(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||||
|
const char *conBinaryObjectGetBufferPointer(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||||
|
bool conBinaryObjectClose(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||||
|
bool conBinaryObjectSave(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||||
|
|
||||||
// General Commands ---------------------------------
|
// General Commands ---------------------------------
|
||||||
const char* conSprintf(Linker::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[]);
|
bool conTSExtensionUpdate(Linker::SimObject *obj, S32 argc, const char *argv[]);
|
||||||
|
|
@ -19,5 +19,107 @@
|
||||||
|
|
||||||
namespace DX
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
#include <DXAPI/ScriptObject.h>
|
||||||
|
|
||||||
|
namespace DX
|
||||||
|
{
|
||||||
|
ScriptObject::ScriptObject(unsigned int obj) : SimObject(obj)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
291
Mod Sources/TSExtension/TSExtension/source/DXBinaryObjects.cpp
Normal file
291
Mod Sources/TSExtension/TSExtension/source/DXBinaryObjects.cpp
Normal file
|
|
@ -0,0 +1,291 @@
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LinkerAPI.h>
|
||||||
|
#include <DXAPI/DXAPI.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *buffer;
|
||||||
|
int buffer_length;
|
||||||
|
int buffer_pointer;
|
||||||
|
bool disk_streaming;
|
||||||
|
FILE *handle;
|
||||||
|
} DXBinaryObject;
|
||||||
|
|
||||||
|
typedef std::map<unsigned int, DXBinaryObject*> DXBinaryObjectMapping;
|
||||||
|
static DXBinaryObjectMapping DXBinaryObjectMap;
|
||||||
|
|
||||||
|
bool conBinaryObjectOpenForRead(Linker::SimObject *obj, S32 argc, const char *argv[])
|
||||||
|
{
|
||||||
|
// By default we don't do disk streaming but this allows for the support
|
||||||
|
bool should_stream = false;
|
||||||
|
if (argc == 4)
|
||||||
|
{
|
||||||
|
int stream_value = atoi(argv[3]);
|
||||||
|
if (stream_value != 0)
|
||||||
|
should_stream = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DX::ScriptObject scriptobject((unsigned int)obj);
|
||||||
|
|
||||||
|
char filepath[256];
|
||||||
|
if (!DX::GetRelativePath(argv[2], filepath, 256))
|
||||||
|
{
|
||||||
|
scriptobject.CallMethod("onOpenFailed", 0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Already open
|
||||||
|
if (DXBinaryObjectMap.count(scriptobject.identifier) != 0)
|
||||||
|
{
|
||||||
|
// TODO: Make these report the actual errors
|
||||||
|
scriptobject.CallMethod("onOpenFailed", 0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *handle = fopen(filepath, "rb");
|
||||||
|
if (!handle)
|
||||||
|
{
|
||||||
|
Con::errorf(0, "Failed to open: %s", filepath);
|
||||||
|
scriptobject.CallMethod("onOpenFailed", 0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fseek(handle, 0, SEEK_END);
|
||||||
|
|
||||||
|
// Init the Binobj
|
||||||
|
DXBinaryObject *binobj = new DXBinaryObject;
|
||||||
|
binobj->disk_streaming = should_stream;
|
||||||
|
binobj->buffer_length = ftell(handle);
|
||||||
|
binobj->buffer_pointer = binobj->buffer_length;
|
||||||
|
binobj->handle = handle;
|
||||||
|
|
||||||
|
if (!should_stream)
|
||||||
|
binobj->buffer = new char[binobj->buffer_length];
|
||||||
|
|
||||||
|
// We don't need the file object anymore after we've read the buffer
|
||||||
|
// so we ditch it.
|
||||||
|
fseek(handle, 0, SEEK_SET);
|
||||||
|
|
||||||
|
if (!should_stream)
|
||||||
|
{
|
||||||
|
fread(binobj->buffer, binobj->buffer_length, 1, handle);
|
||||||
|
fclose(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
DXBinaryObjectMap[scriptobject.identifier] = binobj;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *conBinaryObjectReadU32(Linker::SimObject *obj, S32 argc, const char *argv[])
|
||||||
|
{
|
||||||
|
DX::ScriptObject scriptobject((unsigned int)obj);
|
||||||
|
|
||||||
|
// Not open
|
||||||
|
if (DXBinaryObjectMap.count(scriptobject.identifier) == 0)
|
||||||
|
{
|
||||||
|
scriptobject.CallMethod("onReadFailed", 0);
|
||||||
|
return "-1";
|
||||||
|
}
|
||||||
|
|
||||||
|
DXBinaryObject *binobj = DXBinaryObjectMap[scriptobject.identifier];
|
||||||
|
|
||||||
|
// Okay, so we're open, now we need to make sure we have enough bytes left in the buffer
|
||||||
|
int read_length = sizeof(unsigned int);
|
||||||
|
|
||||||
|
if (binobj->buffer_length - (binobj->buffer_length - binobj->buffer_pointer) < read_length)
|
||||||
|
{
|
||||||
|
scriptobject.CallMethod("onReadFailed", 0);
|
||||||
|
return "-1";
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int return_value = 0;
|
||||||
|
binobj->buffer_pointer -= read_length;
|
||||||
|
if (binobj->disk_streaming)
|
||||||
|
{
|
||||||
|
char out_memory[4];
|
||||||
|
fseek(binobj->handle, binobj->buffer_pointer, SEEK_SET);
|
||||||
|
fread(out_memory, 4, 1, binobj->handle);
|
||||||
|
return_value = *(unsigned int*)out_memory;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// Get a pointer to the object in the buffer and deref it
|
||||||
|
return_value = *(unsigned int*)&binobj->buffer[binobj->buffer_pointer];
|
||||||
|
|
||||||
|
char result[256];
|
||||||
|
sprintf_s<256>(result, "%u", return_value);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *conBinaryObjectReadF32(Linker::SimObject *obj, S32 argc, const char *argv[])
|
||||||
|
{
|
||||||
|
DX::ScriptObject scriptobject((unsigned int)obj);
|
||||||
|
|
||||||
|
// Not open
|
||||||
|
if (DXBinaryObjectMap.count(scriptobject.identifier) == 0)
|
||||||
|
{
|
||||||
|
scriptobject.CallMethod("onReadFailed", 0);
|
||||||
|
return "-1";
|
||||||
|
}
|
||||||
|
|
||||||
|
DXBinaryObject *binobj = DXBinaryObjectMap[scriptobject.identifier];
|
||||||
|
|
||||||
|
// Okay, so we're open, now we need to make sure we have enough bytes left in the buffer
|
||||||
|
int read_length = sizeof(float);
|
||||||
|
|
||||||
|
if (binobj->buffer_length - (binobj->buffer_length - binobj->buffer_pointer) < read_length)
|
||||||
|
{
|
||||||
|
scriptobject.CallMethod("onReadFailed", 0);
|
||||||
|
return "-1";
|
||||||
|
}
|
||||||
|
|
||||||
|
float return_value = 0;
|
||||||
|
binobj->buffer_pointer -= read_length;
|
||||||
|
if (binobj->disk_streaming)
|
||||||
|
{
|
||||||
|
char out_memory[4];
|
||||||
|
fseek(binobj->handle, binobj->buffer_pointer, SEEK_SET);
|
||||||
|
fread(out_memory, 4, 1, binobj->handle);
|
||||||
|
return_value = *(float*)out_memory;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// Get a pointer to the object in the buffer and deref it
|
||||||
|
return_value = *(float*)&binobj->buffer[binobj->buffer_pointer];
|
||||||
|
|
||||||
|
char result[256];
|
||||||
|
sprintf_s<256>(result, "%f", return_value);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *conBinaryObjectReadU8(Linker::SimObject *obj, S32 argc, const char *argv[])
|
||||||
|
{
|
||||||
|
DX::ScriptObject scriptobject((unsigned int)obj);
|
||||||
|
|
||||||
|
// Not open
|
||||||
|
if (DXBinaryObjectMap.count(scriptobject.identifier) == 0)
|
||||||
|
{
|
||||||
|
scriptobject.CallMethod("onReadFailed", 0);
|
||||||
|
return "-1";
|
||||||
|
}
|
||||||
|
|
||||||
|
DXBinaryObject *binobj = DXBinaryObjectMap[scriptobject.identifier];
|
||||||
|
|
||||||
|
// Okay, so we're open, now we need to make sure we have enough bytes left in the buffer
|
||||||
|
int read_length = sizeof(unsigned char);
|
||||||
|
|
||||||
|
if (binobj->buffer_length - (binobj->buffer_length - binobj->buffer_pointer) < read_length)
|
||||||
|
{
|
||||||
|
scriptobject.CallMethod("onReadFailed", 0);
|
||||||
|
return "-1";
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char return_value = 0;
|
||||||
|
binobj->buffer_pointer -= read_length;
|
||||||
|
if (binobj->disk_streaming)
|
||||||
|
{
|
||||||
|
char out_memory[1];
|
||||||
|
fseek(binobj->handle, binobj->buffer_pointer, SEEK_SET);
|
||||||
|
fread(out_memory, 4, 1, binobj->handle);
|
||||||
|
return_value = *(unsigned char*)out_memory;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// Get a pointer to the object in the buffer and deref it
|
||||||
|
return_value = *(unsigned char*)&binobj->buffer[binobj->buffer_pointer];
|
||||||
|
|
||||||
|
char result[256];
|
||||||
|
sprintf_s<256>(result, "%u", return_value);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool conBinaryObjectSetBufferPointer(Linker::SimObject *obj, S32 argc, const char *argv[])
|
||||||
|
{
|
||||||
|
// We don't need a full object instance for some of these
|
||||||
|
unsigned int identifier = atoi(argv[1]);
|
||||||
|
if (DXBinaryObjectMap.count(identifier) == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DXBinaryObject *binobj = DXBinaryObjectMap[identifier];
|
||||||
|
|
||||||
|
int desired_value = atoi(argv[2]);
|
||||||
|
if (desired_value < 0 || desired_value > binobj->buffer_length)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
binobj->buffer_pointer = desired_value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *conBinaryObjectGetBufferPointer(Linker::SimObject *obj, S32 argc, const char *argv[])
|
||||||
|
{
|
||||||
|
unsigned int identifier = atoi(argv[1]);
|
||||||
|
if (DXBinaryObjectMap.count(identifier) == 0)
|
||||||
|
return "-1";
|
||||||
|
|
||||||
|
DXBinaryObject *binobj = DXBinaryObjectMap[identifier];
|
||||||
|
|
||||||
|
char result[256];
|
||||||
|
sprintf_s<256>(result, "%u", binobj->buffer_pointer);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *conBinaryObjectGetBufferLength(Linker::SimObject *obj, S32 argc, const char *argv[])
|
||||||
|
{
|
||||||
|
unsigned int identifier = atoi(argv[1]);
|
||||||
|
if (DXBinaryObjectMap.count(identifier) == 0)
|
||||||
|
return "-1";
|
||||||
|
|
||||||
|
DXBinaryObject *binobj = DXBinaryObjectMap[identifier];
|
||||||
|
|
||||||
|
char result[256];
|
||||||
|
sprintf_s<256>(result, "%u", binobj->buffer_length);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool conBinaryObjectClose(Linker::SimObject *obj, S32 argc, const char *argv[])
|
||||||
|
{
|
||||||
|
unsigned int identifier = atoi(argv[1]);
|
||||||
|
if (DXBinaryObjectMap.count(identifier) == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DXBinaryObject *binobj = DXBinaryObjectMap[identifier];
|
||||||
|
if (!binobj->disk_streaming)
|
||||||
|
delete binobj->buffer;
|
||||||
|
else
|
||||||
|
fclose(binobj->handle);
|
||||||
|
|
||||||
|
delete binobj;
|
||||||
|
|
||||||
|
DXBinaryObjectMap.erase(identifier);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool conBinaryObjectSave(Linker::SimObject *obj, S32 argc, const char *argv[])
|
||||||
|
{
|
||||||
|
unsigned int identifier = atoi(argv[1]);
|
||||||
|
if (DXBinaryObjectMap.count(identifier) == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
char runningmod[256];
|
||||||
|
DX::GetRunningMod(runningmod, 256);
|
||||||
|
int runningmod_length = strlen(runningmod);
|
||||||
|
|
||||||
|
Con::errorf(0, "Got Mod: %s", runningmod);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
int filename_length = strlen(argv[2]);
|
||||||
|
char *desired_filename = (char*)malloc(filename_length + runningmod_length + 2);
|
||||||
|
memcpy(desired_filename, argv[2], filename_length + 1);
|
||||||
|
|
||||||
|
DX::SanitizeFileName(desired_filename, filename_length);
|
||||||
|
sprintf(desired_filename, "%s/%s", runningmod, desired_filename);
|
||||||
|
//Con::errorf(0, "Wrote to: %s", desired_filename);
|
||||||
|
|
||||||
|
FILE *handle = fopen(desired_filename, "wb");
|
||||||
|
DXBinaryObject *binobj = DXBinaryObjectMap[identifier];
|
||||||
|
fwrite(binobj->buffer, binobj->buffer_length, 1, handle);
|
||||||
|
fclose(handle);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
static unsigned int TSEXTENSION_RUNNINGTCPOBJECTCOUNT = 0;
|
static unsigned int TSEXTENSION_RUNNINGTCPOBJECTCOUNT = 0;
|
||||||
static DX::TCPObject *TSEXTENSION_RUNNINGTCPOBJECTS[TCPOBJECT_MAXCOUNT];
|
static DX::TCPObject *TSEXTENSION_RUNNINGTCPOBJECTS[TCPOBJECT_MAXCOUNT];
|
||||||
|
|
||||||
// Since wants TS function call arguments to be of type char*, we use this
|
// Since TS wants function call arguments to be of type char*, we use this
|
||||||
// helper function to painlessly pass in unsigned int arguments for things
|
// helper function to painlessly pass in unsigned int arguments for things
|
||||||
// such as the return value from WSAGetLastError().
|
// such as the return value from WSAGetLastError().
|
||||||
__forceinline static char *S32ToCharPtr(unsigned int in)
|
__forceinline static char *S32ToCharPtr(unsigned int in)
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,17 @@ extern "C"
|
||||||
Con::addMethodB("HTTPObject", "connect", &conHTTPObjectDoNothing, "Disconnects from the remote server", 6, 6);
|
Con::addMethodB("HTTPObject", "connect", &conHTTPObjectDoNothing, "Disconnects from the remote server", 6, 6);
|
||||||
Con::addMethodB("HTTPObject", "listen", &conHTTPObjectDoNothing, "Disconnects from the remote server", 6, 6);
|
Con::addMethodB("HTTPObject", "listen", &conHTTPObjectDoNothing, "Disconnects from the remote server", 6, 6);
|
||||||
|
|
||||||
|
// BinaryObject
|
||||||
|
Con::addMethodB("BinaryObject", "openforread", &conBinaryObjectOpenForRead, "Opens the input file for reading binary data", 3, 4);
|
||||||
|
Con::addMethodB("BinaryObject", "save", &conBinaryObjectSave, "Saves the binary object data to a file", 3, 3);
|
||||||
|
Con::addMethodS("BinaryObject", "readu32", &conBinaryObjectReadU32, "Reads an unsigned int from the buffer", 2, 2);
|
||||||
|
Con::addMethodS("BinaryObject", "readf32", &conBinaryObjectReadF32, "Reads a float from the buffer", 2, 2);
|
||||||
|
Con::addMethodS("BinaryObject", "readu8", &conBinaryObjectReadU8, "Reads a unsigned char from the buffer", 2, 2);
|
||||||
|
Con::addMethodB("BinaryObject", "setbufferpointer", &conBinaryObjectSetBufferPointer, "Sets the buffer pointer", 3, 3);
|
||||||
|
Con::addMethodS("BinaryObject", "getbufferlength", &conBinaryObjectGetBufferLength, "Returns the length of the buffer", 2, 2);
|
||||||
|
Con::addMethodS("BinaryObject", "getbufferpointer", &conBinaryObjectGetBufferPointer, "Returns the buffer pointer", 2, 2);
|
||||||
|
Con::addMethodB("BinaryObject", "close", &conBinaryObjectClose, "Closes the binary object", 2, 2);
|
||||||
|
|
||||||
// General
|
// General
|
||||||
Con::addMethodS(NULL, "sprintf", &conSprintf,"Formats a string. See the C sprintf.", 2, 20);
|
Con::addMethodS(NULL, "sprintf", &conSprintf,"Formats a string. See the C sprintf.", 2, 20);
|
||||||
Con::addMethodB(NULL, "tsExtensionUpdate", &conTSExtensionUpdate,"Updates the TSExtension.", 1, 1);
|
Con::addMethodB(NULL, "tsExtensionUpdate", &conTSExtensionUpdate,"Updates the TSExtension.", 1, 1);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue