2021-10-28

项目准备

首先是文件准备工作,既然要更改文件,首先我们要知道自己所要更改的文件在哪里,这里我们在C盘的隐藏文件夹中寻找,一般情况下植物大战僵尸的数据文件的路径是C:\ProgramData\PopCap Games\PlantsVsZombies\userdata\user1.dat。也就是我们这次所要处理的文件路径。
接下来是我们要想好怎么去读取并修改文件。因为对于.dat后缀的文件我们无法直接用常用的诸如notepad的文件去打开和更改,因为打开的文件一定是乱码的状态。对于解决这个问题,我的思路是用DataInputStream类和DataOutputStream类实现对数据文件的读取和修改。

项目过程

读取文件

对于文件的读取,我们先定义文件流再定义文件数据流(即DataInputStream dis = new DataInputStream(new FileInputStream(“文件名”));)注意!使用数据流类时一定要记得用try/catch语句包含起来,防止报错,最后调用数据流的read()方法进行读取并将其一一存入byte数组中,并将数组输出。

public static void main(String[] args) {
        String fl = "C:\\ProgramData\\PopCap Games\\PlantsVsZombies\\userdata\\user1.dat";
        byte[] b = new byte[1024];
        try {
            DataInputStream dis = new DataInputStream(new FileInputStream(fl));
            dis.read(b);
            int count = 0;
            for (byte a: b) {
                System.out.print(a+" ");
                count++;
                if(count == 16){
                    System.out.println();
                    count = 0;
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

运行结果:
请添加图片描述
要注意的是这个运行结果可能不会相同,因为大家的游戏进度不一所以数据文件的内容也不一。

修改数据文件使得植物大战僵尸游戏内实现跳关

通过刚刚的操作我们实现了对于数据文件的读取并且将其写入了我们的byte数组并将被写入后的byte数组输出,那么此时我们只要修改数组并可以将数组的值再写入文件就可以实现对于游戏数据文件的修改。
而如果要通过写入文件来实现我们所要求的跳关的操作的话需要思考两步问题一是怎么写入文件,二是怎么修改数组内容。
第一个问题,对于文件的写入,我们可以采用DataOutputStream类中的write()方法来实现,关键代码块:

 try {
            DataOutputStream dos = new DataOutputStream(new FileOutputStream(fl));
            try {
                dos.write(b);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

第二个问题也是最关键的问题,那就是我们如何才能实现跳关操作,我们细心观察我们byte的输出结果(我为了方便观察,采用了循环里加计数器的方式,将其分成了一行十六个的形式)在一行第四列的那个数字此时我们的所处的关卡进行对比
请添加图片描述
请添加图片描述

熟知植物大战僵尸的朋友,应该都知道植物大战僵尸每一大关都会十个小关,所以第1-1关就是第一关,而这第3-3关就是第二十三关,也就是说第一行第五列的数据记录着我们现在所处的关卡的数目,我们可以通过修改这个数字来修改我们在游戏中所处的关卡。而相应的要改的数字则取决于我们输入的p-q关来决定,即要跳转的关卡为(p-1)*10+q。相应的代码:

public static void main(String[] args) {
        String fl = "C:\\ProgramData\\PopCap Games\\PlantsVsZombies\\userdata\\user1.dat";
        byte[] b = new byte[1024];
        try {
            DataInputStream dis = new DataInputStream(new FileInputStream(fl));
            dis.read(b);
            int count = 0;
            for (byte a: b) {
                System.out.print(a+" ");
                count++;
                if(count == 16){
                    System.out.println();
                    count = 0;
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        Scanner scanner = new Scanner(System.in);
        System.out.println("是否修改关卡?修改请按1");
        if(scanner.nextInt() == 1){
            System.out.println("请输入修改到几-几关");
            int p = scanner.nextInt();
            int q = scanner.nextInt();
            while (p < 1 || p > 5 || q < 1 || q > 10){
                System.out.println("Error");
                System.out.println("请重新输入");
                p = scanner.nextInt();
                q = scanner.nextInt();
            }
            byte jump = (byte) ((p - 1) * 10 + q);
            b[4] = jump;
        }
        try {
            DataOutputStream dos = new DataOutputStream(new FileOutputStream(fl));
            try {
                dos.write(b);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

运行结果:
修改前:
请添加图片描述

请添加图片描述
修改后:
在这里插入图片描述

修改数据文件实现修改游戏内金币

要实现这个问题与实现跳关问题同理,我们都需要对byte数组进行一定的修改和写入,写入的操作和上个问题的的方式一样,这里就不过多赘述,主要的需要考虑的问题是对于byte数组要进行怎么样的修改。要弄清楚这个问题,首先我们需要理解这个问题的实质,实质在于读取文件后得到的是什么。其实这些数字实质上是用十六进制进行编码的,只不过我们的这个输出结果展示不出来,想要读取到这些我们可以通过Hex Editor Neo 软件来进行对数据文件的解析,所得到的就是一个16进制的表(感兴趣的朋友可以下载该软件后尝试下)。
当我们们观察相对应的表后,我们可以知道第九到十二列表示游戏内金币的数量,而又因为每一个数字的实质又是16进制计数,所以我们每一位数字都要用我们准备修改的金额对256取余来填充。对应代码:

public static void main(String[] args) {
        String fl = "C:\\ProgramData\\PopCap Games\\PlantsVsZombies\\userdata\\user1.dat";
        byte[] b = new byte[1024];
        try {
            DataInputStream dis = new DataInputStream(new FileInputStream(fl));
            dis.read(b);
            int count = 0;
            for (byte a: b) {
                System.out.print(a+" ");
                count++;
                if(count == 16){
                    System.out.println();
                    count = 0;
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        Scanner scanner = new Scanner(System.in);
        System.out.println("是否修改金币?修改请按1");
        if(scanner.nextInt() == 1){
            System.out.println("请输入修改到多少钱(x10)");
            int q = scanner.nextInt();
            while ( q < 0 || q > 999999999){
                System.out.println("Error");
                System.out.println("请重新输入");
                q = scanner.nextInt();
            }
            int coin = q;
            b[8] = (byte) (coin % 256);
            coin /= 256;
            b[9] = (byte) (coin % 256);
            coin /= 256;
            b[10] = (byte) (coin % 256);
            coin /= 256;
            b[11] = (byte) (coin % 256);
        }
        try {
            DataOutputStream dos = new DataOutputStream(new FileOutputStream(fl));
            try {
                dos.write(b);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

运行结果:
修改前:
请添加图片描述

请添加图片描述
修改后:
请添加图片描述

项目总结

这个任务整体来说不是很难,因为对于植物大战僵尸这款游戏来说,他的游戏容量不大,数据文件内容较少,我们可以很快上手,并且得益于Hex Editor Neo 软件的帮助我们可以更直观的了解到了数据文件中的内容含义,对于修改游戏数据内容方面的代码的书写也更加得心应手。第一次上手写博客,才疏学浅,大家切勿见怪。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值