Initial public release of rem-essentials

This commit is contained in:
2026-08-11 16:48:50 +02:00
commit d611924a5e
161 changed files with 9792 additions and 0 deletions
+386
View File
@@ -0,0 +1,386 @@
#pragma once
#include "fl_math.h"
#include "vftable.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <list>
#include "st6.h"
#define IMPORT __declspec(dllimport)
#define ENGINE_TYPE 0x20000
IMPORT UINT CreateID(LPCSTR str);
class INI_Reader
{
public:
IMPORT INI_Reader();
IMPORT ~INI_Reader();
IMPORT bool open(LPCSTR path, bool throwExceptionOnFail = false);
IMPORT bool read_header();
IMPORT bool is_header(LPCSTR name);
IMPORT LPCSTR get_header_ptr();
IMPORT bool read_value();
IMPORT bool is_value(LPCSTR name);
IMPORT LPCSTR get_value_string(UINT index = 0);
IMPORT bool get_value_bool(UINT index = 0);
IMPORT float get_value_float(UINT index = 0);
IMPORT int get_value_int(UINT index = 0);
IMPORT LPCSTR get_name_ptr();
IMPORT LPCSTR get_file_name() const;
IMPORT void close();
// inline UINT get_value_uint(UINT index = 0)
// {
// return static_cast<UINT>(get_value_float(index));
// }
inline UINT get_value_id(UINT index = 0)
{
return CreateID(get_value_string(index));
}
private:
BYTE data[0x1565];
};
class IMPORT CEquip
{
public:
FILL_VFTABLE(0);
FILL_VFTABLE(1);
FILL_VFTABLE(2);
virtual bool Activate(bool value);
};
class IMPORT CELightEquip : public CEquip
{
public:
static CELightEquip * cast(CEquip * equip);
};
class CELauncher
{
public:
IMPORT UINT GetProjectilesPerFire() const;
UINT GetProjectilesPerFire_Hook() const;
};
class IMPORT CEquipTraverser
{
public:
CEquipTraverser(int equipClass);
private:
BYTE data[0x10];
};
class IMPORT CEquipManager
{
public:
CEquip const * FindFirst(UINT type) const;
CEquip * Traverse(CEquipTraverser& equipTraverser);
private:
BYTE x00[0x20];
};
struct CollisionGroupDesc
{};
namespace Archetype
{
struct Root
{
BYTE data[0x44];
int scriptIndex; // 0x44
IMPORT int get_script_index() const;
};
struct EqObj
{
BYTE x00[0x14];
UINT idsName; // 0x14
UINT idsInfo; // 0x18
// st6::list
IMPORT bool get_undamaged_collision_group_list(std::list<CollisionGroupDesc>& colGroupList) const;
bool get_undamaged_collision_group_list_Hook(std::list<CollisionGroupDesc>& colGroupList) const;
};
struct Ship : public EqObj
{
BYTE x1C[0xEC];
Vector angularDrag; // 0x108
Vector steeringTorque; // 0x114
};
IMPORT Ship* GetShip(UINT shipId);
struct Solar : public EqObj
{
};
struct ShieldGenerator
{
BYTE x00[0x94];
float maxCapacity; // 0x94
BYTE x98[0x8];
float offlineThreshold; // 0xA0
};
}
class IMPORT EngineObject
{
public:
float const get_radius() const;
Matrix const & get_orientation() const;
long engineInstance; // 0x04
BYTE x08[0x44];
private:
FILL_VFTABLE(0);
FILL_VFTABLE(1);
FILL_VFTABLE(2);
FILL_VFTABLE(3);
};
struct IMPORT CObject : public EngineObject
{
Archetype::Root* get_archetype() const;
DWORD classType; // 0x4C
};
struct IMPORT CSimple : CObject
{
BYTE x50[0x60];
UINT nickname; // or simpleId, 0xB0
};
class CAttachedEquip
{
FILL_VFTABLE(0);
FILL_VFTABLE(1);
FILL_VFTABLE(2);
FILL_VFTABLE(3);
FILL_VFTABLE(4);
FILL_VFTABLE(5);
FILL_VFTABLE(6);
FILL_VFTABLE(7);
virtual void Vftable_x80();
public:
virtual long GetRootIndex() const;
CObject* parent; // x04
};
struct IMPORT CEqObj : public CSimple
{
private:
FILL_VFTABLE(4);
FILL_VFTABLE(5);
FILL_VFTABLE(6);
FILL_VFTABLE(7);
virtual void Vftable_x80();
virtual void Vftable_x84();
BYTE xB4[0x30];
public:
CEquipManager equipManager; // 0xE4
BYTE x104[0x5C];
UINT baseId; // 0x160
virtual UINT get_name() const; // 0x88
bool is_base() const;
};
struct IObjInspect;
#define CSHIP_CLASS_TYPE 0x503
struct CShip : public CEqObj
{
BYTE x164[0x50];
DWORD groupId; // 0x1B4
IMPORT float get_throttle() const;
IMPORT Archetype::Ship const * shiparch() const;
IMPORT bool is_using_tradelane() const;
IMPORT UINT get_group_name() const;
IMPORT bool is_enemy(IObjInspect *obj);
UINT get_group_name_Hook() const;
bool is_enemy_Hook(IObjInspect *obj);
};
#define CSOLAR_CLASS_TYPE 0x303
struct CSolar : public CEqObj
{
IMPORT bool is_dynamic() const;
IMPORT bool is_waypoint() const;
IMPORT Archetype::Solar const * solararch() const;
static inline const CSolar* cast(const CObject& obj)
{
if ((obj.classType & CSOLAR_CLASS_TYPE) == CSOLAR_CLASS_TYPE)
return (const CSolar*) &obj;
return nullptr;
}
};
inline bool IsObjectAWaypoint(const CObject& cobject)
{
const CSolar* solar = CSolar::cast(cobject);
if (!solar)
return false;
return solar->is_waypoint();
}
class IMPORT FuseAction
{
public:
virtual void Dealloc(bool unk);
virtual bool IsTriggered() const;
};
class IMPORT CEEngine : public FuseAction
{
public:
static CEEngine const * cast(CEquip const * equip);
};
class CRemotePhysicsSimulation
{
public:
IMPORT bool CheckForSync(Vector const &shipPos, Vector const &shipPos2, Quaternion const &unk);
bool CheckForSync_Hook(const CShip& ship, Vector const &shipPos, Quaternion const &unk);
};
struct IObjRW // : public IObjInspectImpl
{
BYTE x04[0xC];
CObject* cobject; // 0x10
BYTE x14[0x8];
int unk_x1C; // 0x1C
BYTE x20[0x16C];
DWORD flags; // 0x18C
FILL_VFTABLE(0)
FILL_VFTABLE(1)
virtual UINT get_simple_id() const; // 0x20
virtual void Vftable_x24();
virtual void Vftable_x28();
virtual void Vftable_x2C();
FILL_VFTABLE(3)
FILL_VFTABLE(4)
FILL_VFTABLE(5)
virtual void Vftable_x60();
virtual void Vftable_x64();
virtual int get_attitude_towards(float &attitude, IObjRW const *other) const; // 0x68
virtual void Vftable_x6C();
virtual void Vftable_x70();
virtual int get_target(const IObjRW *&target) const; // 0x74
virtual void Vftable_x78();
virtual void Vftable_x7C();
FILL_VFTABLE(8)
FILL_VFTABLE(9)
FILL_VFTABLE(A)
virtual void Vftable_xB0();
virtual void Vftable_xB4();
virtual void Vftable_xB8();
virtual bool is_player() const; // 0xBC
inline bool SentTradeRequest() const
{
#define TRADE_REQUEST_FLAGS 0x4
return (flags & TRADE_REQUEST_FLAGS) != 0;
}
};
struct IObjInspect : public IObjRW
{
};
struct PhysicsInfo
{
BYTE x00[0x2F];
bool autoLevel; // 0x2F
};
class IBehaviorManager
{
public:
BYTE x00[0x08];
PhysicsInfo* physicsInfo; // 0x08
BYTE x0C[0xED];
bool rotationLock; // 0xF9
};
IMPORT IBehaviorManager* GetBehaviorManager(IObjRW *iObjRw);
struct ID_String
{
UINT ids;
};
IMPORT bool SinglePlayer();
IMPORT bool IsMPServer();
namespace Reputation
{
namespace Vibe
{
IMPORT int GetInfocard(int const& id, unsigned int& idsInfo);
}
}
struct EquipDesc
{
DWORD x00;
UINT archId; // 0x4
};
class EquipDescList
{
public:
#ifdef USE_ST6
st6
#else
std
#endif
::list<EquipDesc> list; // 0x0
};
enum GoodType : DWORD
{
Commodity = 0,
Hull = 2,
Ship = 3
};
struct GoodInfo
{
BYTE x00[0x4C];
GoodType type; // 0x4C
BYTE x50[0x4];
UINT shipId; // only if type = Hull, 0x54
BYTE x58[0x38];
UINT shipHullId; // only if type = Ship, 0x90
EquipDescList equipDescLists[3]; // 0x94
};
namespace GoodList
{
IMPORT GoodInfo const * find_by_id(UINT id);
};
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#define IMPORT __declspec(dllimport)
class CGunWrapper
{
public:
IMPORT static void __cdecl Shutdown();
};
class CDPClient
{
};
#define FL_CDP_CLIENT ((CDPClient*) 0x67E7BC)
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define IMPORT __declspec(dllimport)
enum DumpSeverity : DWORD
{
SEV_ERROR = 0x100001,
SEV_WARNING = 0x100002,
SEV_NOTICE = 0x100003
};
typedef int (*FDUMP_HANDLER)(DumpSeverity severity, LPCSTR fmt, ...);
extern "C"
{
#ifndef ASM_FDUMP
IMPORT FDUMP_HANDLER FDUMP;
#endif
IMPORT int DACOM_GetDllVersion(LPCSTR dllPath, UINT32& major, UINT32& minor, UINT32& build);
}
+178
View File
@@ -0,0 +1,178 @@
#pragma once
#include "Common.h"
#define PLAYER_SYSTEM *((PUINT) 0x673354)
#define CHECK_FOR_SYNC_CALL_ADDR 0x541602
#define PUSH_SHIP_POS_SYNC_CHECK_ADDR 0x5415FF
#define POST_INIT_DEALLOC_CALL_ADDR 0x54B8B9
#define OBJ_UPDATE_CALL_ADDR 0x54167C
#define WAYPOINT_CHECK_CALL_ADDR 0x4F4141
#define INIT_NN_ELEMENTS_CALL_ADDR 0x5D4A80
#define TEST_RESOLUTIONS_ADDR 0x4B2440
// The buffer length is denoted in WORDs.
#define FL_BUFFER_1 ((LPWSTR) 0x66DC60)
#define FL_BUFFER_2 ((LPWSTR) 0x66FC60)
#define FL_BUFFER_LEN *((PUINT) 0x6119F8)
#define FL_RESOURCES_HANDLE *((PDWORD) 0x67ECA8)
#define UNKNOWN_OBJECT_IDS 1191
#define WAYPOINT_IDS 1090
#define MISSION_WAYPOINT_IDS 1091
#define KNOW_VISIT_FLAG (1)
#define LAND_VISIT_FLAG (1 << 1)
#define COMMODITY_DEALER_VISIT_FLAG (1 << 2)
#define EQUIPMENT_DEALER_VISIT_FLAG (1 << 3)
#define SHIP_DEALER_VISIT_FLAG (1 << 4)
// Time elapsed since startup in miliseconds
#define FL_TIME_ELAPSED_MS (*(double*) 0x667D38)
// System time in miliseconds
#define TIMING_DELTA_TICK_COUNT (*(PDWORD) 0x667D14)
#define TIME_GET_TIME_VAL (*(PDWORD) 0x667D20)
struct Waypoint
{
Vector pos;
UINT system;
UINT target;
int waypointNumber;
};
struct NavMapObj
{
UINT type;
};
struct NeuroNetNavMap
{
NavMapObj* GetHighlightedObject_Hook(DWORD unk1, DWORD unk2);
NavMapObj* GetHighlightedObject(DWORD unk1, DWORD unk2);
};
struct AudioOption
{
UINT idsName;
UINT idsTooltip;
UINT defaultVolume;
DWORD x0C, x10, x14;
};
#define NN_PREFERENCES_NEW_DATA 0x98C
// 0x330 = current selected width
// 0x8b8 = current active width (int)
// 0x8cc = start of resolution array (10 * 4 * 3 bytes)
// 0x8d4 = start of resolution array + 0x8 (points to the bpp of the first element)
// 0x944 = array of 10 bytes that contains flags of whether the resolution index is supported (1 = supported, 0 = unsupported)
// 0x94e = unallocated word (2 bytes)
// 0x950 = amount of supported resolutions (integer)
// 0x954 = array of 4 * 10 bytes that contains the indices of the resolutions in the selection menu (-1 is unsupported resolution)
struct NN_Preferences
{
BYTE x00[0x528];
AudioOption* audioOptions; // pointer to array of audio info from up to 14 UI scroll elements
BYTE x52C[0x128];
PVOID scrollElements[14]; // 0x654, array of pointers to 14 volume scroll elements (there's more but we only need up to 14)
BYTE x68C[0x2C4];
UINT supportedResAmount;
BYTE x954[0x28];
bool unk_x97C;
BYTE x97D[0x3];
UINT selectedHeight;
UINT activeHeight;
bool* resSupportedArr; // Points to new version of 0x944
BYTE newData;
bool InitElements_Hook(DWORD unk1, DWORD unk2);
bool SetResolution_Active_Hook(UINT width, DWORD unk);
bool SetResolution_Selected_Hook(UINT width, DWORD unk);
void TestResolutions_Hook(DWORD unk);
void VolumeSliderAdjustEnd_Hook(PVOID scrollElement);
bool SetResolution(UINT width, DWORD unk, UINT height);
};
void StopSound(BYTE soundId);
void StartSound(BYTE soundId);
Waypoint* GetWaypoint(int index);
struct WaypointWatcher
{
bool GetCurrentWaypointInfo(bool& isPlayerWaypoint, int& waypointIndex);
};
#define WAYPOINT_WATCHER (*((WaypointWatcher**) 0x674BC8))
IObjRW* GetPlayerIObjRW();
CShip* GetPlayerShip();
CShip* GetPlayerShipSafe();
bool AreIObjRWsInSameGroup(const IObjRW& o1, const IObjRW& o2);
bool AreShipsInSameGroup(const CShip* ship1, const CShip* ship2);
bool IsSimpleUnvisited(const CSimple& simple);
BYTE GetSimpleVisitedValue(const CSimple& simple);
UINT GetIdsForUnvisitedSimple(const CSimple& simple);
UINT GetCShipOrCEqObjName(const CEqObj &eqObj);
UINT GetFlStringFromResources(DWORD resourcesHandle, UINT ids, LPWSTR buffer, UINT bufferLen);
inline UINT GetFlString(UINT ids, LPWSTR buffer, UINT bufferLen)
{
return GetFlStringFromResources(FL_RESOURCES_HANDLE, ids, buffer, bufferLen);
}
class RenderDisplayList
{};
void AppendXmlWsToRdlEx(LPCWSTR ws, UINT wsLen, RenderDisplayList& rdl, DWORD flags);
inline void AppendXmlWsToRdl(LPCWSTR ws, RenderDisplayList& rdl)
{
AppendXmlWsToRdlEx(ws, wcslen(ws), rdl, 0);
}
#define SHIP_TRADER_SHIP_AMOUNT 3
#define SHIP_TRADER_PLAYER_SHIP_INDEX -2
#define SHIP_TRADER_NONE_SELECTED_INDEX -1
// 0x370 = ShipTrader3DShip*
struct NN_ShipTrader
{
BYTE x00[0x3CC];
int shipCount; // 0x3CC
int selectedShipIndex; // 0x3D0
BYTE x3D4[0x24];
float playerReputationWithBaseOwners; // 0x3F8
int shipStatuses[SHIP_TRADER_SHIP_AMOUNT]; // 0x3FC, basically enums for available, rep too low, or level too low
BYTE x408[0x40];
int shipRepPercentages[SHIP_TRADER_SHIP_AMOUNT]; // 0x448
void StoreShipRepRequirement(int shipIndex, float repRequirement);
LPWSTR PrintFmtShipRepRequirement();
PBYTE SwapShipRepPercentages(PBYTE rhsShipStatusAddr);
};
void ExpandNNShipTraderObjMemory();
struct FLCursor
{
float xPos, yPos, distFromZero;
};
struct ServerFilterDialog
{
bool OnFrameUpdate_Hook();
};
double GetDeltaTime();
void UpdateDeltaTime();
void UpdateDeltaTimeAndUpTime();
UINT GetNumOfActiveMissionObjectives();
+31
View File
@@ -0,0 +1,31 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "vftable.h"
struct SSPObjUpdateInfo
{
BYTE x00[40];
float throttle; // 0x28
};
class IServerImpl {
public:
FILL_VFTABLE(0)
FILL_VFTABLE(1)
FILL_VFTABLE(2)
FILL_VFTABLE(3)
FILL_VFTABLE(4)
FILL_VFTABLE(5)
FILL_VFTABLE(6)
FILL_VFTABLE(7)
FILL_VFTABLE(8)
FILL_VFTABLE(9)
FILL_VFTABLE(A)
FILL_VFTABLE(B)
FILL_VFTABLE(C)
virtual void SPObjUpdate(SSPObjUpdateInfo &updateInfo, UINT client);
void SPObjUpdate_Hook(const CShip& ship, SSPObjUpdateInfo &updateInfo, UINT client);
};
+15
View File
@@ -0,0 +1,15 @@
#pragma once
struct Alchemy
{
float progress;
void* effect;
};
struct AleLoop
{
int startOffset;
unsigned char maxProgressOffset;
};
void InitAlchemyCrashFix();
+10
View File
@@ -0,0 +1,10 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
struct BaseInfoCat
{
DWORD headerStyleAddr;
DWORD headerNamePrintAddr;
};
void InitBaseInfoSpacingFix();
+3
View File
@@ -0,0 +1,3 @@
#pragma once
void InitBlankFactionNameFix();
+72
View File
@@ -0,0 +1,72 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#ifdef USE_ST6
#include "st6.h"
#else
#include <list>
namespace st6 = std;
#endif
#define FASTCALL __fastcall
struct PlayerData
{
BYTE x00[0x264];
UINT currentShipId; // 0x264
BYTE x268[0xBC];
UINT shipIdOnLand; // 0x324
};
struct BaseGood
{
BYTE x00[0x8];
UINT goodId; // 0x8
float price; // 0xC
int minQuantity; // 0x10
int maxQuantity; // 0x14
DWORD unk_x18; // 0x18
inline bool IsShipCandidate() const
{
return unk_x18 == 0 || unk_x18 == 2;
}
};
struct BaseGoodIt
{
BaseGood* good; // 0x0
void Advance();
};
struct BaseGoodCollection
{
UINT baseName; // 0x0
UINT launchpadName; // 0x4
DWORD unk_x08; // 0x8
float unk_x0C; // 0xC
st6::list<BaseGood> goods; // 0x10
bool HasShipPackageWithGood(UINT goodId);
};
struct MarketGood
{
BYTE x00[0x10];
DWORD type; // 0x10
};
struct BaseMarket
{
UINT baseName; // 0x0
BaseGoodCollection* baseGoods; // 0x4
const MarketGood* GetSoldGood(UINT goodId) const;
};
const MarketGood* FASTCALL GetGoodSoldByBaseOrPartOfShip(const BaseMarket &baseMarket, const PlayerData &playerData, UINT goodId);
void InitShipBuyKickFix();
+7
View File
@@ -0,0 +1,7 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "feature_config.h"
void ReadConfig(LPCSTR path, FeatureManager &manager);
+72
View File
@@ -0,0 +1,72 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "vftable.h"
#include "Common.h"
#ifdef USE_ST6
#include "st6.h"
#else
#include <vector>
namespace st6 = std;
#endif
struct InputChar
{
WCHAR c;
DWORD flags; // I don't know whether this field actually represents flags; it's just an educated guess.
DWORD unk; // Allocated but never assigned.
};
struct KeyMapInfo
{
BYTE x00[0x8];
DWORD controlCharacterFlags; // 0x8
DWORD x0C;
WCHAR enteredKey; // 0x10
inline bool IsCtrlPressed() const
{
return (controlCharacterFlags & 4) == 4;
}
};
struct InputBoxWindow
{
BYTE x04[0x498];
int pos; // 0x49C
BYTE x4A0[0x24];
st6::vector<InputChar> chars; // 0x4C4
BYTE x4D4[0x3C];
int maxCharsLength; // 0x510
BYTE x514[0x14];
WCHAR forbiddenChar; // 0x528
bool noForbiddenChar; // 0x52A
PDWORD ime; // 0x52C
FILL_VFTABLE(0)
FILL_VFTABLE(1)
FILL_VFTABLE(2)
FILL_VFTABLE(3)
FILL_VFTABLE(4)
FILL_VFTABLE(5)
FILL_VFTABLE(6)
FILL_VFTABLE(7)
FILL_VFTABLE(8)
FILL_VFTABLE(9)
FILL_VFTABLE(A)
FILL_VFTABLE(B)
virtual void Vftable_xC0();
virtual void Vftable_xC4();
virtual bool WriteTypedKey(const KeyMapInfo& kmi);
void HandleCopyPaste(const KeyMapInfo& kmi);
void CopyToClipboard();
void CopyFromClipboard();
void WriteString(LPCWSTR str);
};
void HandleDefaultInputKey_Hook();
void InitCopyPasteFeature();
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "Common.h"
// Read from the [Cursor] values in DATA\mouse.ini.
// Constructor: 0x41E550
struct MouseCursor
{
UINT32 nicknameLen; // 0x0
char nickname[32]; // 0x4
PDWORD unk_0x24; // 0x24
UINT32 animNameLen; // 0x28
char animName[24]; // 0x2C
float hotspotX; // 0x44
float hotspotY; // 0x48
DWORD color; // rgba, 0x4C
BYTE x50[0x10];
int animValue1; // 0x60
int animState; // should be preserved when copying, 0x64
BYTE x68[0x28];
};
struct Targetable_Objects
{
BYTE x00[0x3F0];
const CSimple* selectedSimple; // 0x3F0
BYTE x3F4[0x534];
bool isAimLocking; // 0x928
void UpdateTargeting_Hook();
void UpdateTargeting();
};
void InitMoreCursorColors();
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define UI_ELEMENT_VISIBLE 0x3
struct ManeuverFrame
{
BYTE x00[0x6C];
BYTE flags; // 0x6C
};
struct NavBar
{
BYTE x00[0x3D8];
ManeuverFrame* maneuverFrame; // 0x3D8
BYTE x3DC[0x4];
PVOID unkUiElement; // 0x3E0
bool shipDealerMenuOpened; // 0x3E4
void SetHotspot_Hook(PVOID hotspot);
};
struct DealerOpenCamera
{
BYTE x00[0x1338];
bool animationInProgress; // 0x1338
bool StartAnimation(LPCSTR name, PVOID unk, NavBar* navBar, DWORD unk2);
bool StartAnimation_Hook(LPCSTR name, PVOID unk, NavBar* navBar, DWORD unk2);
};
void InitDealerOpenFix();
void InitDealerCrashFix();
+3
View File
@@ -0,0 +1,3 @@
#pragma once
void InitMissingDllCrashFix();
+6
View File
@@ -0,0 +1,6 @@
#pragma once
void InitPostGameDeadlockFix();
void InitQuitMessageFix();
void CleanupQuitMessageFix();
+30
View File
@@ -0,0 +1,30 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string.h>
#include <map>
struct FlSharpFeature
{
void (*initFunc)(); // feature's init function
void (*cleanupFunc)(); // feature's cleanup function
bool (*applyPredicate)(); // function that determines whether the feature must be applied from a technical perspective
bool enabled; // value determined by the user so they can choose whether they want it to be applied
};
class FeatureManager
{
public:
void RegisterFeature(LPCSTR name, void (*initFunc)(), void (*cleanupFunc)(), bool (*applyPredicate)());
bool SetFeatureEnabled(LPCSTR name, bool enabled);
void InitFeatures();
void CleanupFeatures();
private:
std::map<UINT, FlSharpFeature> features;
};
bool ApplyAlways();
bool ApplyOnlyOnClient();
bool ApplyOnlyOnServer();
+11
View File
@@ -0,0 +1,11 @@
#pragma once
#define NAKED __declspec(naked)
#define NOINLINE __declspec(noinline)
#define FL_FUNC(func, addr) \
NAKED NOINLINE func \
{ \
__asm mov eax, addr \
__asm jmp eax \
}
+35
View File
@@ -0,0 +1,35 @@
#pragma once
// NOTE: This only works when loaded via Freelancer.exe, not FLServer.exe.
#define FL_180_OVER_PI (*(float*) 0x5D3D38)
class Vector
{
public:
float x, y, z;
};
class Quaternion
{
public:
float w, x, y, z;
};
class Matrix
{
public:
float data[3][3];
};
float GetRotationDelta(const Quaternion& quat, const Matrix& rot);
Quaternion MatrixToQuaternion(const Matrix& m);
#ifdef _MSC_VER
#if _MSC_VER < 1700
inline float copysign(float x, float y)
{
return (x < 0 && y > 0) || (x > 0 && y < 0) ? -x : x;
}
#endif
#endif
+85
View File
@@ -0,0 +1,85 @@
#pragma once
#include "Common.h"
#include "utils.h"
void InitFlashParticlesFix();
struct EffectInstance
{
virtual void Vftable_x00();
virtual void FreeEngineEffect();
// Dealloc function which the game calls to clean up the effects when e.g. a ship or solar gets destroyed.
inline void EngineDealloc()
{
FreeEngineEffect();
FreeHeapMemory();
}
// Dealloc function which the game calls before creating a new flash effect instance for the same barrel/launcher.
inline void GeneralDealloc()
{
FreeAleEffect();
EngineDealloc();
}
// Dealloc function which the game calls right after quitting the play session.
inline void PostGameDealloc()
{
ResetBaseWatcher();
EngineDealloc();
}
inline void DoFreeHeapMemory()
{
FreeHeapMemory();
}
private:
struct WatcherInfo
{
float data[12];
};
void FreeAleEffect();
int FreeHeapMemory();
void SetBaseWatcher(int unk1, int unk2, const WatcherInfo& watcherInfo);
inline void ResetBaseWatcher()
{
WatcherInfo watcherInfo = { 0 };
watcherInfo.data[0] = watcherInfo.data[4] = watcherInfo.data[8] = 1.0f;
SetBaseWatcher(0, -1, watcherInfo);
}
};
EffectInstance** CreateFlashParticlesArray(UINT barrelAmount);
struct CliLauncher
{
DWORD vftable;
CELauncher* launcher; // 0x04
IObjRW* parent; // 0x08
BYTE x0C[0x1C];
// After playing the flash particle on a launcher, the effect instance is stored in 0x28.
// We need to keep track of more than one effect instance if the launcher has multiple barrels.
// Expanding the struct's memory is not feasible due to there existing many variations of this struct,
// which each have their own unique constructor and object size. Hence we dynamically manage this array at the same offset as currentFlashParticle.
union { // 0x28
EffectInstance* currentFlashParticle;
EffectInstance** flashParticlesArr;
};
void PlayAllFlashParticles(const ID_String& effectName);
// PlayFlashParticleForBarrel must be __cdecl because this code jumps to a vanilla FL function which does ret instead of ret n at the end.
// Therefore, the caller must clean the stack.
void __cdecl PlayFlashParticleForBarrel(const ID_String& effectName, UINT barrelIndex);
void CleanFlashParticlesPostGame_Hook();
void CleanFlashParticlesEngine_Hook();
void CleanFlashParticlesMemory_Hook();
void CleanFlashParticlesArr(void (EffectInstance::*deallocFunc)());
};
+15
View File
@@ -0,0 +1,15 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
enum AttitudeType : int
{
Hostile = -1,
Neutral = 0,
Friendly = 1
};
void InitHostileGroupFormation();
void InitHostileGroupMembersFix();
void InitGroupMemberAttitudeFix();
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <map>
struct InfocardEntry
{
std::map<UINT, UINT>& map;
LPCSTR key;
LPCSTR value;
};
void InitDynamicSolarInfocards();
+13
View File
@@ -0,0 +1,13 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
namespace Logger
{
void PrintModuleError(LPCSTR functionName, LPCSTR moduleName);
void PrintFileOpenError(LPCSTR functionName, LPCSTR filePath);
void PrintV10Warning(LPCSTR moduleName);
void PrintInvalidFeatureWarning(LPCSTR functionName, LPCSTR featureName, LPCSTR iniPath);
void PrintInvalidHeaderWarning(LPCSTR functionName, LPCSTR headerName, LPCSTR iniPath);
}
+28
View File
@@ -0,0 +1,28 @@
#pragma once
#include "vftable.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define STDCALL __stdcall
void InitCursorFix();
void InitMouseWarpFix();
// Redefining this because I don't want the project to depend on the DirectX SDK...
struct IDirectInputDevice8
{
FILL_VFTABLE(0)
virtual void Vftable_x10();
virtual void Vftable_x14();
virtual void Vftable_x18();
virtual long STDCALL Acquire(); // 0x1C
virtual long STDCALL Unacquire(); // 0x20
virtual void Vftable_x24();
virtual void Vftable_x28();
virtual void Vftable_x2C();
virtual void Vftable_x30();
virtual long STDCALL SetCooperativeLevel(HWND hwnd, DWORD flags); // 0x34
};
+17
View File
@@ -0,0 +1,17 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
struct StrBuffer
{
LPWSTR str;
size_t capacity;
};
enum NameType : DWORD
{
FactionAndDesignation = 0,
PilotName = 1,
Unk = 2
};
void InitPilotNamesFix();
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "Common.h"
void InitProjectilesSoundFix();
void InitProjectilesServerFix();
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
void InitPrintRepRequirements();
struct DealerStack
{
BYTE x00[0x24];
float repRequired;
};
struct NN_Dealer
{
void PrintFmtStrPurchaseInfo_Hook(UINT idsPurchaseInfo, const DealerStack& stack);
void PrintFmtStrPurchaseInfo(UINT idsPurchaseInfo, int fmtValue);
};
+70
View File
@@ -0,0 +1,70 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "Freelancer.h"
#define MIN_RES_WIDTH 800
#define MIN_RES_HEIGHT 600
#define NN_PREFERENCES_ALLOC_SIZE_PTR 0x4B296A
#define NN_PREFERENCES_ALLOC_SIZE 0x980
struct WidthHeight
{
UINT width, height;
bool Equals(const WidthHeight &other)
{
return memcmp(this, &other, sizeof(other)) == 0;
}
};
struct ResolutionInfo
{
ResolutionInfo(UINT width, UINT height, UINT bpp)
: width(width), height(height), bpp(bpp)
{}
// bpp = bits per pixel. FL appears to only support 16 and 32
UINT width, height, bpp;
// First sort by bpp, then width, then height, all in ascending order
bool operator < (const ResolutionInfo& other) const
{
if (bpp != other.bpp)
return bpp < other.bpp;
else if (width != other.width)
return width < other.width;
else
return height < other.height;
}
};
struct ResolutionInitInfo
{
BYTE x00[0x8];
ResolutionInfo resolutionInfo;
};
inline bool IsResolutionAllowed(const DEVMODE &dm)
{
return dm.dmPelsWidth >= MIN_RES_WIDTH && dm.dmPelsHeight >= MIN_RES_HEIGHT && (dm.dmBitsPerPel == 16 || dm.dmBitsPerPel == 32);
}
// Returns true if the given resolution is narrower than 4:3.
inline bool IsResolutionNarrow(UINT width, UINT height)
{
#define MIN_4_BY_3_FACTOR (4.0f / 3.0f) - 0.02f
if (height == 0)
return true;
return ((float) width / (float) height) < MIN_4_BY_3_FACTOR;
}
bool ResolutionInit(HWND windowHandle, ResolutionInitInfo& info, DWORD windowFlags);
void InitBetterResolutions();
void CleanupBetterResolutions();
+23
View File
@@ -0,0 +1,23 @@
#pragma once
void CurrentResInfoWrite1();
void CurrentResInfoWrite2();
void CurrentResInfoWrite3();
void CurrentResInfoWrite4();
void CurrentResInfoWrite5();
void CurrentResInfoWrite6();
void CurrentResInfoWrite7();
void CurrentResInfoCheck1();
void CurrentResInfoCheck2();
void CurrentResInfoCheck3();
void CurrentResInfoCheck4();
void CurrentResInfoCheck5();
void CurrentResInfoCheck6();
void CurrentResInfoCheck7();
void DefaultResSet1();
void DefaultResSet2();
void SetMainResWidth(int value);
void SetMainResHeight(int value);
+3
View File
@@ -0,0 +1,3 @@
#pragma once
void InitSaveCrashFix();
+4
View File
@@ -0,0 +1,4 @@
#pragma once
void InitServerFilterCrashFix();
void InitServerFilterSpeedFix();
+3
View File
@@ -0,0 +1,3 @@
#pragma once
void InitShieldCapacityFix();
+190
View File
@@ -0,0 +1,190 @@
#pragma once
#include <cstddef>
#include <stdexcept>
#include <iterator>
#ifndef _POINTER_X
#define _POINTER_X(T, A) T*
#endif
#ifndef _REFERENCE_X
#define _REFERENCE_X(T, A) T&
#endif
namespace st6
{
template<class _Ty>
class allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _Ty* pointer;
typedef const _Ty* const_pointer;
typedef _Ty& reference;
typedef const _Ty& const_reference;
typedef _Ty value_type;
pointer address(reference _X) const { return (&_X); }
const_pointer address(const_reference _X) const { return (&_X); }
void construct(pointer _P, const _Ty& _V) { _Construct(_P, _V); }
void destroy(pointer _P) { _Destroy(_P); }
size_t max_size() const
{
size_t _N = (size_t)(-1) / sizeof(_Ty);
return (0 < _N ? _N : 1);
}
};
template<class _Ty, class _A = allocator<_Ty>>
class vector
{
public:
typedef vector<_Ty, _A> _Myt;
typedef _A allocator_type;
typedef typename _A::size_type size_type;
typedef typename _A::difference_type difference_type;
typedef typename _A::pointer _Tptr;
typedef typename _A::const_pointer _Ctptr;
typedef typename _A::reference reference;
typedef typename _A::const_reference const_reference;
typedef typename _A::value_type value_type;
typedef _Tptr iterator;
typedef _Ctptr const_iterator;
iterator begin() { return (_First); }
const_iterator begin() const { return ((const_iterator)_First); }
iterator end() { return (_Last); }
const_iterator end() const { return ((const_iterator)_Last); }
size_type size() const { return (_First == 0 ? 0 : _Last - _First); }
bool empty() const { return (size() == 0); }
const_reference operator[](size_type _P) const { return (*(begin() + _P)); }
reference operator[](size_type _P) { return (*(begin() + _P)); }
protected:
_A allocator;
iterator _First, _Last, _End;
};
template <class _Ty, class _A = allocator<_Ty>>
class list
{
protected:
struct _Node;
friend struct _Node;
typedef _POINTER_X(_Node, _A) _Nodeptr;
struct _Node
{
_Nodeptr _Next, _Prev;
_Ty _Value;
};
struct _Acc;
friend struct _Acc;
struct _Acc
{
typedef _REFERENCE_X(_Nodeptr, _A) _Nodepref;
typedef typename _A::reference _Vref;
static _Nodepref _Next(_Nodeptr _P) { return ((_Nodepref)(*_P)._Next); }
static _Nodepref _Prev(_Nodeptr _P) { return ((_Nodepref)(*_P)._Prev); }
static _Vref _Value(_Nodeptr _P) { return ((_Vref)(*_P)._Value); }
};
public:
typedef list<_Ty, _A> _Myt;
typedef _A allocator_type;
typedef typename _A::size_type size_type;
typedef typename _A::difference_type difference_type;
typedef typename _A::pointer _Tptr;
typedef typename _A::const_pointer _Ctptr;
typedef typename _A::reference reference;
typedef typename _A::const_reference const_reference;
typedef typename _A::value_type value_type;
// CLASS const_iterator
class iterator;
class const_iterator;
friend class const_iterator;
class const_iterator
{
public:
const_iterator() {}
const_iterator(_Nodeptr _P) : _Ptr(_P) {}
const_iterator(const iterator& _X) : _Ptr(_X._Ptr) {}
const_reference operator*() const { return (_Acc::_Value(_Ptr)); }
_Ctptr operator->() const { return (&**this); }
const_iterator& operator++()
{
_Ptr = _Acc::_Next(_Ptr);
return (*this);
}
const_iterator operator++(int)
{
const_iterator _Tmp = *this;
++*this;
return (_Tmp);
}
const_iterator& operator--()
{
_Ptr = _Acc::_Prev(_Ptr);
return (*this);
}
const_iterator operator--(int)
{
const_iterator _Tmp = *this;
--*this;
return (_Tmp);
}
bool operator==(const const_iterator& _X) const { return (_Ptr == _X._Ptr); }
bool operator!=(const const_iterator& _X) const { return (!(*this == _X)); }
_Nodeptr _Mynode() const { return (_Ptr); }
protected:
_Nodeptr _Ptr;
};
// CLASS iterator
friend class iterator;
class iterator : public const_iterator
{
public:
iterator() {}
iterator(_Nodeptr _P) : const_iterator(_P) {}
reference operator*() const { return (_Acc::_Value(this->_Ptr)); }
_Tptr operator->() const { return (&**this); }
iterator& operator++()
{
this->_Ptr = _Acc::_Next(this->_Ptr);
return (*this);
}
iterator operator++(int)
{
iterator _Tmp = *this;
++*this;
return (_Tmp);
}
iterator& operator--()
{
this->_Ptr = _Acc::_Prev(this->_Ptr);
return (*this);
}
iterator operator--(int)
{
iterator _Tmp = *this;
--*this;
return (_Tmp);
}
bool operator==(const iterator& _X) const { return (this->_Ptr == _X._Ptr); }
bool operator!=(const iterator& _X) const { return (!(*this == _X)); }
};
iterator begin() { return (iterator(_Acc::_Next(_Head))); }
const_iterator begin() const { return (const_iterator(_Acc::_Next(_Head))); }
iterator end() { return (iterator(_Head)); }
const_iterator end() const { return (const_iterator(_Head)); }
_A allocator;
_Nodeptr _Head;
size_type _Size;
};
}
+3
View File
@@ -0,0 +1,3 @@
#pragma once
void InitFlightControlsFix();
+67
View File
@@ -0,0 +1,67 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "vftable.h"
#include "Common.h"
struct SoundHandle
{
BYTE data_x04[0x2C];
int unkBytePtr; // I don't know anything about this value (besides it being a pointer to some byte), but it gets nulled when the music stops playing.
inline bool FinishedPlaying()
{
return unkBytePtr == NULL || unkBytePtr == -1;
}
void ForcePause();
void ForceResume();
virtual void Vftable_x00();
virtual void Vftable_x04();
virtual DWORD __stdcall FreeReference();
virtual void Vftable_x0C();
FILL_VFTABLE(1)
FILL_VFTABLE(2)
FILL_VFTABLE(3)
FILL_VFTABLE(4)
FILL_VFTABLE(5)
virtual void Vftable_x60();
virtual void Vftable_x64();
virtual void Pause();
virtual void Resume();
virtual bool IsPaused();
};
struct TestSound
{
UINT idsName;
BYTE soundId;
};
struct FlSound
{
DWORD vftable;
UINT id;
LPCSTR filePath;
int unk_x0C;
float unk_x10;
float unk_x14;
};
FlSound* GetSound(const ID_String& ids);
bool GetBackgroundMusicHandle(SoundHandle **pHandle);
bool GetBackgroundAmbienceHandle(SoundHandle **pHandle);
bool GetBackgroundMusicHandle_Hook(SoundHandle **handle);
void StopMusicTestSound_Hook(BYTE soundId);
void InitTestSounds();
typedef bool (*GetSoundHandleFunc)(SoundHandle **pHandle);
void PauseSound(bool &shouldResume, GetSoundHandleFunc getHandle, bool force = false);
void ResumeSound(bool &shouldResume, GetSoundHandleFunc getHandle, bool force = false);
+21
View File
@@ -0,0 +1,21 @@
#pragma once
#include "Common.h"
struct CETradeLaneEquip
{
DWORD vftable;
CSolar* solar;
};
struct TradeLaneEquipObj
{
DWORD vftable;
CETradeLaneEquip* tradeLaneEquip;
BYTE x08[0x28];
BOOL isDisrupted;
void SetLightsState_Hook();
};
void InitTradeLaneLightsFix();
+42
View File
@@ -0,0 +1,42 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "vftable.h"
#include "Common.h"
struct BigImage
{
virtual void Vftable_x00();
virtual void Vftable_x04();
virtual DWORD __stdcall Destroy();
};
struct UITextMsgButton
{
public:
int UpdatePosition_Hook(BYTE unk1, const Vector* newPosOffset, BYTE unk2);
FILL_VFTABLE(0)
FILL_VFTABLE(1)
FILL_VFTABLE(2)
FILL_VFTABLE(3)
FILL_VFTABLE(4)
FILL_VFTABLE(5)
FILL_VFTABLE(6)
FILL_VFTABLE(7)
FILL_VFTABLE(8)
FILL_VFTABLE(9)
virtual void Vftable_xA0();
virtual void Vftable_xA4();
// UpdatePosition is actually Transform and unk1 is the transform type, with 6 = UPDATE_POS.
// Thus the function actually has more purposes than just updating the position.
virtual int UpdatePosition(BYTE unk1, const Vector* newPosOffset, BYTE unk2);
BYTE x04[0x3E8];
BigImage* textImage; // 0x3EC. textImage = nullptr will prevent the text from rendering
BYTE x3F0[0x81];
bool disableHovering; // 0x471
};
void InitSlideUiAnimFix();
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include "Common.h"
#include "RemoteServer.h"
void ResetTimeSinceLastUpdate();
void InitBetterUpdates();
+108
View File
@@ -0,0 +1,108 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <cassert>
#include <initializer_list>
void Patch(DWORD vOffset, const LPVOID mem, UINT len);
template <typename Type>
inline void Patch(DWORD vOffset, Type value)
{
Patch(vOffset, &value, sizeof(Type));
}
void PatchBytes(DWORD vOffset, std::initializer_list<BYTE> bytes);
void Nop(DWORD vOffset, UINT len);
inline void ReadWriteProtect(DWORD location, DWORD size)
{
DWORD _;
VirtualProtect((PVOID) location, size, PAGE_EXECUTE_READWRITE, &_);
}
template <typename Func>
Func SetRelPointer(DWORD location, Func hookFunc)
{
// Set and calculate the relative offset for the hook function
DWORD& relOriginalLocation = GetValue<DWORD>(location);
DWORD originalPointer = location + relOriginalLocation + 4;
DWORD hookFuncLocation = *((PDWORD) &hookFunc);
relOriginalLocation = hookFuncLocation - (location + 4);
return GetFuncDef<Func>(originalPointer);
}
template <typename Func>
void Hook(DWORD location, Func hookFunc, UINT instrLen, bool jmp = false)
{
assert(instrLen >= 5);
// Set the opcode for the call or jmp instruction
Patch<BYTE>(location, jmp ? 0xE9 : 0xE8); // 0xE9 = jmp, 0xE8 = call
// Set the relative address
SetRelPointer(location + 1, hookFunc);
// Nop out excess bytes
if (instrLen > 5)
Nop(location + 5, instrLen - 5);
}
template <typename Func>
Func Trampoline(DWORD location, Func hookFunc, UINT instrLen)
{
// Allocate memory for gateway function.
PBYTE gatewayFunc = (PBYTE) VirtualAlloc(nullptr, instrLen + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
// Copy the instruction(s) that will be overwritten by setting the hooks to the gateway code.
ReadWriteProtect(location, instrLen);
memcpy(gatewayFunc, (PVOID) location, instrLen);
// Jmp from location to hook function.
Hook(location, hookFunc, instrLen, true);
// Jmp from gateway to original function.
Hook((DWORD) (gatewayFunc + instrLen), GetFuncDef<Func>(location + instrLen), 5, true);
// Return handle for calling the gateway function which in turn calls the original function.
return GetFuncDef<Func>((DWORD) gatewayFunc);
}
template <typename Func>
void CleanupTrampoline(Func trampolineFunc)
{
VirtualFree((LPVOID) *((PDWORD) &trampolineFunc), 0, MEM_RELEASE);
}
template <typename Func>
Func SetPointer(DWORD location, Func hookFunc)
{
DWORD originalPointer = GetValue<DWORD>(location);
*(Func*) location = hookFunc;
return GetFuncDef<Func>(originalPointer);
}
template <typename Type>
inline Type& GetValue(DWORD location)
{
ReadWriteProtect(location, sizeof(Type));
return *(Type*) location;
}
template <class Func>
inline Func GetFuncDef(DWORD funcAddr)
{
return *(Func*) &funcAddr;
}
DWORD GetUnloadedModuleHandle(LPCTSTR moduleName);
struct NopStr
{
UINT len;
LPCSTR nopSequence;
};
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
UINT32 GetDllProductBuildVersion(LPCSTR dllName);
+7
View File
@@ -0,0 +1,7 @@
#pragma once
#define FILL_VFTABLE(tensPlace) \
virtual void Vftable_x ##tensPlace## 0(); \
virtual void Vftable_x ##tensPlace## 4(); \
virtual void Vftable_x ##tensPlace## 8(); \
virtual void Vftable_x ##tensPlace## C();
+3
View File
@@ -0,0 +1,3 @@
#pragma once
void InitWaypointFixes();
+12
View File
@@ -0,0 +1,12 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
struct MissionObjective
{
BYTE fmtStr[0x16]; // 0x0
DWORD flags; // 0x18
};
void InitWaypointNameFixes();
+39
View File
@@ -0,0 +1,39 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "Common.h"
#include "vftable.h"
enum EngModelType : DWORD
{
Object = 0,
Virtual = 2,
};
struct EngModel
{
EngModelType type; // 0x00
BYTE x04[0xC];
EngModel* parent; // 0x10
};
struct EngAnimation
{
// The first parameter seems to be a pointer to a stack-struct with the first three DWORDS set to 0 and then a ModelBinary*.
bool SetModel_Hook(PDWORD unk, const EngModel* model);
bool SetModel(PDWORD unk, const EngModel* model);
};
struct IAnimation2
{
FILL_VFTABLE(0);
FILL_VFTABLE(1);
virtual void Vftable_x20();
virtual int __stdcall Open(int scriptIndex, long engineInstance, LPCSTR animationScript, int unk1 = 0, int unk2 = 0);
int Open_Hook(LPCSTR animationScript, int scriptIndex, const CAttachedEquip& equip);
};
void InitWeaponAnimFix();