Giter Club home page Giter Club logo

Comments (3)

Lectem avatar Lectem commented on August 29, 2024 1

So there are multiple issues at hand.

I want to detour calls to functions Foo, Bar, and Baz to my own implementations, but I want these functions to continue using the existing D2 logic for everything else so the mod can coexist with other mods and to use code that is known to be working. Half of this issue is something that will disappear as this codebase grows

There are multiple ways to do this, but essentially if you want to use D2Moo's patching mechanism you'll need to rely on doing 2 things:

  1. Detours the target function you want to replace
  2. Call the original functions instead of D2Moo's

The first one is easy to do with pretty much any patching mechanism, including D2Moo's.
The second one is a bit more tricky, you will need to either:

  • Keep the current code, and patch D2Moo functions you call to call the original ones instead
  • Change the code to call functions you manually loaded

If using D2Moo's patching mechanism, if you need to patch ordinal functions(or pointers) this couldn't be easier, just change the patch action as done here for datatables:

// Don't patch, datatable
PatchAction::FunctionReplacePatchByOriginal, // DATATBLS_GetLevelDefRecord @10010

If you need to patch something that is not an ordinal, you'll need to use the extra patch actions

static ExtraPatchAction extraPatchActions[] = {

If you need to call the original function from your detoured version, you'll also want to use extra patch actions by specifying a pointer that can store the original function address, much like what the debugger does:

{ 0x6FC386D0 - D2GameImageBase, &GAME_UpdateProgress_WithDebugger, PatchAction::FunctionReplaceOriginalByPatch, &GAME_UpdateProgress_Original},

In theory, we wouldn't need to patch D2Moo to call the original code if:

  • we were done writing/fixing all the functions
  • we didn't care about other patches being installed by "3rd party" mods

One alternative would be to use only D2Moo's headers, write your own patching DLLs and/or mechanism, and only write the functions you want to patch. As soon as would try to call a function that does not exist in your DLL and that is not an imported ordinal, you would end up with a linker error saying it can't find the function. You could then implement it as a simple call to the original function that you loaded with GetProcAddress() . This is what the macros D2FUNC does (in a not really optimized/pretty way). Example in the debugger:

D2FUNC(D2Game, SpawnSuperUnique_6FC6F690, D2UnitStrc*, __fastcall, (D2GameStrc* pGame, D2ActiveRoomStrc* pRoom, int32_t nX, int32_t nY, int32_t nSuperUnique), 0x6FC6F690 - D2GameImageBase);

I hope this can help and answers your question. If I can help making the process easier, don't hesitate to suggest changes to the project. I know one of the current pain points is that currently one .dll can only patch one original .dll. (This was kind of done on purpose to avoid mixing code from multiple .dlls and export ordinals that shouldn't be)

from d2moo.

silvermane-HU avatar silvermane-HU commented on August 29, 2024

Reading the list I'd prefer the "subproject - Import D2MOO .dlls and patch the functions you want" If there was a vote that is what I'd choose

from d2moo.

nooperation avatar nooperation commented on August 29, 2024

I'm likely doing it wrong and forcing this project to do something it really isn't geared towards, but I had to end up going with copy-paste. I want to detour calls to functions Foo, Bar, and Baz to my own implementations, but I want these functions to continue using the existing D2 logic for everything else so the mod can coexist with other mods and to use code that is known to be working. Half of this issue is something that will disappear as this codebase grows

for instance

SKILLS_GetSkillsTxtRecord_t SKILLS_GetSkillsTxtRecord = nullptr;
...
SKILLS_GetSkillsTxtRecordFromSkill = (SKILLS_GetSkillsTxtRecordFromSkill_t)(D2CommonImageBase + 0x71540);
...
int32_t __fastcall My_SKILLS_SrvSt58_FireClaws(D2GameStrc* pGame, D2UnitStrc* pUnit, int32_t nSkillId, int32_t nSkillLevel)
{
    D2SkillsTxt* pSkillsTxtRecord = SKILLS_GetSkillsTxtRecord(nSkillId); // Call the original SKILLS_GetSkillsTxtRecord
    ...
    MyD2DamageStrc damage = {};
    My_sub_6FD155E0(pGame, pUnit, pTarget, pSkillsTxtRecord, nSkillId, nSkillLevel, &damage, 0); // Call my custom implementation of sub_6FD155E0
    ...
}

Let's say I had a custom My_SKILLS_SrvSt58_FireClaws. I want it to still call SKILLS_GetSkillsTxtRecord from the loaded D2Common library instead of the D2Moo implementation (It's just an example, assume these are both from the same dll and a bit more complex). I do this because I want to call functions that other mods may have injected their own code into and because it's guaranteed to be a correct implementation since it's using the original logic.

I started off as "subproject - Configure CMake to use your own patch files and .def" and this was working well until I started hitting issues with other mods and running into not yet complete logic in this codebase. Am I doing something completely wrong, or do I just have a not so great usecase at the moment?

from d2moo.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.