blocklauncher插件吧 关注:2,534贴子:18,937

【思路&教程】饥饿值的修改和获取

只看楼主收藏回复

温馨提示,本贴所讨论的一切内容仅于AIDE 3.2.160210 With NDK 20160121 环境编译通过,并于Minecraft PE 0.14.3 With BlockLauncher 1.12.7环境测试成功。


IP属地:云南来自Android客户端1楼2016-06-10 01:40回复
    经过昨天与今天的研究,以及多方讨教,才疏学浅的本人了解了游戏中Player的Hunger值的Setting与Getting。
    那么,接下来就将至分享于众,如有疏漏,敬请联系本人修改。


    IP属地:云南来自Android客户端2楼2016-06-10 01:40
    回复
      2026-01-05 21:06:29
      广告
      不感兴趣
      开通SVIP免广告
      注意,代码中有三句:
      BL _ZNK17AttributeInstance15getCurrentValueEv
      BL _ZNK17AttributeInstance15getDefaultValueEi
      VCMPE.F32 S16, S15
      很明显,第一句是获取现在的饥饿值,第二句是获取饥饿值的默认值,也就是最大值,然后作比较,得到结果。
      而稍懂的人,就知道要是想调用调用一个非静态类成员函数,则必须拥有该类的指针,并以此充当第一个参数来调用这个非静态类成员函数。


      IP属地:云南来自Android客户端4楼2016-06-10 01:41
      回复
        可能有的Modder发现了,Player和Mob明明是两个类,为什么Player可以调用Mob的函数,这是因为Player类继承自Mob类。
        当然这不是我们讨论的重点,我们言归正传。
        前面提到,游戏调用了AttributeInstance::getCurrentValue获取了饥饿值,那这返回值,一定便是AttributeInstance指针或引用了。
        那么,我们再看看Mob::getAttribute的参数,他有几个参数?严格来说是两个,类指针为第一个参数,Attribute const&为第二个。
        第一个很好解决啊,我们获取Player的指针传进去就好(不知道怎么获取Player的Modder可以参考我的另一篇教程贴),那么第二个参数呢?好,我们又懵逼了。这时候应该再看看汇编代码。
        我们看看这几句:
        ADD R1, PC ; off_7580F8
        LDR R1, [R1] ; Player::HUNGER


        IP属地:云南来自Android客户端6楼2016-06-10 01:42
        回复
          ---Code---
          AttributeInstance* ins = player->getAttribute(Player::HUNGER);
          float hunger = ins->getCurrentValue();
          ---Code---


          IP属地:云南来自Android客户端8楼2016-06-10 01:43
          回复
            很简单,但是,等等,我们怎么修改它?于是我们在AttributeInstance类了找一下有没有set相关的函数。
            倒是真找到了,AttributeInstance::serialitionSetValue(float, int);
            第一个参数好说,一看float不就是我们想设置的值了,那第二个呢?于是再一次懵逼了……
            好吧,我也不知道第二是参数是什么(当然,现在我倒是知道了,如果有兴趣了解,可以查看文章末尾)


            IP属地:云南来自Android客户端9楼2016-06-10 01:43
            回复
              不过我却想到了另一个方法,我们既然可以通过AttributeInstance::getCurrentValue获取饥饿值,那么,如果我们逆向操作,不就可以更改值了?
              于是我们需要反汇编AttributeInstance::getCurrentValue函数。
              具体汇编代码如下:
              AttributeInstance::getCurrentValue(void) const:
              LDR R0, [R0, #0x4C]
              BX LR


              IP属地:云南来自Android客户端10楼2016-06-10 01:44
              回复
                我们第三次说一下,这里R0是隐藏的第一个参数,储存类指针。
                而读值到R0然后BX跳回,这就是要将读到的值作为返回值了。
                ---科普---
                LDR: 加载一个立即数或一个地址内的值到指定寄存器。
                B: 跳转指令,使用结合情况判断使用,BX作用为跳转到指定地址,并且可以切换ARM与THUMB模式。
                ---科普---
                所以,这就意味着AttributeInstance+76就是当前值的储存位置。


                IP属地:云南来自Android客户端11楼2016-06-10 01:44
                回复
                  2026-01-05 21:00:29
                  广告
                  不感兴趣
                  开通SVIP免广告
                  那么,我们这么改一下AttributeInstance类的定义,加一点东西就好。
                  ---Code---
                  class AttributeInstance {
                  char filler[76];
                  float value;
                  // ...
                  };
                  ---Code---
                  然后我们就可以根据这个来修改饥饿值了,代码如下:
                  ---Code---
                  AttributeInstance* ins = player->getAttribute(Player::HUNGER);
                  ins->value = 20;
                  ---Code---


                  IP属地:云南来自Android客户端12楼2016-06-10 01:44
                  回复
                    好吧,我承认这个方法不是最好的。而我也研究出了更好的方法,但因为篇幅已经足够长,便不继续写下去了,只是公布函数用法,不公布研究方法。
                    AttributeInstance::serializationSetValue(Value, Type);
                    Value为欲设置的值
                    Type为欲设置的值的类型,1为最小值,2为当前值
                    也就是说,上面的通过偏移更改的方法,可以修改为:
                    ---Code---
                    AttributeInstance* ins = player->getAttribute(Player::HUNGER);
                    ins->serializationSetValue(20, 2);
                    ---Code---


                    IP属地:云南来自Android客户端13楼2016-06-10 01:45
                    回复
                      所以本贴到此就差不多完结了,如果你对文章有什么意见或建议,又或者你发现文中有错误的地方,欢迎指出,期待你的不吝赐教。


                      IP属地:云南来自Android客户端14楼2016-06-10 01:45
                      收起回复
                        不错


                        IP属地:浙江来自Android客户端15楼2016-06-10 02:02
                        收起回复
                          必须顶!


                          IP属地:广东来自Android客户端16楼2016-06-10 10:25
                          收起回复
                            看不懂


                            来自Android客户端17楼2016-06-10 15:52
                            收起回复
                              2026-01-05 20:54:29
                              广告
                              不感兴趣
                              开通SVIP免广告


                              来自Android客户端18楼2016-06-10 17:26
                              收起回复