diff --git a/Mod Sources/TSExtension/TSExtension/TSExtension.vcxproj b/Mod Sources/TSExtension/TSExtension/TSExtension.vcxproj
index 6ab5808..15dfc68 100644
--- a/Mod Sources/TSExtension/TSExtension/TSExtension.vcxproj
+++ b/Mod Sources/TSExtension/TSExtension/TSExtension.vcxproj
@@ -15,32 +15,42 @@
+
+
+
+
+
+
+
+
+
+
@@ -91,6 +101,7 @@
Windows
true
+ ws2_32.lib;Dnsapi.lib;%(AdditionalDependencies)
@@ -107,6 +118,7 @@
true
true
true
+ ws2_32.lib;Dnsapi.lib;%(AdditionalDependencies)
diff --git a/Mod Sources/TSExtension/TSExtension/include/DXAPI/DXAPI.h b/Mod Sources/TSExtension/TSExtension/include/DXAPI/DXAPI.h
index f809a40..72391c4 100644
--- a/Mod Sources/TSExtension/TSExtension/include/DXAPI/DXAPI.h
+++ b/Mod Sources/TSExtension/TSExtension/include/DXAPI/DXAPI.h
@@ -30,9 +30,19 @@
#include
#include
#include
+#include
namespace DX
{
//! A typedef referring to some type of unresolved object in the game.
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
\ No newline at end of file
diff --git a/Mod Sources/TSExtension/TSExtension/include/DXAPI/ScriptObject.h b/Mod Sources/TSExtension/TSExtension/include/DXAPI/ScriptObject.h
new file mode 100644
index 0000000..9149d99
--- /dev/null
+++ b/Mod Sources/TSExtension/TSExtension/include/DXAPI/ScriptObject.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include
+
+namespace DX
+{
+ class ScriptObject : public SimObject
+ {
+ public:
+ ScriptObject(unsigned int obj);
+ };
+} // End NameSpace DX
diff --git a/Mod Sources/TSExtension/TSExtension/include/DXConCmds.h b/Mod Sources/TSExtension/TSExtension/include/DXConCmds.h
index 106d503..14685f7 100644
--- a/Mod Sources/TSExtension/TSExtension/include/DXConCmds.h
+++ b/Mod Sources/TSExtension/TSExtension/include/DXConCmds.h
@@ -39,6 +39,17 @@ bool conTCPObjectDisconnect(Linker::SimObject *obj, S32 argc, const char *argv[]
// HTTPObject Commands ------------------------------
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 ---------------------------------
const char* conSprintf(Linker::SimObject *obj, S32 argc, const char* argv[]);
bool conTSExtensionUpdate(Linker::SimObject *obj, S32 argc, const char *argv[]);
\ No newline at end of file
diff --git a/Mod Sources/TSExtension/TSExtension/source/DXAPI/DXAPI.cpp b/Mod Sources/TSExtension/TSExtension/source/DXAPI/DXAPI.cpp
index 6498e5c..e97ccd6 100644
--- a/Mod Sources/TSExtension/TSExtension/source/DXAPI/DXAPI.cpp
+++ b/Mod Sources/TSExtension/TSExtension/source/DXAPI/DXAPI.cpp
@@ -19,5 +19,107 @@
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;
+ }
}
\ No newline at end of file
diff --git a/Mod Sources/TSExtension/TSExtension/source/DXAPI/ScriptObject.cpp b/Mod Sources/TSExtension/TSExtension/source/DXAPI/ScriptObject.cpp
new file mode 100644
index 0000000..18bf1aa
--- /dev/null
+++ b/Mod Sources/TSExtension/TSExtension/source/DXAPI/ScriptObject.cpp
@@ -0,0 +1,8 @@
+#include
+
+namespace DX
+{
+ ScriptObject::ScriptObject(unsigned int obj) : SimObject(obj)
+ {
+ }
+}
\ No newline at end of file
diff --git a/Mod Sources/TSExtension/TSExtension/source/DXBinaryObjects.cpp b/Mod Sources/TSExtension/TSExtension/source/DXBinaryObjects.cpp
new file mode 100644
index 0000000..957f2a3
--- /dev/null
+++ b/Mod Sources/TSExtension/TSExtension/source/DXBinaryObjects.cpp
@@ -0,0 +1,291 @@
+/**
+ */
+
+#include
+#include
+
+#include