diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5bf437efd..c93067ffb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,9 +3,11 @@ on: push: branches: - master + - '[0-9]+.[0-9]+-dev' pull_request: branches: - master + - '[0-9]+.[0-9]+-dev' jobs: test: strategy: diff --git a/.gitignore b/.gitignore index c2f678d98..40ce744da 100644 --- a/.gitignore +++ b/.gitignore @@ -24,5 +24,6 @@ Release.*/ # AMBuild build directories build/ +build-*/ obj-*/ .gdb_history diff --git a/AMBuildScript b/AMBuildScript index c9e8cd50f..0c8441bbc 100644 --- a/AMBuildScript +++ b/AMBuildScript @@ -323,7 +323,6 @@ class MMSConfig(object): os.path.join(context.sourcePath, 'loader'), ] - defines = [] for other_sdk in self.sdk_manifests: cxx.defines += ['SE_{}={}'.format(other_sdk['define'], other_sdk['code'])] diff --git a/core/metamod.cpp b/core/metamod.cpp index a29266612..67f58ee4c 100644 --- a/core/metamod.cpp +++ b/core/metamod.cpp @@ -94,7 +94,7 @@ static bool g_bIsVspBridged = false; MetamodSource g_Metamod; PluginId g_PLID = Pl_Console; -CSourceHookImpl g_SourceHook; +CSourceHookImpl g_SourceHook(mm_LogMessage); ISourceHook *g_SHPtr = &g_SourceHook; SourceMM::ISmmAPI *g_pMetamod = &g_Metamod; @@ -430,12 +430,13 @@ class SaveAndSet { T old_; }; -void +int mm_LogMessage(const char *msg, ...) { + int ret = 0; static bool g_logging = false; if (g_logging) { - return; + return ret; } SaveAndSet(&g_logging, true); @@ -446,7 +447,7 @@ mm_LogMessage(const char *msg, ...) size_t len = vsnprintf(buffer, sizeof(buffer) - 2, msg, ap); len = std::min(len, sizeof(buffer) - 2); if (len < 0) { - return; + return ret; } va_end(ap); @@ -454,11 +455,14 @@ mm_LogMessage(const char *msg, ...) buffer[len++] = '\n'; buffer[len] = '\0'; + if (!provider->LogMessage(buffer)) { - fprintf(stdout, "%s", buffer); + ret = fprintf(stdout, "%s", buffer); } provider->ConsolePrint(buffer); + + return ret; } static void diff --git a/core/metamod.h b/core/metamod.h index b1446bbc6..ad479ac6a 100644 --- a/core/metamod.h +++ b/core/metamod.h @@ -102,7 +102,7 @@ class MetamodSource : public ISmmAPI bool mm_DetectGameInformation(); -void +int mm_LogMessage(const char *msg, ...); int diff --git a/core/sourcehook/generate/sourcehook.hxx b/core/sourcehook/generate/sourcehook.hxx index 29db9fc88..1520a8805 100755 --- a/core/sourcehook/generate/sourcehook.hxx +++ b/core/sourcehook/generate/sourcehook.hxx @@ -132,6 +132,11 @@ enum META_RES namespace SourceHook { + /** + * @brief SourceHook's debug log function + */ + typedef int (*DebugLogFunc)(const char*, ...); + /** * @brief Specifies the size (in bytes) for the internal buffer of vafmt(printf-like) function handlers */ @@ -194,7 +199,7 @@ namespace SourceHook // SH tries to auto-detect these // If you want to override SH's auto-detection, pass them in yourself PassFlag_RetMem = (1<<6), /**< Object is returned in memory (through hidden first param */ - PassFlag_RetReg = (1<<7) /**< Object is returned in EAX(:EDX) */ + PassFlag_RetReg = (1<<7) /**< Object is returned in EAX(:EDX)/RAX(x86_64) */ }; size_t size; //!< Size of the data being passed @@ -499,6 +504,8 @@ namespace SourceHook const void *origRetPtr, void *overrideRetPtr) = 0; virtual void EndContext(IHookContext *pCtx) = 0; + + virtual void LogDebug(const char *pFormat, ...) = 0; }; diff --git a/core/sourcehook/sourcehook.cpp b/core/sourcehook/sourcehook.cpp index fbb3b3d00..27d7cfa2e 100644 --- a/core/sourcehook/sourcehook.cpp +++ b/core/sourcehook/sourcehook.cpp @@ -80,8 +80,9 @@ namespace SourceHook ////////////////////////////////////////////////////////////////////////// - CSourceHookImpl::CSourceHookImpl() + CSourceHookImpl::CSourceHookImpl(DebugLogFunc logfunc) { + m_LogFunc = logfunc; } CSourceHookImpl::~CSourceHookImpl() { @@ -639,6 +640,14 @@ namespace SourceHook ResolvePendingUnloads(); } + void CSourceHookImpl::LogDebug(const char *format, ...) + { + va_list args; + va_start(args, format); + m_LogFunc(format, args); + va_end(args); + } + void CSourceHookImpl::CompleteShutdown() { CVector removehooks; diff --git a/core/sourcehook/sourcehook.h b/core/sourcehook/sourcehook.h index 2ab0c0a95..4c464fddb 100644 --- a/core/sourcehook/sourcehook.h +++ b/core/sourcehook/sourcehook.h @@ -52,7 +52,6 @@ #endif #ifdef SH_DEBUG - # include # include @@ -133,6 +132,11 @@ enum META_RES namespace SourceHook { + /** + * @brief SourceHook's debug log function + */ + typedef int (*DebugLogFunc)(const char*, ...); + /** * @brief Specifies the size (in bytes) for the internal buffer of vafmt(printf-like) function handlers */ @@ -500,6 +504,8 @@ namespace SourceHook const void *origRetPtr, void *overrideRetPtr) = 0; virtual void EndContext(IHookContext *pCtx) = 0; + + virtual void LogDebug(const char *pFormat, ...) = 0; }; @@ -4929,4 +4935,4 @@ namespace SourceHook } #endif - // The pope is dead. -> :( \ No newline at end of file + // The pope is dead. -> :( diff --git a/core/sourcehook/sourcehook_impl.h b/core/sourcehook/sourcehook_impl.h index 9755ab946..96cba35b8 100644 --- a/core/sourcehook/sourcehook_impl.h +++ b/core/sourcehook/sourcehook_impl.h @@ -179,9 +179,10 @@ New SH_CALL #include "sourcehook_impl_ciface.h" #include "sourcehook_impl_cvfnptr.h" #include "sourcehook_impl_chookidman.h" +#include #include -void mm_LogMessage(const char* msg, ...); +extern SourceHook::ISourceHook *g_SHPtr; namespace SourceHook { @@ -203,10 +204,13 @@ namespace SourceHook template inline void SH_DEBUG_LOG(SH_LOG log_level, const char* message, Args... args) { +#ifndef SOURCEHOOK_TESTS if (log_level < sh_log_level) { return; } - mm_LogMessage(message, args...); + + SH_GLOB_SHPTR->LogDebug(message, args...); +#endif } struct CHookContext : IHookContext @@ -322,12 +326,13 @@ namespace SourceHook CHookIDManager m_HookIDMan; HookContextStack m_ContextStack; List m_PendingUnloads; + DebugLogFunc m_LogFunc; bool SetHookPaused(int hookid, bool paused); CHookManList::iterator RemoveHookManager(CHookManList::iterator iter); List::iterator RevertAndRemoveVfnPtr(List::iterator vfnptr_iter); public: - CSourceHookImpl(); + CSourceHookImpl(DebugLogFunc logfunc = printf); virtual ~CSourceHookImpl(); /** @@ -381,6 +386,8 @@ namespace SourceHook void DoRecall(); + void LogDebug(const char *pFormat, ...) override; + IHookContext *SetupHookLoop(IHookManagerInfo *hi, void *vfnptr, void *thisptr, void **origCallAddr, META_RES *statusPtr, META_RES *prevResPtr, META_RES *curResPtr, const void *origRetPtr, void *overrideRetPtr); diff --git a/core/sourcehook/test/AMBuilder b/core/sourcehook/test/AMBuilder index 4a6c2fa48..6edca31fe 100644 --- a/core/sourcehook/test/AMBuilder +++ b/core/sourcehook/test/AMBuilder @@ -4,6 +4,13 @@ import os for cxx in MMS.all_targets: name = 'test_sourcehook' binary = MMS.Program(cxx, name) + if binary.compiler.target.arch == 'x86_64' and binary.compiler.target.platform == 'linux': + continue + + binary.compiler.defines += [ + 'SOURCEHOOK_TESTS', + ] + binary.compiler.cxxincludes += [ os.path.join(builder.sourcePath, 'core', 'sourcehook'), ] @@ -19,6 +26,7 @@ for cxx in MMS.all_targets: '../sourcehook_impl_chookidman.cpp', '../sourcehook_impl_cproto.cpp', '../sourcehook_impl_cvfnptr.cpp', + '../sourcehook_hookmangen.cpp', 'test1.cpp', 'test2.cpp', 'test3.cpp', @@ -36,7 +44,9 @@ for cxx in MMS.all_targets: 'testrefret.cpp', 'testvphooks.cpp', ] - if binary.compiler.target.arch == 'x86': - binary.sources += ['../sourcehook_hookmangen.cpp'] + if cxx.target.arch == 'x86': + binary.sources += ['../sourcehook_hookmangen_x86.cpp'] + elif binary.compiler.target.arch == 'x86_64': + binary.sources += ['../sourcehook_hookmangen_x86_64.cpp'] builder.Add(binary)