• 骑砍2霸主MOD开发(6)-使用C#-Harmony修改本体游戏逻辑


    一.C#-Harmony反射及动态注入

        利用C#运行时环境的反射原理,实现对已加载DLL,未加载DLL中代码替换和前置后置插桩.

        C#依赖库下载地址:
    霸王•吕布 / CSharpHarmonyLib · GitCodeicon-default.png?t=N7T8https://gitcode.net/qq_35829452/csharpharmonylib

        根据实际运行.Net环境选择对应版本的0Harmony.dll

    二.csproj文件添加0Harmony.dll依赖

        <1.使用dnspy确定当前游戏版本使用.NET运行时环境

        <2.确定启动项为TaleWorlds.MountAndBlade.Launcher.exe

        <3.csproj选择编译环境,依赖dll路径

    1. <Project Sdk="Microsoft.NET.Sdk">
    2. <PropertyGroup>
    3. <Version>0.0.1</Version>
    4. <!--指定VS编译依赖.net2框架-->
    5. <TargetFramework>netstandard2.0</TargetFramework>
    6. <Platforms>x64</Platforms>
    7. <!--指定游戏安装目录-->
    8. <GameFolder>D:\work\Steam\steamapps\common\Mount &amp; Blade II Bannerlord</GameFolder>
    9. <GameBinariesFolder Condition="Exists('$(GameFolder)\bin\Win64_Shipping_Client\Bannerlord.exe')">Win64_Shipping_Client</GameBinariesFolder>
    10. <GameBinariesFolder Condition="Exists('$(GameFolder)\bin\Gaming.Desktop.x64_Shipping_Client\Bannerlord.exe')">Gaming.Desktop.x64_Shipping_Client</GameBinariesFolder>
    11. <!--指定输出dll名称,输出dll路径-->
    12. <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
    13. <AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
    14. <AssemblyName>NativeTest</AssemblyName>
    15. <OutputPath>D:\work\Steam\steamapps\common\Mount &amp; Blade II Bannerlord\Modules\NativeTest\bin\Win64_Shipping_Client</OutputPath>
    16. </PropertyGroup>
    17. <!--指定使用C#接口-->
    18. <ItemGroup>
    19. <Reference Include="$(GameFolder)\bin\$(GameBinariesFolder)\Newtonsoft.Json.dll">
    20. <HintPath>%(Identity)</HintPath>
    21. <Private>False</Private>
    22. </Reference>
    23. <Reference Include="$(GameFolder)\Modules\Harmony\bin\Win64_Shipping_Client\0Harmony.dll">
    24. <HintPath>%(Identity)</HintPath>
    25. <Private>False</Private>
    26. </Reference>
    27. <Reference Include="$(GameFolder)\bin\$(GameBinariesFolder)\TaleWorlds.*.dll" Exclude="$(GameFolder)\bin\$(GameBinariesFolder)\TaleWorlds.Native.dll">
    28. <HintPath>%(Identity)</HintPath>
    29. <Private>False</Private>
    30. </Reference>
    31. <Reference Include="$(GameFolder)\Modules\Native\bin\$(GameBinariesFolder)\*.dll">
    32. <HintPath>%(Identity)</HintPath>
    33. <Private>False</Private>
    34. </Reference>
    35. <Reference Include="$(GameFolder)\Modules\SandBox\bin\$(GameBinariesFolder)\*.dll">
    36. <HintPath>%(Identity)</HintPath>
    37. <Private>False</Private>
    38. </Reference>
    39. <Reference Include="$(GameFolder)\Modules\SandBoxCore\bin\$(GameBinariesFolder)\*.dll">
    40. <HintPath>%(Identity)</HintPath>
    41. <Private>False</Private>
    42. </Reference>
    43. <Reference Include="$(GameFolder)\Modules\StoryMode\bin\$(GameBinariesFolder)\*.dll">
    44. <HintPath>%(Identity)</HintPath>
    45. <Private>False</Private>
    46. </Reference>
    47. <Reference Include="$(GameFolder)\Modules\CustomBattle\bin\$(GameBinariesFolder)\*.dll">
    48. <HintPath>%(Identity)</HintPath>
    49. <Private>False</Private>
    50. </Reference>
    51. <Reference Include="$(GameFolder)\Modules\BirthAndDeath\bin\$(GameBinariesFolder)\*.dll">
    52. <HintPath>%(Identity)</HintPath>
    53. <Private>False</Private>
    54. </Reference>
    55. </ItemGroup>
    56. </Project>

    三.SubModule.xml添加0Harmony.dll依赖

    1. <!-- 对应bin\Win64_Shipping_Client下的MOD自定义DLL-->
    2. <SubModules>
    3. <SubModule>
    4. <Name value="NativeTestSubModule" />
    5. <DLLName value="NativeTest.dll" />
    6. <SubModuleClassType value="NativeTest.NativeTest" />
    7. <Assemblies>
    8. <Assembly value="0Harmony.dll" />
    9. </Assemblies>
    10. <Tags>
    11. <Tag key="DedicatedServerType" value ="none" />
    12. </Tags>
    13. </SubModule>
    14. </SubModules>

    四.Harmony实现对任意类任意方法的前置后置插桩

        <1.MBSubModuleBase.OnSubModuleLoad()中进行Harmony注入

        <2.实现Prefix,Postfix前置后置插桩,实现对本体代码的修改,例如游戏菜单的加载调用前插入一个对话框MsgBox

    1. public class NativeTest : MBSubModuleBase
    2. {
    3. protected override void OnSubModuleLoad()
    4. {
    5. base.OnSubModuleLoad();
    6. Harmony patch = new Harmony("MyPatch");
    7. patch.PatchAll();
    8. PrefixbBox();
    9. }
    10. }
    11. #实现对游戏菜单初始化的前置插桩
    12. namespace CampaignMissionPatch
    13. {
    14. [HarmonyPatch(typeof(EncounterGameMenuBehavior), "AddGameMenus")]
    15. public class CampaignMissionPatch {
    16. [DllImport("user32.dll", EntryPoint = "MessageBoxA")]
    17. public static extern int MsgBox(int hWnd, string msg, string caption, int type);
    18. public static bool Prefix(CampaignGameStarter gameSystemInitializer)
    19. {
    20. MsgBox(0, "this is conversation mission", "msg box", 0x30);
    21. return true;
    22. }
    23. }
    24. }

  • 相关阅读:
    2022 ACM-ICPC 网络赛(1) A题
    XSS靶场中级绕过
    UNet网络模型:数据集制作
    一文解决什么是Docker。如何使用Docker。Docker能做什么。
    【基础篇】四、本地部署Flink
    Pytorch:BatchNorm1d、BatchNorm2d、BatchNorm3d
    react 生命周期
    如何拥有自己的专属GPT-本地部署目前最强大模型llama3
    redis快速入门
    计算机网络 4 - 网络层
  • 原文地址:https://blog.csdn.net/qq_35829452/article/details/138039550