Skip to content

Commit

Permalink
Add LE3 SLH
Browse files Browse the repository at this point in the history
  • Loading branch information
Mgamerz committed Sep 12, 2021
1 parent 786eae7 commit 58eb10c
Show file tree
Hide file tree
Showing 7 changed files with 594 additions and 12 deletions.
12 changes: 6 additions & 6 deletions LE3-ASI-Plugins.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@ VisualStudioVersion = 16.0.31624.102
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LE3-SDK", "LE3-SDK\LE3-SDK.vcxproj", "{8DA34EDE-7D5C-4DA3-8841-78AB05E8C6D2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LE3StreamingLevelsHUD", "LE3StreamingLevelsHUD\LE3StreamingLevelsHUD.vcxproj", "{24261DB1-E217-4234-B048-1ACEA2F67237}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8DA34EDE-7D5C-4DA3-8841-78AB05E8C6D2}.Debug|x64.ActiveCfg = Debug|x64
{8DA34EDE-7D5C-4DA3-8841-78AB05E8C6D2}.Debug|x64.Build.0 = Debug|x64
{8DA34EDE-7D5C-4DA3-8841-78AB05E8C6D2}.Debug|x86.ActiveCfg = Debug|Win32
{8DA34EDE-7D5C-4DA3-8841-78AB05E8C6D2}.Debug|x86.Build.0 = Debug|Win32
{8DA34EDE-7D5C-4DA3-8841-78AB05E8C6D2}.Release|x64.ActiveCfg = Release|x64
{8DA34EDE-7D5C-4DA3-8841-78AB05E8C6D2}.Release|x64.Build.0 = Release|x64
{8DA34EDE-7D5C-4DA3-8841-78AB05E8C6D2}.Release|x86.ActiveCfg = Release|Win32
{8DA34EDE-7D5C-4DA3-8841-78AB05E8C6D2}.Release|x86.Build.0 = Release|Win32
{24261DB1-E217-4234-B048-1ACEA2F67237}.Debug|x64.ActiveCfg = Debug|x64
{24261DB1-E217-4234-B048-1ACEA2F67237}.Debug|x64.Build.0 = Debug|x64
{24261DB1-E217-4234-B048-1ACEA2F67237}.Release|x64.ActiveCfg = Release|x64
{24261DB1-E217-4234-B048-1ACEA2F67237}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
68 changes: 68 additions & 0 deletions LE3-SDK/Common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#pragma once
#include <windows.h>
#include <TlHelp32.h>

#include <cstdio>
#include <string>


typedef unsigned char byte;
typedef signed long int32;
typedef unsigned long uint32;
typedef signed long long int64;
typedef unsigned long long uint64;
typedef wchar_t wchar;


namespace Common
{
void OpenConsole()
{
AllocConsole();

freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
freopen_s((FILE**)stderr, "CONOUT$", "w", stderr);

HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo;
GetConsoleScreenBufferInfo(console, &lpConsoleScreenBufferInfo);
SetConsoleScreenBufferSize(console, { lpConsoleScreenBufferInfo.dwSize.X, 30000 });
}

void CloseConsole()
{
FreeConsole();
}

// loosely based on https://stackoverflow.com/q/26572459
byte* GetModuleBaseAddress(wchar* moduleName)
{
auto pid = GetCurrentProcessId();

HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
byte* baseAddress = nullptr;

if (INVALID_HANDLE_VALUE != snapshot)
{
MODULEENTRY32 moduleEntry = { 0 };
moduleEntry.dwSize = sizeof(MODULEENTRY32);

if (Module32First(snapshot, &moduleEntry))
{
do
{
if (0 == wcscmp(moduleEntry.szModule, moduleName))
{
baseAddress = moduleEntry.modBaseAddr;
break;
}
} while (Module32Next(snapshot, &moduleEntry));
}
CloseHandle(snapshot);
}

return baseAddress;
}
}

#define writeln(msg,...) fwprintf_s(stdout, L"LENE::" msg "\n", __VA_ARGS__)
169 changes: 169 additions & 0 deletions LE3-SDK/Interface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#pragma once


#pragma region Plugin-side utilities

/// Game versions for SpiSupportDecl.
/// Not convertible with LEGameVersion or SPIGameVersion!!!

#define SPI_GAME_LEL (1 << 0)
#define SPI_GAME_LE1 (1 << 1)
#define SPI_GAME_LE2 (1 << 2)
#define SPI_GAME_LE3 (1 << 3)


/// SPI version macros.
/// Duplicate the stuff in version.h!!!

#define SPI_VERSION_ANY 3
#define SPI_VERSION_LATEST 3

/// Plugin-side definition which marks the dll as supporting SPI.
#define SPI_PLUGINSIDE_SUPPORT(NAME,AUTHOR,VERSION,GAME_FLAGS,SPIMINVER) \
extern "C" __declspec(dllexport) void SpiSupportDecl(wchar_t** name, wchar_t** author, wchar_t** version, int* gameIndexFlags, int* spiMinVersion) \
{ *name = NAME; *author = AUTHOR; *version = VERSION; *gameIndexFlags = GAME_FLAGS; *spiMinVersion = SPIMINVER; }

/// Plugin-side definition which marks the dll for being loaded
/// at the earliest possible moment.
#define SPI_PLUGINSIDE_PRELOAD extern "C" __declspec(dllexport) bool SpiShouldPreload(void) { return true; }
/// Plugin-side definition which marks the dll for being loaded
/// only after DRM has finished decrypting the game.
#define SPI_PLUGINSIDE_POSTLOAD extern "C" __declspec(dllexport) bool SpiShouldPreload(void) { return false; }

/// Plugin-side definition which marks the dll for running
/// its attach point sequentially during game startup.
#define SPI_PLUGINSIDE_SEQATTACH extern "C" __declspec(dllexport) bool SpiShouldSpawnThread(void) { return false; }
/// Plugin-side definition which marks the dll for running
/// its attach point asynchronously during game startup.
#define SPI_PLUGINSIDE_ASYNCATTACH extern "C" __declspec(dllexport) bool SpiShouldSpawnThread(void) { return true; }

/// Plugin-side boilerplate macro for defining the plugin attach point.
/// This is run when the plugin is loaded by SPI (!), not when the DLL itself is loaded.
#define SPI_IMPLEMENT_ATTACH extern "C" __declspec(dllexport) bool SpiOnAttach(ISharedProxyInterface* InterfacePtr)
/// Plugin-side boilerplate macro for defining the plugin detach point.
/// This *should* run when the plugin is unloaded by SPI (!), not when the DLL itself is unloaded.
/// WARNING: DO NOT RELY ON THIS BEING RUN
#define SPI_IMPLEMENT_DETACH extern "C" __declspec(dllexport) bool SpiOnDetach(ISharedProxyInterface* InterfacePtr)

#pragma endregion


#pragma region Error codes

/// <summary>
/// Return value for all public SPI functions.
/// - 0 is illegal to return,
/// - 1 means success,
/// - [10; 100) mean failures,
/// - [100; ...) mean that normal operation is no longer possible.
/// </summary>
enum class SPIReturn : short
{
// Adding stuff here requires adding stuff to MakeReturnCodeText() !!!
Undefined = 0,
Success = 1,
FailureGeneric = 10,
FailureDuplicacy = 11,
FailureHooking = 12,
FailureInvalidParam = 13,
FailureUnsupportedYet = 14,
FailureDeprecated = 15,
FailurePatternInvalid = 16,
FailurePatternTooLong = 17,
ErrorFatal = 100,
ErrorWinApi = 115,
};

/// <summary>
/// Get a string describing an SPIReturn code.
/// </summary>
/// <returns>A const wide string</returns>
const wchar_t* SPIReturnToString(SPIReturn code)
{
switch (code)
{
case SPIReturn::Undefined: return L"Undefined - illegal return code";
case SPIReturn::Success: return L"Success - yay!";
case SPIReturn::FailureGeneric: return L"FailureGeneric - unspecified error";
case SPIReturn::FailureDuplicacy: return L"FailureDuplicacy - something unique was not unique, or something that should have existed didn't";
case SPIReturn::FailureHooking: return L"FailureHooking - injection code returned an error";
case SPIReturn::FailureInvalidParam: return L"FailureInvalidParam - illegal parameter passed to an SPI method";
case SPIReturn::FailureUnsupportedYet: return L"FailureUnsupportedYet - feature is defined in SPI but not yet provided";
case SPIReturn::FailureDeprecated: return L"FailureDeprecated - feature is defined in SPI but must not be used";
case SPIReturn::FailurePatternInvalid: return L"FailurePatternInvalid - provided pattern was ill-formed";
case SPIReturn::FailurePatternTooLong: return L"FailurePatternTooLong - provided pattern is too long";
case SPIReturn::ErrorFatal: return L"ErrorFatal - unspecified error AFTER WHICH EXECUTION CANNOT CONTINUE";
case SPIReturn::ErrorWinApi: return L"ErrorWinApi - a call to Win API function failed, check GetLastError()";
default: return L"UNRECOGNIZED RETURN CODE - CONTACT DEVELOPERS";
}
}

#pragma endregion


#pragma region The public-facing interface

#define SPIDECL [[nodiscard]] __declspec(noinline) virtual SPIReturn
#define SPIDEFN virtual SPIReturn

/// Game versions for GetHostGame.
/// Not interchangable with LEGameVersion!!!
enum class SPIGameVersion
{
Launcher = 0,
LE1 = 1,
LE2 = 2,
LE3 = 3
};

/// <summary>
/// SPI declaration for use in ASI mods.
/// </summary>
class ISharedProxyInterface
{
public:
/// <summary>
/// Get version of the SPI implementation provided by the host proxy.
/// </summary>
/// <param name="outVersionPtr">Output value for the version.</param>
/// <returns>An appropriate <see cref="SPIReturn"/> code.</returns>
SPIDECL GetVersion(unsigned long* outVersionPtr) = 0;
/// <summary>
/// Get if the host proxy was built in debug or release mode.
/// </summary>
/// <param name="outIsRelease">Output value for the build mode.</param>
/// <returns>An appropriate <see cref="SPIReturn"/> code.</returns>
SPIDECL GetBuildMode(bool* outIsRelease) = 0;
/// <summary>
/// Get the game this host proxy is attached to (1 - 3 or Launcher).
/// </summary>
/// <param name="outGameVersion">Output value for the game.</param>
/// <returns>An appropriate <see cref="SPIReturn"/> code.</returns>
SPIDECL GetHostGame(SPIGameVersion* outGameVersion) = 0;

/// <summary>
/// Search the main game module for a PEiD-style pattern.
/// </summary>
/// <param name="outOffsetPtr">Output value for the offset, set to NULL if not found.</param>
/// <param name="combinedPattern">PEiD-style pattern specifying 100 bytes (299 chars + \0) at most.</param>
/// <returns>An appropriate <see cref="SPIReturn"/> code.</returns>
SPIDECL FindPattern(void** outOffsetPtr, char* combinedPattern) = 0;

/// <summary>
/// Use bink proxy's built-in injection library to detour a procedure.
/// </summary>
/// <param name="name">Name of the hook used for logging purposes.</param>
/// <param name="target">Pointer to detour.</param>
/// <param name="detour">Pointer to what to detour the target with.</param>
/// <param name="original">Pointer to where to write out the original procedure.</param>
/// <returns>An appropriate <see cref="SPIReturn"/> code.</returns>
SPIDECL InstallHook(const char* name, void* target, void* detour, void** original) = 0;
/// <summary>
/// Remove a hook installed by <see cref="ISharedProxyInterface::InstallHook"/>.
/// </summary>
/// <param name="name">Name of the hook to remove.</param>
/// <returns>An appropriate <see cref="SPIReturn"/> code.</returns>
SPIDECL UninstallHook(const char* name) = 0;
};

#pragma endregion
19 changes: 13 additions & 6 deletions LE3-SDK/LE3-SDK.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,12 @@
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<ConformanceMode>false</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<LanguageStandard>stdcpp17</LanguageStandard>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>
Expand All @@ -196,9 +199,13 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<ConformanceMode>false</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<LanguageStandard>stdcpp17</LanguageStandard>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>
Expand Down
22 changes: 22 additions & 0 deletions LE3StreamingLevelsHUD/LE1StreamingLevelsHUD.vcxproj.filters
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="LE1StreamingLevelsHUD.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
Loading

0 comments on commit 58eb10c

Please sign in to comment.