Unity保存解析问题

时间:2018-07-07 15:31:48

标签: unity3d

当试图从简单的.gdsave(游戏开发保存,我制作的自定义文件,与.txt文件没有区别)中接收值时,我一直试图找出这个错误。此错误:

  

FormatException:无效的长度。   System.Convert.FromBase64String(System.String s)(位于/Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Convert.cs:146)   Assets.USecurity.AES.Decrypt(System.String值,System.String密码)(在Assets / USecurity / AES.cs:60处)   AESCrypt.EncryptDecrypt.AESDecrypt(System.String文件路径,System.String密码)(在Assets / Scripts / EncryptDecrypt.cs:38)   SaveSys.Display.parseData(Int32 indexGrab)(位于Assets / Scripts / UI / Display.cs:32)   TextToDisplay.Update()(位于Assets / Scripts / UI / TextToDisplay.cs:9)

我将在下面的脚本中添加任何帮助,如前所述,不幸的是我找不到答案。

Display.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Text;
using Assets.USecurity;
using AESCrypt;
using TMPro;

namespace SaveSys
{
    public class Display : MonoBehaviour {

        public static string parseData(int indexGrab) // Parse the info type to return
        {

            if (1 == 2) // If we are inside the editor, we'll cheat :D (STACK OVERFLOW IGNORE THIS, I KNOW)
            {
                return "editor";
            } else
            {
                string defaultPath = Application.dataPath; // Data storage

                if (Directory.Exists(defaultPath + "/saves")) // If the save folder exists
                {
                    string currentPath = Application.dataPath + "/saves"; // Grabbing the saves folder

                    if (File.Exists(currentPath + "/" + PlayerPrefs.GetString("CurrentSaveName", "save1.gdsav"))) // Checking if there is a save file for the current game
                    {
                        string gdsavePath = currentPath + "/" + PlayerPrefs.GetString("CurrentSaveName", "save1.gdsav"); // Grabbing the current save name

                        string[] arr = AESCrypt.EncryptDecrypt.AESDecrypt(Application.dataPath + "/saves/" + PlayerPrefs.GetString("CurrentSaveName", "save1.gdsav"), "default").Split(); // Decrypt and split data
                        return arr[indexGrab].ToString(); // Return the requested value
                    } else
                    {
                        File.WriteAllText(Application.dataPath + "/saves/" + PlayerPrefs.GetString("CurrentSaveName", "save1.gdsav"), ""); // Create save file
                        return "FileCreated";
                    }
                } else
                {
                    Directory.CreateDirectory(Application.dataPath + "/saves"); // Creates save directory
                    File.WriteAllText(Application.dataPath + "/saves/" + PlayerPrefs.GetString("CurrentSaveName", "save1.gdsav"), ""); // Create save file, as it could not exist

                    string newSave = Application.dataPath + "/saves/" + PlayerPrefs.GetString("CurrentSaveName", "save1.gdsav"); // Get the save file

                    AESCrypt.EncryptDecrypt.AESEncrypt(newSave, "Default"); // Encrypt the file
                    return "FileCreated+Dir";
                }
            }
        }

        public static string changeData(string changingData)
        {
            string[] args = changingData.Split(); // Splits up the input given by UI, other scripts etc, so "0 CompanyName" becomes "0", "CompanyName"
            int index = int.Parse(args[0]); // The data to change has an args position of 0, therefor index = 0, to detect the type of data we're modifying

            // To see more about above, goto https://docs.google.com/document/d/167kAoNZddcd6k36auk7_unCegCGl4sgJ8ojjddoAmx0/edit?usp=sharing

            //foreach(string x in args) - debugging
            //{
                //print(x);
            //}
            string[] arr = File.ReadAllLines(Application.dataPath + "/saves/" + PlayerPrefs.GetString("CurrentSaveName", "save1.gdsav")); //AESCrypt.EncryptDecrypt.AESDecrypt(Application.dataPath + "/saves/" + PlayerPrefs.GetString("CurrentSaveName", "save1.gdsav"), "default").Split(); // Decrypt and split data
            if (arr.Length > int.Parse(args[0])) // If the array isn't out of range
            {

                print(index);
                print(arr.Length);
                print(args.Length);

                arr[index] = args[1].ToString(); // Changing the data's value to the second string in the array
                File.WriteAllLines(Application.dataPath + "/saves/" + PlayerPrefs.GetString("CurrentSaveName", "save1.gdsav"), arr); // Write modified data to the file
                AESCrypt.EncryptDecrypt.AESEncrypt(Application.dataPath + "/saves/" + PlayerPrefs.GetString("CurrentSaveName", "save1.gdsav"), "default"); // Encrypt the file

                return "Complete";
            }

            return "Failed";

        }   
    }
}

TextToDisplay.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using SaveSys;
public class TextToDisplay : MonoBehaviour {
    public int inde;
    void Update () {
        print(SaveSys.Display.parseData(inde));
        this.gameObject.GetComponent<TextMeshProUGUI>().text = SaveSys.Display.parseData(inde);
    }
}

EncryptDecrypt.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Text;
using Assets.USecurity;

namespace AESCrypt {
    public class EncryptDecrypt : MonoBehaviour {

        public static string AESEncrypt(string filepath, string password) // Encryption method
            {
                if (password == "default") // Keyword for default password
                {
                    password = "gdevaesencrypt"; // Default password if not specified
                    string fileText = File.ReadAllText(filepath); // Grabbing all lines to convert them
                    string encrypted = AES.Encrypt(fileText, password); // Setting encrypted to the encrypted string

                    File.WriteAllText(filepath, encrypted); // Write the encrypted value to the file
                    return encrypted;
                } else
                {
                    string fileText = File.ReadAllText(filepath); // Grabbing all lines to convert them
                    string encrypted = AES.Encrypt(fileText, password); // Setting encrypted to the encrypted string

                    File.WriteAllText(filepath, encrypted); // Write the encrypted value to the file
                    return encrypted;
                }

            }

            public static string AESDecrypt(string filepath, string password) // Encryption method
            {
                if (password == "default") // Keyword for default password
                {
                    password = "gdevaesencrypt"; // Default password if not specified
                    string fileText = File.ReadAllText(filepath); // Grabbing all lines to convert them
                    string decrypted = AES.Decrypt(fileText, password); // Setting decrypted to the encrypted string

                    return decrypted;
                } else
                {
                    string fileText = File.ReadAllText(filepath); // Grabbing all lines to convert them
                    string decrypted = AES.Decrypt(fileText, password); // Setting decrypted to the encrypted string

                    return decrypted;
                }
            }
    }
}

UI Elements.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using SaveSys;
using TMPro;
public class UIElements : MonoBehaviour {
    public int index;

    public void nameThing(TMP_InputField inp)
    {
        SaveSys.Display.changeData(inp.GetComponent<UIElements>().index + " " + inp.text);
    }
}

1 个答案:

答案 0 :(得分:0)

在创建目录的else中,您正在使用错误的密码创建文件,并使用带有大写D的“默认”。这是否可能引起问题?在此部分中创建文件时,也许还应该加密:

else
{
    File.WriteAllText(Application.dataPath + "/saves/" + PlayerPrefs.GetString("CurrentSaveName", "save1.gdsav"), ""); // Create save file
    return "FileCreated";
}