3DMGAME 3DM首页 新闻中心 前瞻 | 评测 游戏库 热门 | 最新 攻略中心 攻略 | 秘籍 下载中心 游戏 | 汉化 购买正版 论坛

注册 登录

QQ登录

只需一步,快速开始

查看: 8184|回复: 22
打印 上一主题 下一主题

[MOD] 关于2.07的mod失效问题调查 以及解决(提供可用的反编译工具,4月13上传反编译工具luadec),附带示例mod代码

[复制链接]

1

主题

40

帖子

105

积分

中级玩家

Rank: 3Rank: 3

贡献度
1
金元
1005
积分
105
精华
0
注册时间
2017-3-20
跳转到指定楼层
主题
发表于 2017-4-6 23:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 金鱼师父 于 2017-4-30 10:27 编辑

今晚研究了一下,基本确定2.07的在lua字节码层面不再兼容
昨天下好了游戏,今天开始写mod,然后发现论坛介绍的方法都失效了,表现为无法反编译源文件。
通过对比文件头和调试luadec:github.com(不)/(能)viruscamp/(发链接)luadec,
以及从新版lua文件头可正常读取的信息判断,有两个变化:
1 2.07的lua版本从5.1升到了5.3
2 供应商自己修改了文件头校验规则

问题2我自己通过简单修改lua源码解决了,下边百度盘是新编译的luadec
问题1没能解决,luadec可以反编译但错误多,unluac我找到的版本最多支持到5.2

对于一般玩家,你们只需要知道,所有字节码mod都失效了。
既然有人还能用之前mod,那么说明未编译的mod依然有效,剩下的问题无非是 1 兼容新源码的其他文件 2 兼容lua5.3新语言特性
lua5.3有setfenv->_ENV等几处变化,具体请自查。

因为luadec对5.3反编译的bug太多,我决定不再通过修改源码的方式来实现mod,改为挂钩函数或修改全局数据等方法。


是我修改过的luadec,可以反编译2.07的字节码:
pan.baidu.com(删除)/s(删除)/1bG8HPG
要注意反编译可能有错,错误参考:
github.com(删除)/viruscamp(删除)/luadec(删除)/issues
所以这个工具大家用来读源码就是了,编译结果务必慎用----------------
补充:为什么我不直接将2.06的lua.hpk替换掉2.07的呢,因为地图文件也带lua脚本,我还没确认2.06的脚本和2.07的地图有无兼容问题---------------
2.06和2.07代码确实有些不同,比如loottable里项的格式。2.06的一项是{1,1,1,func},2.07则变为{1,1,1,'',func},增加了一个字符串。这就可能导致修改掉落表的mod失效。
另外如果mod运行错误,2.07不会给出任何提示,要么不加载mod,要么不能正常进入游戏,请modder自己加好日志功能,用pcall捕捉错误

使用本版mod教程方式安装lua,下边是我的示例文件

ZZZ.lua

local logfl = false
local function log(...)
        logfl=logfl or io.open('D:/ErrorLog.txt','w') --日志文件路径
        logfl:write(...)
        logfl:flush()
end

local function floor(v)--因为游戏lua虚拟机禁用了math库,游戏参数又需要是整数,所以自己实现一个math.floor
        if v < 1  then return 0 end
        
        local n=128

        while n < v do
                n = n << 1
        end
        
        while n > v do
                n = n >> 1
        end
        
        local r=n
        
        while n > 1 and r < v do
                n = n>>1
                local i=r+n
                if i <= v then
                        r=i
                end
        end
        
        return r
end

local function main()
        local function multi_g(t)--挂钩函数示例,效果,物品数量x10
                local fun=t[#t]
                t[#t] = function(...)
                        local r=fun(...)
                        if r then
                                r.stack = r.stack*10
                        end
                        return r
                end
        end

         local function genmod(m)
                local l = m.obj.Level

                assert(l and l > 0, 'Invaild self.obj.Level')
                m.obj:SetModifiers(m.equip_id,{                                movement_speed = floor(l^0.5 * 25),                                attack_speed=floor(l^0.8 * 15),                                weapon_lifesteal = floor(l^0.5),                                max_overdrive_add = OverdriveBar*floor(l/5),                                overdrive=floor(100 * l^0.6),                                health=200*l,                                armor=10*l,                                adm=10*l,                                armor_penetration=5*l})

        end
--自定义modifyer,作为等级1的效果,卡片和升级奖励都通过modifyer实现        
        DefineClass.SA_YOURMOD = {
                __parents = {"SA_Effect"},
                proc_events = {"recalc"},

                Proc=function(self)
                        local suc,m = pcall(genm,self.obj.Level)
                        if not suc then
                                log('ERROR:\r\n'..m)
                        end
                        return true
                end
        }

        multi_g(LootTable.Gold[1])
        multi_g(LootTable.Gold_small[1])
        multi_g(LootTable.Gold_medium[1])
        multi_g(LootTable.Gold_large[1])
--金钱 x 10
        table.insert(LevelRewards[1].effects,'SA_YOURMOD ')
--修改升级奖励        
        SA_Level_5_E1.modifiers.destiny_points = 6
        SA_Level_10_E1.modifiers.destiny_slots = 2
        SA_Level_11_E1.modifiers.destiny_points = 6

--修改掉落率        
        local function avgloot(t,weight)
                for _,v in ipairs(t) do
                        v[1] = floor(sqrt(v[1])) + weight
                end
        end
        
        avgloot(LootTable.DefaultLoot,32)
        avgloot(LootTable.DefaultChest,8)

        for name, it in pairs(LootTable) do
                --log('\r\n'..name..'-----')
                if type(it) == 'table' and name:sub(1+#name-#'Minion') ~= 'Minion' then
                        for nth, v in pairs(it) do
                                if type(v)=='table' and v[5] == 'none' then
                                        assert(#v==5, '#v==5')
                                        --log(name..':'..nth..'='..v[1]..'  ')
                                        v[1]=Max(1,floor(v[1]/10))
                                end
                        end
                end
        end


end

local suc,msg=pcall(main)
if not suc then
        log('ERROR:\r'..msg)
end-----------------------------------
首先感谢

同学给我的旧版代码,然后补充:最近发现那个java版的unluac也有反编译错误,有的地方把...参数给反编译没了

那么现在可以说,对于所有的luaMod,无论2.07还是之前,都不建议修改原来的文件,因为你反编译出来的源码就可能错了


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|3DMGAME ( 京ICP备14006952号-1  沪公网安备 31011202006753号

GMT+8, 2026-3-30 04:27 , Processed in 0.027016 second(s), 16 queries , Memcached On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表