TapTap猛鬼宿舍 抖音躺平发育 修改各种功能教程
作者:忆笙发布时间:2022-01-23 00:00浏览数量:1894次评论数量:1次
猛鬼宿舍DIY
从抖音上看到了这个游戏,玩了一会还算不错,就是是单机,而且AI还挺弱智,开发团队刚开发的原因;不过我觉得这个类型还是蛮喜欢的
从TapTap叫猛鬼宿舍,在抖音叫躺平发育,都是一样的
从TapTap下载,要依靠TapTap启动。通过mt,最终在/data/com.taptap/virtual/data/app/目录下找到了apk安装包,然后提取了出来。但是主界面少了场外商店和皮肤,不知道为什么(后来不知怎么又有了)
jadx打开查看MainActivity没有东西,也搜不到任何字符串。正疑惑呢发现了一个类叫JSBridge,所以猜想这东西主要代码应该在js那。
于是解压搜索,找到了位于assets/cache/stand.alone.version/的文件6ab7299a
分析class i
首先看到的是各个局内道具的价格定义
// row49 class i { constructor() { (this._newBuildData = { at: [ /* 花费金币,花费闪电,攻击力,攻击距离,升级前置条件 */ ["笤帚炮台", 8, 0, 4, 4, ""], ["铲铲炮台", 16, 0, 8, 4.5, ""], ["鱼叉炮台", 32, 0, 16, 5, ""], ["喷射水枪", 64, 0, 32, 5.5, ""], ["高压水枪", 256, 0, 64, 6, "game_1"], ["气泡发射器", 512, 0, 128, 6.5, ""], ["魔力气泡机", 1024, 32, 256, 7, "game_2"], ["驱魔气泡机", 2048, 64, 512, 7.5, ""], ["初级激光器", 4096, 128, 1024, 8, "game_3"], ["恶魔激光器", 8192, 256, 2048, 8.5, "game_4"], ["圣光生成器", 16384, 512, 4096, 9, "game_5"], ["圣光发射器", 32768, 1024, 8192, 9.5, "game_6"], ["圣光炮台", 65536, 2048, 16384, 10, ""], ], bed: [ /* 花费金币,花费闪电,金币产量,闪电产量,升级前置条件 */ ["发霉小床", 0, 0, 1, 0, ""], ["湿冷小床", 25, 0, 2, 0, ""], ["破旧小床", 50, 0, 4, 0, "door_2"], ["简陋的床", 100, 0, 8, 0, ""], ["标准床铺", 200, 0, 16, 0, "door_5"],
具体属性猜测如下:
at: [ /* 炮台:花费金币,花费闪电,攻击力,攻击距离,升级前置条件 */], bed: [ /* 床:花费金币,花费闪电,金币产量,闪电产量,升级前置条件 */], door: [ /* 门:花费金币,花费闪电,金币产量,未知,升级前置条件 */], game: [ /* 游戏机:花费金币,花费闪电,金币产量,闪电产量,升级前置条件 */], mine: [ /* 矿:花费金币,花费闪电,金币产量,闪电产量,升级前置条件 */],
此外还有一些特殊道具的花费
(this._newBuildData1 = { spell: ["符咒弹射器", 0, 64, 0, 0, ""], ice: ["冰箱", 0, 256, 0, 0, ""], entrapment: ["诱捕", 0, 512, 0, 0, ""], barb: ["倒刺", 0, 512, 0, 0, ""], guillotine: ["断头台", 0, 2048, 0, 0, ""], repair: ["维修台", 0, 64, 0, 0, ""], energyhood: ["能量罩", 0, 64, 0, 0, ""], smoney: ["取款机", 0, 128, 0, 0, ""], longrange: ["瞭望台", 0, 256, 0, 0, ""], particlea: ["粒子加速器", 0, 2048, 0, 0, ""], solenoid: ["电磁圈", 0, 2048, 0, 0, ""], }),
我们可以在这里修改物品的属性,比如说攻击力,血量,购买花费金币闪电什么的。
再之后是商品的一些描述。
继续向下分析,是一些局内商店和局外商店可以购买的物品,
(this._basicBuildData = [ ["at_1", "game_1", "repair_1"], ["mine_1", "mine_2", "mine_3", "mine_4"], ["spell_1", "energyhood_1", "smoney_1", "ice_1"], ["entrapment_1", "barb_1", "guillotine_1"], ["longrange_1", "particlea_1", "solenoid_1"], ]), (this._ShopBuildData = [ ["spell_1", "energyhood_1", "smoney_1", "ice_1"], ["entrapment_1", "barb_1", "guillotine_2", "repair_1"], ["longrange_1", "particlea_1", "solenoid_2"], ]),
再之后是皮肤图片加载,和局外商店的物品价格,标识为999的,则需要通过看视频来获得
(this._skin = { spell: "map/spellimg_0.png", energyhood: "map/energyhood_2.png", smoney: "map/money.png", entrapment: "map/entramentImage_1.png", guillotine: "map/guillotine_3.png", particlea: "map/particleaImg.png", solenoid: "map/solenoidimg_1.png" }), (this._ShopBuildMoney = { repair: ["维修台", 10], spell: ["符咒弹射器", 20], smoney: ["取款机", 20], ice: ["冰箱", 30], entrapment: ["诱捕", 30], barb: ["倒刺", 50], energyhood: ["能量罩", 50], guillotine: ["断头台", 999], longrange: ["瞭望台", 30], particlea: ["粒子加速器", 100], solenoid: ["电磁圈", 999], }),
这部分数据看不太懂是什么,应该是一些我没有用过的道具的属性buff
(this._AIPos = [ [21, 22], [21, 23], [22, 22], [22, 23], [23, 22], [23, 23], ]), (this._trollPos = [ [22, 1], [41, 23], [21, 35], [1, 23], ]), (this.AtBasePower = [1, 2, 4, 6, 14, 22.5, 40, 75]), (this.bulletBuff = { 1: [0, 0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.08], 2: [0, 0, 0, 0, 0, 0.5, 0.7, 1], 3: [0, 0, 1, 2, 3, 4, 5, 8] }), (this.AtBuffEff = [ [0, 0, 0, 0, 0, 0.01, 0.02, 0.04], [0, 0, 0, 0, 0, 0.01, 0.02, 0.04], [0, 0, 0, 0, 0, 0.01, 0.02, 0.04], ]);
之后便是一些get方法
class _
这个类里面有一些房间room的信息,判断游戏是否结束和开始,是否胜利,还有玩家数组,是否是mvp什么的,还有初始化玩家信息,和对玩家按金币和闪电进行冒泡排序;没啥需要修改的
class n
玩家的一些信息
constructor() { (this._key = "PlayerData"), (this._trollIndex = 0), (this.countI = 3), /* 皮肤最大数量 */ (this.skinMaxNum = 6), /* 皮肤序号 */ (this.skin = [0, 6, 2, 3, 4, 5]), /* 玩家的一些信息 */ (this._data = { _playerSelectIndex: 0, /* 玩家拥有的皮肤数组 */ _playerSkin: [0], _win: 0, _lose: 0, _mvp: 0, _gold: 0, _task: 0, _taskOk: !1, _ysOK: !1, /* 道具数量 */ _blueprint: { spell: 1, ice: 1, entrapment: 1, barb: 1, guillotine: 1, repair: 10, energyhood: 1, smoney: 1, longrange: 1, particlea: 1, solenoid: 1 }, }), (this._goldTextArr = []), this.Read(); }
这里可以修改初始化的道具数量,和皮肤数组
返回道具数量,直接改成定值10
GetBuileprintNum(t) { let e = this._data._blueprint[t]; return null != e ? e : null; } // 改为 return 10;
class Y
局内道具判断
BuildOrUp(t) { let e = h.instance.game.GetRoomPR(y.instance.player.roomIndex), i = t.split("_"), s = h.instance.build.GetBuildData(i[0], parseInt(i[1])); if (0 == s[5].length || this.ReachConditions(s[5], y.instance.player.roomIndex)) if (e.gold1 >= s[1] && e.gold2 >= s[2]) if (((e.gold1 -= s[1]), (e.gold2 -= s[2]), null == this.clickBlock.blockC)) r.instance.Fire(r.instance.MAP_BUILD_NEW, this.clickBlock.x, this.clickBlock.y, t); else { let e = this.clickBlock.blockC.FindBlockInfo_Pos(this.clickBlock.x + "_" + this.clickBlock.y); null != e ? (u.instance.PlaySound(u.instance.TB_sound.build_up), r.instance.Fire(r.instance.MAP_UPBUILD, e.build, t), this.clickBlock.blockC.BuildUp(this.clickBlock.x + "_" + this.clickBlock.y), d.instance.AddEffect(d.instance.effectStr.buildDownEffect, e.build.x, e.build.y), this._buildMenu.MenuHide()) : r.instance.Fire(r.instance.UIGM_TIPS, "该建筑已被摧毁!!!"); } else e.gold1 < s[1] && e.gold2 < s[2] ? r.instance.Fire(r.instance.UIGM_TIPS, "金币、闪电不足,请升级床铺、闪电") : e.gold1 < s[1] ? r.instance.Fire(r.instance.UIGM_TIPS, "金币不足,请提升床铺") : r.instance.Fire(r.instance.UIGM_TIPS, "闪电不足,请提升游戏机"); else { let t = s[5].split("_"), e = h.instance.build.GetBuildData(t[0], parseInt(t[1])); /* 升级前置条件 */ r.instance.Fire(r.instance.UIGM_TIPS, "需要一个" + e[0]); } }
可以看到判断了,将第7行的-=改成+=便可以实现金币不减反加
同样还有一处,道具是需要在场外购买的,这个在class n类修改
class M
应该是猛鬼的类,在这里看到了最大hp,当前hp,能量,速度;这里没需求改
class z
广告视频类
class Q extends J
含有猛鬼入场时间(30s),可更改
新手任务可直接完成
// 原代码 TaskPanel() { let t = h.instance.task.GetTaskText(this.taskIndex); t ? (this.taskIndex > h.instance.player.taskIndex && (h.instance.player.taskIndex++, (h.instance.player.gold += 5), (this.gold3.y = 225.5), p.instance.Gold3Effwct(this.gold3)), (this.taskText.text = t), (this.taskBtn.text = "未完成"), (this.taskBtn.color = "#675a59"), (this.taskBtn.underlineColor = "#675a59"), this.taskBtn.offAll()) : (this.TaskOver(), this.tasklg.RemoveUpEvent()); } // 修改后 TaskPanel() { let t = h.instance.task.GetTaskText(this.taskIndex); t ? (this.taskIndex > h.instance.player.taskIndex && (h.instance.player.taskIndex++, (h.instance.player.gold += 5), (this.gold3.y = 225.5), p.instance.Gold3Effwct(this.gold3)), (this.taskText.text = t), (this.taskBtn.text = "领取"), (this.taskBtn.color = "#23af00"), (this.taskBtn.underlineColor = "#23af00"), this.taskBtn.on(Laya.Event.CLICK, this, this.TaskBtnClickEvent)) : (this.TaskOver(), this.tasklg.RemoveUpEvent()); }
也可以注释掉,但是第一次任务还是需要自己完成、
class tt
随机人机的姓名,没啥用
class et extends J
匹配时相关函数
有一个每秒可能匹配一个人忍不了,单机都是人机还匹配这么慢
// 原代码 MatchEvent() { if (this.headImg.length > 0) { this.time++, (this.pp.text = "匹配中 " + this.time + "s"); let t = Math.random(); if (t < 0.7) { t = Math.floor(Math.random() * this.headImg.length); let e = this.headImg[t], i = this.heads.getChildAt(e); this.headImg.splice(t, 1); let s = i.getChildByName("name"), _ = tt.instance.name; if (0 == e) (i.skin = "StartGameUI/mg_" + h.instance.player.trollIndex + ".png"), (h.instance.game.trollName = _); else { let t = Math.floor(Math.random() * this.playerSKin); (i.skin = "StartGameUI/player_" + t + ".png"), (h.instance.game.playerArr = { name: _, index: t }); } (s.text = _), p.instance.Shake(i, 0.2), u.instance.PlaySound(u.instance.Other_sound.MP); } } else this._isMatch && (Laya.timer.clear(this, this.MatchEvent), this.StartGame(), (this.pp.visible = !1)); } // 修改后 MatchEvent() { while (this.headImg.length > 0) { this.time++, (this.pp.text = "匹配中 " + this.time + "s"); let t = Math.random(); if (t < 0.7) { t = Math.floor(Math.random() * this.headImg.length); let e = this.headImg[t], i = this.heads.getChildAt(e); this.headImg.splice(t, 1); let s = i.getChildByName("name"), _ = tt.instance.name; if (0 == e) (i.skin = "StartGameUI/mg_" + h.instance.player.trollIndex + ".png"), (h.instance.game.trollName = _); else { let t = Math.floor(Math.random() * this.playerSKin); (i.skin = "StartGameUI/player_" + t + ".png"), (h.instance.game.playerArr = { name: _, index: t }); } (s.text = _), p.instance.Shake(i, 0.2), u.instance.PlaySound(u.instance.Other_sound.MP); } } this._isMatch && (Laya.timer.clear(this, this.MatchEvent), this.StartGame(), (this.pp.visible = !1)); }
修改后的效果就是点击准备后秒进游戏了
class at extends J
可以发现调用了
ADVClickEvent() { Platform.video.playVideo({ success: () => { u.instance.PlaySound(u.instance.Other_sound.tcOpen), this.TcEffectInit(), this.MoveDown(this.tc, this.advBtn.y, 1, 600, () => { this.tc.play(0, !1, "open"), this.tc.on(Laya.Event.COMPLETE, this, this.open); }), (this.advBtn.visible = !1), (this.qq.visible = !1), this.MoveDown(this.closeBtn, this.closeBtn.y + this.closeBtn.height, 0, 200, () => { this.closeBtn.visible = !1; }); }, fail: () => { r.instance.Fire(r.instance.UIGM_TIPS, "请观看完整视频,获得宝箱"); }, }); }
直接将success中的回调内容覆盖到该函数就好了。
搜索这个Platform.video.playVideo函数,发现有5次调用。以相同方式改掉(但是会报错,最终也没试)
class $ extends J
看视频领蜜罐币(player.gold)
输赢事件,即使输了,用赢方法覆盖输方法可以将输改为赢
class it extends J
有场外道具的购买代码
// 原代码 ShopBtnEvent(...t) { let e = t[0].split("_"), i = e[0], s = t[1], _ = h.instance.build.GetShopBuildMoney(i), n = _[1]; h.instance.player.gold >= n ? ((h.instance.player.gold -= n), h.instance.player.ModifiedBuileprintQuantity(i, 1), (s.text = h.instance.player.GetBuileprintNum(i)), (this._gold.text = h.instance.player.gold.toString()), r.instance.Fire(r.instance.UIGM_TIPS, "购买成功")) : r.instance.Fire(r.instance.UIGM_TIPS, "钻石不足"); } // 修改后(部分) ((h.instance.player.gold += n), h.instance.player.ModifiedBuileprintQuantity(i, 1), (s.text = h.instance.player.GetBuileprintNum(i)), (this._gold.text = h.instance.player.gold.toString()), r.instance.Fire(r.instance.UIGM_TIPS, "购买成功"));
改不改也没啥,毕竟我提取出来的安装包没有场外道具
class _t extends J
每次打开游戏有个公告,必须要强制看三秒,就在这里
this.gsTime = 3 // 改为1
去校验
刚开始修改完,打包安装发现报错,查了半天这个游戏使用的是layabox,然后有一个校验dcc的过程。
我不会去除校验过程(好像也不能去除),然后看了两篇资料https://ask.layabox.com/question/3678和https://ldc.layabox.com/doc/?nav=zh-as-7-2-1 ,决定重新生成文件内容的校验值,然后替换掉旧的
首先去除android.permission.INTERNET权限,这个软件还有乱七八糟的一堆权限,但是我没有去,删了会报错,我也懒得一个个验证,索性就只去除一个联网,防止热更新修改完的js文件
修改完文件后,将其复制到一个文件夹,npm安装好layadcc后运行命令
layadcc .
就会生成update文件夹,然后去把正确的校验值复制出来
先是修改filetable.txt和filetable1.txt里面文件名后的内容校验值;还有一个filetable.bin,使用010打开,然后查找int值,找到后将其修改
这样便完成了
总结
因为没去掉校验,修改比较麻烦,每次都得重新生成校验值填进去。最终修改的功能如下
修改金币闪电钻石不减反增
修改为秒匹配人机
修改场外道具定值10
删掉升级前置条件
删掉开局公告强制等待3秒
解锁全皮肤
新手任务可直接点完成
每次都是修改一个小功能填进去,修改校验值,如果报错还需重新改,上面记录的代码可能不是最终的,但都是这意思,关键点是对的。
其实能改的有很多,游戏地图都在这个文件里用数组存着,再加上没有混淆,甚至可以二次开发。
我这里仅仅是简单的分析了一下,这个文件有9000行,仅仅是一小部分,感兴趣的可以再深入分析。
最后,补张图
- 上一篇:简洁大气资源站emlog模板
- 下一篇:伍登华美腿健身锻炼视频课程
相关推荐
你 发表评论:
欢迎- 玩偶姐姐Hong Kongdoll森林系列【相遇】【欺骗】【碎裂】巅峰之作,第四集预告即将来袭…
- 玩偶姐姐(Hong Kong Doll)又出新作【夏日回忆3】Summer Memories 3
- 抖音“林青平”(洗衣机)事件是什么梗?林青平洗衣机视频
- 小黄鸭晴天国际服除草V1.6.0最新版已更新
- 玩偶姐姐(Hong Kong Doll)新森林系列第二集“欺骗”上线,你期待吗?
- 玩偶姐姐新作《我的一日女友之热恋海岸线》
- 小黄鸭注入器辅助破解热更新页0914
- 玩偶姐姐Hong Kong Doll又一新作《晨钟暮鼓》质感爆棚!
- 忆笙资源网官方APP下载 再也不怕忘记网址啦
- 绿巨人4.0最新版破解教程
已有1位网友发表了看法:
访客 评论于 [2022-04-15 06:45:16] 回复
666