Maris Posted June 11, 2020 Share Posted June 11, 2020 (edited) Let's say there is a critical game function "render": function SomeClass:render() --Game code (safe) end And you want to inject into it. As you know, replacing the whole function is bad practice. Therefore, the injection in your mod will look something like this: local old_fn = SomeClass.render SomeClass.render = function(self, ...) --Your code (unsafe) return old_fn(self, ...) end The main difficulty is that your code may contain errors with a high chance. And if something goes wrong, the user will receive a ton of red errors or the game will freeze because the function is critical and is called roughly every tick. So you want at least stop spam of errors if something went wrong. There is a solution! local in_progress = false local old_fn = SomeClass.render SomeClass.render = function(self, ...) if in_progress then return old_fn(self, ...) end in_progress = true --Your code (unsafe) in_progress = false return old_fn(self, ...) end Actually, this code was created in order to avoid recursion. But as a side effect, it allows to bypass the storm of errors. If something breaks the mod, then the mod just stops working, and the game continues without further errors. Edited June 16, 2020 by Maris Dr_Cox1911 1 Link to comment Share on other sites More sharing options...
Maris Posted June 16, 2020 Author Share Posted June 16, 2020 (edited) Okay, let's say you need DOUBLE INJECTION. Why would you need this? For example, you are a very neat modder and do not want to load the user's CPU, overwriting common game functions and making permanent injection. One of these functions is getText(). And you want to make temporary ninja injection. So we have to go a more complex way: local old_getText = nil local function new_getText(str,...) --You code (unsafe!) return old_getText(str,...) end local in_progress = false local old_render = SomeClass.render function SomeClass:render(...) --permanent injection if in_progress then if old_getText and getText == new_getText then getText = old_getText old_getText = nil end return old_render(self, ...) end old_getText = getText getText = new_getText --tempry second injection in_progress = true local result = old_render(self, ...) in_progress = false if old_getText then getText = old_getText end return result end If something goes wrong, your feature just stop working and that's it. No further game errors. P.S. Specific function render() does not return a result (by meaning), so you may omit it in this case. But it's not a mistake. Usually you have to keep the result. Edited July 29, 2020 by Maris Dr_Cox1911 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now