terraria吧 关注:738,797贴子:9,737,716

半源码mod制作教程

只看楼主收藏回复


头像镇楼


1楼2018-01-20 13:04回复
    2L链接


    2楼2018-01-20 13:04
    收起回复

      压缩包里面有什么?
      Patcher.zip和1353 Src Runnable.zip,前者是半源码mod的开发包,后者是1353可运行的源,具体的请看后面。
      什么叫半源码mod?
      半源码mod和源码mod没有本质上的不同。
      源码mod就好像是游戏给出了一张巨大的图片,而开发者在里面进行修改。
      优点是灵活性好,基本上想怎么改就怎么改,TML就可以看作是一个源码mod。
      缺点是开发效率太慢,抛开如此多的代码令人晕头转向不说,光是重新编译一次就需要不少的时间,而且还要稍好的配置,否则能否编译都是问题。
      半源码mod牺牲了源码mod的部分灵活性,但是解决了很多其他的麻烦。
      半源码mod采用的是补丁模式,将开发者写好的DLL视作补丁,打入游戏的可执行文件,紧接着运行打完生成的游戏文件即可。
      优点是开发效率很高,就拿压缩包内的补丁来说,在作者的电脑上打一次,大概就只需要30s。另外内存占用也极低,不会超过100MB。
      缺点就是灵活性的缺失————补丁的方式已经被补丁工具钉死了,不过这一点可以通过一些奇技淫巧来弥补。
      后文将半源码mod称为补丁。
      那我为什么不用TML而要用这个?
      emmm你要这么问我也没办法反驳什么。
      TML主要处理的是游戏内容,那是真正意义上的mod,同时TML抽象出来的接口限制了很多东西。
      其实如果没有特殊需求,TML非常的棒。
      我应该用什么编程语言呢?
      C#,准确来说是任何完备的可以运行在.Net运行时上的编程语言。此外还需要Python,由IronPython解释执行。
      那要用什么工具呢?
      dnspy:用于查询源码,和一些必要的简单修改
      VS2012~VS2017任一版本:用于编写代码
      VS的替代品SharpDevelop,如果不需要太高级的功能,可以选择SharpDevelop,其实这个挺**的,智能提示和代码格式化都不好,后文会用VS讲解,如果使用SharpDevelop就自己看着办吧
      notepad++:用于编写Python代码
      可以大致阐述一下原理吗?
      原理要分两个步骤阐述,分别是补丁开发和打补丁。
      补丁开发:引用游戏、补丁工具提供的基础补丁和别的前置补丁,写好要完成的逻辑,交由补丁工具打入游戏。
      打补丁:将补丁整个移入游戏,然后根据PBase提供的信息对补丁进行操作。


      3楼2018-01-20 13:06
      收起回复
        文件表及说明:
        1353 Src Runnable.zip->1353可编译运行的TR源码,修复工作由我和TH汉化组领导者 @1623027244maa 共同完成,但是不完美,部分代码是从老版本源码直接复制的,例如NetMessage.cs。总之这些都很好处理,用dnspy弄到新版源码直接复制进去改几下就好了。
        Patcher.zip->半源码mod开发包,需要解压再使用
        一个不好玩的端.zip->作者自己开发的端
        Patches ->放置补丁的文件夹
        Utils.py->基础的补丁,让单人模式下也可以打开输入框
        Utils.dll->基础的补丁,作用有修复原版输入框输入中文退格的问题和关闭游戏的正版验证,输入修复完全来自 @1623027244maa
        PHooks.dll->钩子补丁,提供一套简单的钩子
        PUI.dll->GUI补丁,提供了一套基于TR的GUI,包括了窗口和控件等,可以在github上找到工程,压缩包也有源码,emm本人水平不够,希望大家帮忙改进
        CheatTool.dll->作者自己开发的端的补丁文件,包内文件"一个不好玩的端.zip",视频: B站:av16920687 末尾有端的部分功能录像,这个补丁依赖于PUI和PHooks
        *.pdb->各种工程的pdb文件,用于调试,其实如果补丁被打入了游戏,这个文件也就没什么用了
        Src->放置补丁源码的文件夹
        内含Patches文件夹下dll补丁的源码
        PBase.dll->基础补丁,在补丁工具中这个补丁无法被取消选中,且大部分补丁以这个补丁为基础
        PatchLib.dll->由 @1623027244maa 合并而成,是Patcher.dll的前置
        Patcher.dll->由作者开发,部分技术细节来自 @1623027244maa ,负责打补丁的逻辑
        ILFactory.dll->由作者开发,提供给Python脚本,用于进行函数的精确修改
        PatcherGUI.exe->由作者开发,补丁工具的界面


        4楼2018-01-20 13:07
        回复
          打补丁的过程可以参考前文提到的视频,里面有详细步骤,需要注意的是如果你不是正版玩家,就需要手动去选择游戏文件。
          开始!
          1.打开补丁工具,选择游戏。
          2.点击导出资源,这一步会把Terraria的DLL全部导出来。
          3.点击导出Public.exe,这一步会导出一个所有方法,字段等全部公开化的游戏文件Public.exe,方便引用开发。
          4.打开VS,新建类库项目,引用上一步导出的Public.exe、PBase.dll,如果有需要可以饮用其他的DLL,需要注意的是,如果引用了非补丁的DLL,而游戏本身没有并且无法在库中找到,就需要把这个DLL和打了补丁的游戏放在一个目录下才能运行。
          5.可以开始编写补丁的代码了,压缩包内Src文件夹有几个补丁的源码,可以进行参考。


          5楼2018-01-20 13:08
          回复
            没人么,lz可是写了好久的。。


            6楼2018-01-20 13:10
            回复
              先顶再看 支持大佬!


              IP属地:重庆7楼2018-01-20 13:14
              收起回复
                期待一下,坐等更新


                IP属地:江西8楼2018-01-20 13:17
                回复
                  PBase主要提供了以下Attribute:
                  PPatch:用于描述一个类,确定对这个类的操作
                  原型
                  PPatch(PPatchOption option, string Namespace, string TypeName, string Description, bool moveStaticVarible = false, bool moveDynamicVarible = false, bool moveAnonymousType = false)
                  option取值:Merge和Move
                  Merge代表将此类与目标类合并,只有在此时,moveStaticVarible及后面的参数才有意义
                  Move代表将此类移往目标处,如果已经存在,会发生冲突。这种标识下,只有前三个参数有意义
                  Namespace是目标命名空间
                  TypeName是目标类名称
                  最后三个参数在option为Merge时起效,分别指示了合并时是否移动静态字段,移动变量,移动匿名类
                  PMethod:用于描述一个方法,包括构造方法和静态构造方法,但是这个描述只在PPatch为Merge的类中方法起效
                  原型
                  PMethod(PMethodOption option, string MethodName, string Description, bool willCheck = false)
                  option取值:Move、Replace以及Hook
                  Move表示直接把方法移动到目标处而不进行操作
                  Replace表示替换掉目标方法
                  Hook表示将这个方法移入目标类,且让目标方法运行完毕之后调用这个方法
                  需要十分注意,PMethod为目标方法名称,而具体的命名空间和类名由当前类的PPatch指定
                  willCheck参数已弃用
                  PDependence:用于描述依赖,可以叠加多个,无法满足依赖时Patcher会根据指示进行处理,这个描述只在PPatch为Merge的类中方法起效
                  原型
                  PDependence(PDependenceOption option, bool isClass, string name)
                  option取值:Error、Warning和Skip
                  Error表示在依赖无法满足时发生错误并且停止操作
                  Warning表示警告,但是不会停止操作,该方法仍会被处理
                  Skip表示无法满足依赖时警告,并且跳过当前方法,方法不会被处理
                  参数isClass表示所依赖的是否是类,不是类则是方法
                  name是依赖的完全限定名称,即包括命名空间、类名、(方法名)在内的完整名称


                  9楼2018-01-20 13:20
                  回复
                    顶顶


                    IP属地:广东来自Android客户端10楼2018-01-20 14:11
                    回复
                      ????突然正经


                      来自Android客户端11楼2018-01-20 14:13
                      收起回复
                        顶顶 顺便问一下2楼的链接呢?


                        来自Android客户端12楼2018-01-20 14:14
                        收起回复
                          不明觉厉,这原来还分源码和半源码的
                          那这个半源码是不是不能联机玩啊?


                          IP属地:广东13楼2018-01-20 14:29
                          收起回复
                            完全看不懂专业名词的我前来围观


                            来自Android客户端14楼2018-01-20 14:35
                            收起回复