From 7f16dedc092512a4cda45caa5895ec1e036937ef Mon Sep 17 00:00:00 2001 From: Lorraxs Date: Tue, 5 Dec 2023 15:00:07 +0700 Subject: [PATCH] z --- client/impl/newbie.impl.lua | 3 ++- client/impl/test.impl.lua | 6 +++++ client/impl/test2.impl.lua | 39 ++++++++++++++++++++++++++++ impl.lua | 52 ++++++++++++++++++++++++++++++++++++- main.lua | 15 ++++++----- 5 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 client/impl/test2.impl.lua diff --git a/client/impl/newbie.impl.lua b/client/impl/newbie.impl.lua index ce02fb7..b1692a9 100644 --- a/client/impl/newbie.impl.lua +++ b/client/impl/newbie.impl.lua @@ -6,4 +6,5 @@ end function Impl:OnReady() main:LogInfo("%s ready", self:GetName()) -end \ No newline at end of file +end + diff --git a/client/impl/test.impl.lua b/client/impl/test.impl.lua index c8947fe..cb0a2e9 100644 --- a/client/impl/test.impl.lua +++ b/client/impl/test.impl.lua @@ -5,8 +5,14 @@ function Impl:Init() self.data = { test = "test" } + self.testVar = 0 end function Impl:GetData() return self.data +end + +function Impl:Add(amount, amount2) + self.testVar = self.testVar + amount + amount2 + return self.testVar end \ No newline at end of file diff --git a/client/impl/test2.impl.lua b/client/impl/test2.impl.lua new file mode 100644 index 0000000..68be622 --- /dev/null +++ b/client/impl/test2.impl.lua @@ -0,0 +1,39 @@ +local Impl = NewImpl("Test2") + +function Impl:OnReady() + self:MainThread() + self:TestHook() + self:TestReplaceMethod() +end + +function Impl:MainThread() + local testImpl = main:GetImpl("Test") + Citizen.CreateThread(function() + while true do + Wait(1000) + local result = testImpl:Add(1, 2) + main:LogInfo("TestImpl result %s", result) + end + end) +end + +function Impl:TestHook() + local testImpl = main:GetImpl("Test") + testImpl:HookMethod("Add", function(self, amount, amount2) + return amount+1, amount2 + end) +end + +function Impl:TestReplaceMethod() + Citizen.CreateThread(function() + Wait(5000) + local testImpl = main:GetImpl("Test") + local oldMethod = testImpl:GetMethod("Add") + testImpl:ReplaceMethod("Add", function(self, amount, amount2) + self.testVar = self.testVar * amount * amount2 + return self.testVar + end) + Wait(5000) + testImpl:ReplaceMethod("Add", oldMethod) + end) +end \ No newline at end of file diff --git a/impl.lua b/impl.lua index 52274a7..8768d5b 100644 --- a/impl.lua +++ b/impl.lua @@ -90,7 +90,10 @@ end -- create an instance of an object with constructor parameters function Class:new(...) - local obj = self:extend({}) + local obj = self:extend({ + destroyed = false, + originalMethods = {} + }) if obj.Init then obj:Init(...) end return obj end @@ -115,6 +118,53 @@ end function Impl:OnReady(...) end +function Impl:HookMethod(method, hookFn) + local oldMethod = self[method] + if not oldMethod then + main:LogError("Impl %s missing method %s", self.name, method) + return + end + self.originalMethods[method] = oldMethod + + self[method] = function(...) + if self.destroyed then + return + end + local result = {pcall(hookFn, ...)} + print(json.encode(result)) + local success = table.remove(result, 1) + if not success then + main:LogError("Impl %s hook %s error: %s", self.name, method, result[2]) + self[method] = oldMethod + return oldMethod(...) + end + return oldMethod(self, table.unpack(result)) + end +end + +function Impl:GetMethod(method) + return self[method] +end + +function Impl:ReplaceMethod(method, newMethod) + if not self[method] then + main:LogError("Impl %s missing method %s", self.name, method) + return + end + if not self.originalMethods[method] then + self.originalMethods[method] = self[method] + end + self[method] = newMethod +end + +function Impl:RefreshMethod(method) + if not self.originalMethods[method] then + main:LogError("Impl %s missing method %s", self.name, method) + return + end + self[method] = self.originalMethods[method] +end + function NewImpl(name) local impl = Impl:extend({ name = name diff --git a/main.lua b/main.lua index 00ebb72..731dd11 100644 --- a/main.lua +++ b/main.lua @@ -8,6 +8,7 @@ function Main:Init() local o = {} setmetatable(o, {__index = Main}) o.impls = {} + o.initializedImpls = {} o.lastTimeImplRegistered = 0 o.ready = false if not IsDuplicityVersion() then @@ -78,28 +79,28 @@ function Main:RegisterImpl(name, impl) self.lastTimeImplRegistered = GetGameTimer() self:LogSuccess("Impl %s registered", name) if self.ready then - self.impls[name] = impl(self) - self.impls[name]:OnReady() + self.initializedImpls[name] = impl(self) + self.initializedImpls[name]:OnReady() end end function Main:InitImpl() for name, impl in pairs(self.impls) do - self.impls[name] = impl(self) + self.initializedImpls[name] = impl(self) end self:LogInfo("All impls initialized") self.ready = true - for name, impl in pairs(self.impls) do + for name, impl in pairs(self.initializedImpls) do impl:OnReady() end end function Main:GetImpl(name) - if not self.impls[name] then + if not self.initializedImpls[name] then self:LogError("Impl %s not found", name) return end - return self.impls[name] + return self.initializedImpls[name] end function Main:ImplCall(name, func, ...) @@ -114,6 +115,8 @@ function Main:ImplCall(name, func, ...) return impl[func](impl, ...) end + + function Main:ImplInfo() for name, impl in pairs(self.impls) do local debug = debug.getinfo(impl.Init, "S")