diff --git a/L2Detect2.vcxproj b/L2Detect2.vcxproj
index 09d88ea..f9c1ac3 100644
--- a/L2Detect2.vcxproj
+++ b/L2Detect2.vcxproj
@@ -47,6 +47,8 @@
false
d3d9
d3d9
+ .;$(IncludePath)
+ .;$(IncludePath)
diff --git a/d3d9_proxy_loader.vcxproj b/d3d9_proxy_loader.vcxproj
new file mode 100644
index 0000000..49295b6
--- /dev/null
+++ b/d3d9_proxy_loader.vcxproj
@@ -0,0 +1,108 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {AD9D2AEC-9165-4DF6-B3E3-9EED13CD81AB}
+ Win32Proj
+ d3d9_proxy_loader
+
+
+
+ DynamicLibrary
+ true
+ Unicode
+
+
+ DynamicLibrary
+ false
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ d3d9
+ _build\d3d9_proxy_loader_Debug\
+ _build\d3d9_proxy_loader_Debug\
+ .\d3d9_proxy_loader;$(IncludePath)
+
+
+ false
+ d3d9
+ _build\d3d9_proxy_loader_Release\
+ _build\d3d9_proxy_loader_Release\
+ .\d3d9_proxy_loader;$(IncludePath)
+
+
+
+
+
+ Level4
+ Disabled
+ WIN32;_DEBUG;_WINDOWS;_USRDLL;D3D9_PROXY_LOADER_EXPORTS;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+ Windows
+ true
+ d3d9.lib;%(AdditionalDependencies)
+ .\d3d9_proxy_loader\proxydll.def
+
+
+
+
+ Level4
+ Use
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_WINDOWS;_USRDLL;D3D9_PROXY_LOADER_EXPORTS;%(PreprocessorDefinitions)
+ MultiThreaded
+ pch.h
+
+
+ Windows
+ true
+ true
+ true
+ d3d9.lib;%(AdditionalDependencies)
+ .\d3d9_proxy_loader\proxydll.def
+
+
+
+
+
+
+ Create
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/d3d9_proxy_loader.vcxproj.filters b/d3d9_proxy_loader.vcxproj.filters
new file mode 100644
index 0000000..e7379ee
--- /dev/null
+++ b/d3d9_proxy_loader.vcxproj.filters
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+ logger
+
+
+
+
+
+ logger
+
+
+
+
+
+
+
+
+ {6e4bccdb-ba9d-4a27-8866-bbded29f1eb0}
+
+
+
\ No newline at end of file
diff --git a/d3d9_proxy_loader/DllMain.cpp b/d3d9_proxy_loader/DllMain.cpp
new file mode 100644
index 0000000..2e99d86
--- /dev/null
+++ b/d3d9_proxy_loader/DllMain.cpp
@@ -0,0 +1,159 @@
+#include "pch.h"
+#include "d3d9_proxy.h"
+
+// global variables
+#pragma data_seg (".d3d9_shared")
+HINSTANCE gl_hOriginalDll;
+HINSTANCE gl_hThisInstance;
+HINSTANCE gl_hL2Detect;
+#pragma data_seg ()
+
+FILE *g_fLog = NULL;
+
+
+BOOL WINAPI DllMain( HINSTANCE hInstDLL, DWORD reason, LPVOID lpvReserved )
+{
+ lpvReserved = NULL;
+ switch( reason )
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+ gl_hThisInstance = hInstDLL;
+ DisableThreadLibraryCalls( hInstDLL );
+ D3D9Proxy_Initialize();
+ } break;
+ case DLL_PROCESS_DETACH:
+ {
+ D3D9Proxy_Uninitialize();
+ } break;
+ }
+ return TRUE;
+}
+
+
+void D3D9Proxy_Initialize()
+{
+ // init Logger
+ ErrorLogger_Init();
+ ErrorLogger_Enable( true );
+#ifdef _DEBUG
+ ErrorLogger_EnableLoggingToConsole( true );
+#endif
+ g_fLog = fopen( "D3D9Proxy.log", "wt" );
+ ErrorLogger_SetLogFile( g_fLog );
+ ErrorLogger_SetAutoPrependErrorType( true );
+#ifdef _DEBUG
+ ErrorLogger_SetWarnMessageLevel( LOG_DEBUGDUMP );
+#else
+ ErrorLogger_SetWarnMessageLevel( LOG_WARNING );
+#endif
+ log_error( LOG_OK, "D3D9Proxy_Initialize() called.\n" );
+
+ // Initialisation
+ gl_hOriginalDll = NULL;
+ gl_hThisInstance = NULL;
+ gl_hL2Detect = NULL;
+}
+
+
+void D3D9Proxy_Uninitialize()
+{
+ log_error( LOG_OK, "D3D9Proxy_Uninitialize() called.\n" );
+
+ // Release the system's d3d9.dll
+ if( gl_hOriginalDll )
+ {
+ ::FreeLibrary( gl_hOriginalDll );
+ gl_hOriginalDll = NULL;
+ log_error( LOG_DEBUG, "gl_hOriginalDll (d3d9) unloaded.\n" );
+ }
+
+ // Release L2Detect DLL
+ if( gl_hL2Detect )
+ {
+ ::FreeLibrary( gl_hL2Detect );
+ gl_hL2Detect = NULL;
+ log_error( LOG_DEBUG, "gl_hL2Detect (L2Detect) unloaded.\n" );
+ }
+
+ // close logger
+ log_error( LOG_OK, "Closing log. Last message! Bye!\n=======================\n" );
+ ErrorLogger_FlushLogFile();
+ ErrorLogger_Enable( false );
+#ifdef _DEBUG
+ ErrorLogger_EnableLoggingToConsole( false );
+#endif
+ if( g_fLog )
+ {
+ ErrorLogger_SetLogFile( NULL );
+ fflush( g_fLog );
+ fclose( g_fLog );
+ g_fLog = NULL;
+ }
+}
+
+
+void D3D9Proxy_LoadL2Detect()
+{
+ if( gl_hL2Detect != NULL )
+ return;
+
+ gl_hL2Detect = LoadLibraryW( L"L2Detect_d.dll" );
+ if( gl_hL2Detect == NULL )
+ {
+ gl_hL2Detect = LoadLibraryW( L"L2Detect.dll" );
+ if( gl_hL2Detect == NULL )
+ log_error( LOG_ERROR, "Failed to load radar DLL! Tried to find L2Detect_d / L2Detect dlls.\n" );
+ else
+ log_error( LOG_OK, "Loaded L2Detect.dll at 0x%08X\n", gl_hL2Detect );
+ }
+ else
+ log_error( LOG_OK, "Loaded L2Detect_d.dll (debug version) at 0x%08X\n", gl_hL2Detect );
+}
+
+
+void LoadOriginalDll()
+{
+ wchar_t buffer[MAX_PATH];
+ buffer[0] = 0;
+ // Getting path to system dir and to d3d8.dll
+ ::GetSystemDirectory( buffer, MAX_PATH );
+ // Append dll name
+ wcscat( buffer, L"\\d3d9.dll" );
+ // try to load the system's d3d9.dll, if pointer empty
+ if( !gl_hOriginalDll ) gl_hOriginalDll = ::LoadLibrary( buffer );
+ // Debug
+ if( !gl_hOriginalDll )
+ {
+ log_error( LOG_ERROR, "LoadOriginalDll(): Original d3d9.dll not loaded!\n");
+ ErrorLogger_FlushLogFile();
+ ::ExitProcess(0);
+ }
+}
+
+
+// Exported function (faking d3d9.dll's one-and-only export)
+IDirect3D9* WINAPI Direct3DCreate9( UINT SDKVersion )
+{
+ if( !gl_hOriginalDll ) LoadOriginalDll(); // looking for the "right d3d9.dll"
+
+ // Hooking IDirect3D Object from Original Library
+ typedef IDirect3D9 *(WINAPI* D3D9_Type)(UINT SDKVersion);
+ D3D9_Type D3DCreate9_fn = (D3D9_Type)GetProcAddress( gl_hOriginalDll, "Direct3DCreate9" );
+
+ // Debug
+ if( !D3DCreate9_fn )
+ {
+ log_error( LOG_ERROR, "Direct3DCreate9(): Pointer to original Direct3DCreate9 function not received!\n" );
+ ErrorLogger_FlushLogFile();
+ ::ExitProcess(0); // exit the hard way
+ }
+
+ D3D9Proxy_LoadL2Detect();
+
+ // Request pointer from Original Dll.
+ IDirect3D9 *pIDirect3D9_orig = D3DCreate9_fn( SDKVersion );
+
+ // Return pointer to hooking Object instead of "real one"
+ return pIDirect3D9_orig;
+}
diff --git a/d3d9_proxy_loader/d3d9_proxy.h b/d3d9_proxy_loader/d3d9_proxy.h
new file mode 100644
index 0000000..60bd1de
--- /dev/null
+++ b/d3d9_proxy_loader/d3d9_proxy.h
@@ -0,0 +1,8 @@
+#pragma once
+
+extern HINSTANCE gl_hThisInstance;
+extern HINSTANCE gl_hOriginalDll;
+
+void D3D9Proxy_Initialize();
+void D3D9Proxy_Uninitialize();
+void D3D9Proxy_LoadL2Detect();
\ No newline at end of file
diff --git a/d3d9_proxy_loader/logger/Logger.cpp b/d3d9_proxy_loader/logger/Logger.cpp
new file mode 100644
index 0000000..46ba399
--- /dev/null
+++ b/d3d9_proxy_loader/logger/Logger.cpp
@@ -0,0 +1,195 @@
+#include "pch.h"
+#include "Logger.h"
+
+// global ErrorLogger vars
+bool g_error_logger_enabled;
+bool g_error_logger_enabled_console;
+FILE *g_error_logger_file;
+bool g_error_logger_auto_prepend;
+CRITICAL_SECTION g_error_logger_cs;
+HANDLE g_error_logger_stdout;
+// strings
+char g_error_logger_strtype_unknown[16];
+char g_error_logger_strtype[LOG_LEVELS][16];
+//
+LOG_LEVEL g_errorLogger_WarnMessageLevel;
+
+void ErrorLogger_InitStrings()
+{
+ strcpy( g_error_logger_strtype_unknown, "[??] " );
+ strcpy( g_error_logger_strtype[LOG_OK], "[++] " );
+ strcpy( g_error_logger_strtype[LOG_ERROR], "[--] " );
+ strcpy( g_error_logger_strtype[LOG_WARNING], "[WARN] " );
+ strcpy( g_error_logger_strtype[LOG_USERAI], "[AI] " );
+ strcpy( g_error_logger_strtype[LOG_PACKETNAME], "[PACK] " );
+ strcpy( g_error_logger_strtype[LOG_DEBUG], "[DBG] " );
+ strcpy( g_error_logger_strtype[LOG_DEBUGDUMP], "[DUMP] " );
+}
+
+void ErrorLogger_Init()
+{
+ g_error_logger_enabled = false;
+ g_error_logger_enabled_console = false;
+ g_error_logger_file = stdout;
+ g_error_logger_auto_prepend = false;
+ g_error_logger_stdout = INVALID_HANDLE_VALUE;
+ g_errorLogger_WarnMessageLevel = LOG_DEBUG;
+ InitializeCriticalSection( &g_error_logger_cs );
+ ErrorLogger_InitStrings();
+}
+
+void ErrorLogger_Enable( bool bEnable )
+{
+ g_error_logger_enabled = bEnable;
+}
+
+void ErrorLogger_SetWarnMessageLevel( LOG_LEVEL level )
+{
+ g_errorLogger_WarnMessageLevel = level;
+}
+
+void ErrorLogger_EnableLoggingToConsole( bool bEnable )
+{
+ EnterCriticalSection( &g_error_logger_cs );
+ if( bEnable )
+ {
+ if( g_error_logger_enabled_console == false ) AllocConsole();
+ g_error_logger_stdout = GetStdHandle( STD_OUTPUT_HANDLE );
+ }
+ else
+ {
+ g_error_logger_stdout = INVALID_HANDLE_VALUE;
+ if( g_error_logger_enabled_console == true ) FreeConsole();
+ }
+ g_error_logger_enabled_console = bEnable;
+ LeaveCriticalSection( &g_error_logger_cs );
+}
+
+void ErrorLogger_SetLogFile( FILE *f )
+{
+ EnterCriticalSection( &g_error_logger_cs );
+ if( !f ) g_error_logger_file = stdout; else g_error_logger_file = f;
+ LeaveCriticalSection( &g_error_logger_cs );
+}
+
+FILE *ErrorLogger_GetLogFile()
+{
+ return g_error_logger_file;
+}
+
+void ErrorLogger_FlushLogFile()
+{
+ EnterCriticalSection( &g_error_logger_cs );
+ if( g_error_logger_file ) fflush( g_error_logger_file );
+ LeaveCriticalSection( &g_error_logger_cs );
+}
+
+void ErrorLogger_SetAutoPrependErrorType( bool bPrepend )
+{
+ g_error_logger_auto_prepend = bPrepend;
+}
+
+int log_error( LOG_LEVEL logLevel, const char *_Format, ... )
+{
+ if( !g_error_logger_enabled ) return 0;
+ int ret = 0;
+ if( (logLevel < 0) || (!_Format) ) return 0;
+ if( logLevel > g_errorLogger_WarnMessageLevel ) return 0;
+ EnterCriticalSection( &g_error_logger_cs );
+ va_list l;
+ va_start( l, _Format );
+ if( g_error_logger_auto_prepend )
+ {
+ char *szPrepend = g_error_logger_strtype_unknown;
+ if( (logLevel >= LOG_OK) && (logLevel <= LOGLEVEL_LAST) )
+ szPrepend = g_error_logger_strtype[logLevel];
+ fprintf( g_error_logger_file, "%s", szPrepend );
+ // also write to console, if enabled
+ if( g_error_logger_enabled_console )
+ {
+ DWORD numWritten = 0;
+ WriteConsoleA( g_error_logger_stdout, szPrepend, (DWORD)strlen(szPrepend), &numWritten, NULL );
+ }
+ }
+ ret = vfprintf( g_error_logger_file, _Format, l );
+ // also write to console, if enabled
+ if( g_error_logger_enabled_console )
+ {
+ char *cbuffer = (char *)malloc( 20480 ); // 20 Kb >_<
+ if( cbuffer )
+ {
+ va_list l2;
+ va_start( l2, _Format );
+ vsprintf( cbuffer, _Format, l2 );
+ DWORD numWritten = 0;
+ WriteConsoleA( g_error_logger_stdout, cbuffer, (DWORD)strlen(cbuffer), &numWritten, NULL );
+ free( cbuffer );
+ }
+ }
+ LeaveCriticalSection( &g_error_logger_cs );
+ return ret;
+}
+
+// forces NO prepend even if set to
+int log_error_np( LOG_LEVEL logLevel, const char *_Format, ... )
+{
+ if( !g_error_logger_enabled ) return 0;
+ int ret = 0;
+ if( (logLevel < 0) || (!_Format) ) return 0;
+ if( logLevel > g_errorLogger_WarnMessageLevel ) return 0;
+ EnterCriticalSection( &g_error_logger_cs );
+ va_list l;
+ va_start( l, _Format );
+ // no prepend, just vfprintf
+ ret = vfprintf( g_error_logger_file, _Format, l );
+ // also write to console, if enabled?
+ if( g_error_logger_enabled_console )
+ {
+ char *cbuffer = (char *)malloc( 20480 );
+ if( cbuffer )
+ {
+ va_list l2;
+ va_start( l2, _Format );
+ vsprintf( cbuffer, _Format, l2 );
+ DWORD numWritten = 0;
+ WriteConsoleA( g_error_logger_stdout, cbuffer, (DWORD)strlen(cbuffer), &numWritten, NULL );
+ free( cbuffer );
+ }
+ }
+ LeaveCriticalSection( &g_error_logger_cs );
+ return ret;
+}
+
+//int log_console( LOG_LEVEL logLevel, const char *_Format, ... )
+//{
+// if( !g_error_logger_enabled_console ) return 0;
+//}
+//
+//int log_console_np( LOG_LEVEL logLevel, const char *_Format, ... )
+//{
+// if( !g_error_logger_enabled_console ) return 0;
+//}
+
+void ErrorLogger_FormatLastError( char *msg, size_t nMaxCount, DWORD error_code )
+{
+ FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, error_code, 0/*MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT)*/, msg, nMaxCount, NULL );
+}
+
+void ErrorLogger_LogLastError( char *comment, DWORD error_code )
+{
+ char errbuf[512];
+ errbuf[0] = 0;
+ ErrorLogger_FormatLastError( errbuf, 511, error_code );
+ errbuf[511] = 0;
+ size_t ll = strlen( errbuf );
+ if( ll > 0 )
+ {
+ if( errbuf[ll-1] == '\n' || errbuf[ll-1] == '\r' ) errbuf[ll-1] = 0;
+ if( ll > 1 )
+ {
+ if( errbuf[ll-2] == '\n' || errbuf[ll-2] == '\r' ) errbuf[ll-2] = 0;
+ }
+ }
+ log_error( LOG_ERROR, "%s: error code: %u (%s)\n", comment, (unsigned int)error_code, errbuf );
+}
diff --git a/d3d9_proxy_loader/logger/Logger.h b/d3d9_proxy_loader/logger/Logger.h
new file mode 100644
index 0000000..db4fdcd
--- /dev/null
+++ b/d3d9_proxy_loader/logger/Logger.h
@@ -0,0 +1,37 @@
+#ifndef FL_ERRORLOGGER_H_
+#define FL_ERRORLOGGER_H_
+
+typedef enum eLOG_LEVEL
+{
+ LOG_OK = 0,
+ LOG_ERROR, // 1
+ LOG_WARNING, // 2
+ LOG_USERAI, // 3
+ LOG_PACKETNAME, // 4
+ LOG_DEBUG, // 5
+ LOG_DEBUGDUMP, // 6
+ LOGLEVEL_LAST = LOG_DEBUGDUMP
+} LOG_LEVEL;
+
+#define LOG_LEVELS 7
+
+void ErrorLogger_Init();
+void ErrorLogger_Enable( bool bEnable );
+void ErrorLogger_EnableLoggingToConsole( bool bEnable );
+void ErrorLogger_SetLogFile( FILE *f );
+FILE *ErrorLogger_GetLogFile();
+void ErrorLogger_FlushLogFile();
+
+void ErrorLogger_SetWarnMessageLevel( LOG_LEVEL level );
+void ErrorLogger_SetAutoPrependErrorType( bool bPrepend );
+
+int log_error( LOG_LEVEL logLevel, const char *_Format, ... );
+int log_error_np( LOG_LEVEL logLevel, const char *_Format, ... ); // forces NO prepend even if set to
+
+//int log_console( LOG_LEVEL logLevel, const char *_Format, ... );
+//int log_console_np( LOG_LEVEL logLevel, const char *_Format, ... );
+
+void ErrorLogger_FormatLastError( char *msg, size_t nMaxCount, DWORD error_code );
+void ErrorLogger_LogLastError( char *comment, DWORD error_code );
+
+#endif /*FL_ERRORLOGGER_H_*/
diff --git a/d3d9_proxy_loader/pch.cpp b/d3d9_proxy_loader/pch.cpp
new file mode 100644
index 0000000..9e6b2e0
--- /dev/null
+++ b/d3d9_proxy_loader/pch.cpp
@@ -0,0 +1 @@
+#include "pch.h"
diff --git a/d3d9_proxy_loader/pch.h b/d3d9_proxy_loader/pch.h
new file mode 100644
index 0000000..59835b0
--- /dev/null
+++ b/d3d9_proxy_loader/pch.h
@@ -0,0 +1,35 @@
+#define WINVER 0x0501
+#define _WIN32_WINNT 0x0501
+#define _WIN32_IE 0x0600
+#define _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_DEPRECATE
+
+// C++ RTL
+#include
+#include
+#include
+#include
+#include
+
+// WinAPI
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+// STL
+#include
+#include