当前位置: 首页 > article >正文

Unity类银河战士恶魔城学习总结(P146 Delete Save file-P147 Encryption of save data删除数据和加密数据)

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili

教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/

本章节实现了快速删除存档加密存档

以下是加密前和加密后的对比

SaveManager.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;



//2024.11.25
public class SaveManager : MonoBehaviour
{
    public static SaveManager instance;

    [SerializeField] private string fileName;
    [SerializeField] private bool encryptData;

    private GameData gameData;
    private List<ISaveManager> saveManagers = new List<ISaveManager>();
    private FileDataHandler dataHandler;


    [ContextMenu("Delete save file")]
    private void DeleteSaveData()
    {
        dataHandler = new FileDataHandler(Application.persistentDataPath, fileName, encryptData);
        dataHandler.Delete();
    }

    private void Awake()
    {
        if (instance != null)
            Destroy(instance.gameObject);
        else
            instance = this;
    }

    private void Start()
    {
        dataHandler = new FileDataHandler(Application.persistentDataPath,fileName, encryptData);
        saveManagers = FindAllSaveManagers();

        LoadGame();
    }


    public void NewGame()
    {
        gameData = new GameData();
    }


    public void LoadGame()
    {
        gameData = dataHandler.Load();

        if (this.gameData == null)
        {
            Debug.Log("没有找到存档");
            NewGame();
        }

        foreach (ISaveManager saveManager in saveManagers)
        {
            saveManager.LoadData(gameData);
        }

        
    }


    public void SaveGame()
    {
        foreach(ISaveManager saveManager in saveManagers)
        {
            saveManager.SaveData(ref gameData);
        }

        dataHandler.Save(gameData);
    }


    private void OnApplicationQuit()
    {
        SaveGame();
    }


    private List<ISaveManager> FindAllSaveManagers()
    {
        IEnumerable<ISaveManager> saveManagers = FindObjectsOfType<MonoBehaviour>(true).OfType<ISaveManager>();

        return new List<ISaveManager>(saveManagers);

    }
}

FileDataHandler.cs

Save 方法

  • 功能:将 GameData 数据保存到指定路径的文件中。
  • 核心逻辑
    1. 创建完整路径:通过 Path.Combine 组合文件夹路径和文件名。
    2. 确保文件夹存在:调用 Directory.CreateDirectory 确保路径中的文件夹被创建。
    3. 序列化数据:使用 JsonUtility.ToJsonGameData 对象转为 JSON 格式的字符串。
    4. 加密数据(可选):如果 encrypDatatrue,调用 EncryptDecrypt 方法加密数据。
    5. 写入文件:通过 FileStreamStreamWriter 写入数据到文件。
    6. 异常处理:捕获并报告文件操作可能抛出的异常。

Load 方法

  • 功能:从文件中读取数据并反序列化为 GameData 对象。
  • 核心逻辑
    1. 创建完整路径:和 Save 方法类似,通过 Path.Combine 拼接路径。
    2. 检查文件是否存在:通过 File.Exists 判断文件是否存在。
    3. 读取数据:使用 FileStreamStreamReader 读取文件内容。
    4. 解密数据(可选):如果 encrypDatatrue,调用 EncryptDecrypt 解密数据。
    5. 反序列化:使用 JsonUtility.FromJson 将 JSON 字符串解析为 GameData 对象。
    6. 异常处理:捕获读取过程中的异常并报告。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.IO;

//2024.11.27
public class FileDataHandler
{
    private string dataDirPath = "";//数据文件夹路径
    private string dataFileName = "";//数据文件名

    private bool encrypData=false;//是否加密数据
    private string codeWord = "FuNignNa";//加密密码



    public FileDataHandler(string _dataDirPath, string _dataFileName, bool encrypData)
    {
        dataDirPath = _dataDirPath;
        dataFileName = _dataFileName;
        this.encrypData = encrypData;
        
    }

    public void Save(GameData _data)
    {
        string fullPath = Path.Combine(dataDirPath, dataFileName);


        try
        {
            Directory.CreateDirectory(Path.GetDirectoryName(fullPath));//确保路径中的文件夹被创建

            string dataToStore = JsonUtility.ToJson(_data, true);//将数据转换为json格式

            if (encrypData)
                dataToStore = EncryptDecrypt(dataToStore);//加密数据

            using (FileStream stream = new FileStream(fullPath, FileMode.Create))
            {
                using (StreamWriter writer = new StreamWriter(stream))
                {
                    writer.Write(dataToStore);
                }
            }

        }

        catch (Exception e)
        {
            Debug.LogError("保存数据错误: " + fullPath + "\n" + e);
        }
    }

    public GameData Load()
    {
        string fullPath = Path.Combine(dataDirPath, dataFileName);//找到文件路径
        GameData loadData = null;

        if (File.Exists(fullPath))
        {
            try
            {
                string dataToLoad = "";

                using (FileStream stream = new FileStream(fullPath, FileMode.Open))//打开文件
                {
                    using (StreamReader reader = new StreamReader(stream))//读取文件
                    {
                        dataToLoad = reader.ReadToEnd();//读取文件
                    }
                }

                if (encrypData)
                    dataToLoad = EncryptDecrypt(dataToLoad);//解密数据

                loadData = JsonUtility.FromJson<GameData>(dataToLoad);

            }

            catch (Exception e)
            {
                Debug.LogError("读取数据错误: " + fullPath + "\n" + e);
            }
        }


        return loadData;
    }


    public void Delete()//删除数据
    {
        string fullPath = Path.Combine(dataDirPath, dataFileName);//找到文件路径

        if (File.Exists(fullPath))//如果文件存在就删除s
            File.Delete(fullPath);

    }

    private string EncryptDecrypt(string _data)//加密解密
    {
        string modifiedData = "";//修改后的数据

        for (int i = 0; i < _data.Length; i++)
        {
            modifiedData += (char)(_data[i] ^ codeWord[i % codeWord.Length]);  
        }

        return modifiedData;
    }
}


http://www.kler.cn/a/413000.html

相关文章:

  • 一、Java 动态字节码增强技术概述
  • 【附录】Rust国内镜像设置
  • 如何使用OCR技术批量识别图片中的文字并重命名文件,OCR 技术批量识别图片中的文字可能出现的错误
  • 爬虫开发(5)如何写一个CSDN热门榜爬虫小程序
  • 学习Java的日子 Day56 数据库连接池,Druid连接池
  • Oracle SQL优化②——访问路径
  • 软件测试丨Pytest生命周期与数据驱动
  • 下载安装Android Studio
  • C++模板(入门)
  • Go错误与日志处理—推荐实践
  • STM32F103系列单片机通用和复用I/O(GPIO)
  • 容器和它的隔离机制
  • linux模拟HID USB设备及wireshark USB抓包配置
  • 最小生成树-Prim与Kruskal算法
  • day25|leetCode 491.递增子序列,46.全排列 ,47.全排列 II
  • 算法——四数相加 二(leetcode454)
  • 预处理指令
  • Java线程同步Synchronized
  • Kadb中的ecpg编程
  • 如何开发历史题材游戏。
  • C++练级计划->《单例模式》懒汉和饿汉
  • 使用PHP实现用户权限控制系统
  • c++的虚继承说明、案例、代码
  • 网络药理学之薛定谔Schrödinge Maestro:6、分子对接(Glide、Ligand docking)和可视化
  • 【人工智能】Python常用库-TensorFlow常用方法教程
  • C语言编译和链接讲解