最近被合成大西瓜这个魔性的小游戏刷屏了, 于是去玩了一下. 但每次都只能合成一个大西瓜, 一直不知道两个西瓜会合成什么样的新物品, 所以去研究了一下游戏代码, 看看能不能通过一个比较骚的方式开个挂.

_20214329024301.png

通过观察网页源代码, 可以看到小游戏用的是cocos2dx开发的, 通过canvas绘图, 由js来控制游戏逻辑, 游戏过程中没有产生相关的网络请求, 也就是说这个游戏的水果生成逻辑都写在了js里, 由客户端完成计算. 于是乎, 顺着程序加载的静态资源目录搜索到了下面的代码:

addNodeAni: function(e, t, n, o, c, a, i) {
                for (var r = e.getComponent(cc.Animation), s = [], l = o; l <= c; l++) {
                    var u = new cc.SpriteFrame(cc.url.raw("resources/" + t + l + ".png"));
                    s.push(u)
                }
                var d = cc.AnimationClip.createWithSpriteFrames(s, 5);
                d.name = n,
                d.speed = i,
                d.wrapMode = a ? cc.WrapMode.Loop : cc.WrapMode.Normal,
                r.addClip(d)
            },
            returnRanNum: function(e, t) {
                return e + Math.floor(Math.random() * (t - e + 1))
            }

可以代码进行了一定的压缩, 但由于没有进行混淆, 大体上还是可读的,看到RanNum函数可以猜测程序就是利用了Math.random来随机生成水果, 那么就有一个比较简单的方法去验证思路是否正确了.

直接在console中重写Math.random函数, 让他永远返回一个1, 看看是什么效果

Math.random = () => {return 1}

_20214329024314.png

这边有一个坑, 改完之后游戏最开始的几个水果依然没有变化, 起初我以为是改错了, 后来发现每次玩的时候一开始都是这几种水果顺序, 似乎是固定的.

于是多点了几次, 果然发现前几个水果是固定的那几种, 后面才会用随机数逻辑, 方法可行~
经过测试, 发现random返回2的时候直接就是大西瓜, 所以就有了这个一行代码创造大西瓜:

Math.random = () => {return 2}

_20214329024324.png

对于这种单机小游戏, 看到random函数可以顺手尝试一下, 就不用辛苦分析几千行js代码了

--

后面又试着看了一下js的逻辑, 找到了生成水果的关键函数

                this.fruitS = ["PuTaoS", "YingTaoS", "JuZiS", "NingMengS", "MiHouTaoS", "XiHongShiS", "TaoS", "BoLuoS", "YeZiS", "XiGuaS"],
                this.createOneFruit(0)

也找到了前几个固定水果的逻辑

                this.scheduleOnce(function() {
                    i.default.GameUpdateCtrl && (0 == t.createFruitCount ? (a.default.Instance.createOneFruit(0),
                    t.createFruitCount++) : 1 == t.createFruitCount ? (a.default.Instance.createOneFruit(0),
                    t.createFruitCount++) : 2 == t.createFruitCount ? (a.default.Instance.createOneFruit(1),
                    t.createFruitCount++) : 3 == t.createFruitCount ? (a.default.Instance.createOneFruit(2),
                    t.createFruitCount++) : 4 == t.createFruitCount ? (a.default.Instance.createOneFruit(2),
                    t.createFruitCount++) : 5 == t.createFruitCount ? (a.default.Instance.createOneFruit(3),
                    t.createFruitCount++) : t.createFruitCount > 5 && (a.default.Instance.createOneFruit(s.default.RandomInteger(0, 5)),
                    t.createFruitCount++))
                }, .5))

改随机数有赌的成分~

如果觉得我的文章对你有用,请随意赞赏