using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Runtime.Serialization.Formatters.Binary; using System.IO; using System; using MiniJSON; /// <summary> /// /// </summary> public static class SharePrefs { //================================================================================= //共通 //================================================================================= private const string PASS = "testmima123"; private const string DIRECTORY_NAME = "Data"; private static string EncryptKey(string sourceString) { System.Security.Cryptography.RijndaelManaged rijndael = new System.Security.Cryptography.RijndaelManaged(); //パスワードから共有キーと初期化ベクタを作成 byte[] key, iv; GenerateKeyFromPassword( rijndael.KeySize, out key, rijndael.BlockSize, out iv); rijndael.Key = key; rijndael.IV = iv; //文字列をバイト型配列に変換する byte[] strBytes = System.Text.Encoding.UTF8.GetBytes(sourceString); //対称暗号化オブジェクトの作成 System.Security.Cryptography.ICryptoTransform encryptor = rijndael.CreateEncryptor(); //バイト型配列を暗号化する byte[] encBytes = encryptor.TransformFinalBlock(strBytes, 0, strBytes.Length); //閉じる encryptor.Dispose(); //バイト型配列を文字列に変換して返す return System.Convert.ToBase64String(encBytes); } private static string EncryptValue(string value){ return EncryptKey(value); } internal static void Save(Dictionary<string, int> saveDict, string v) { throw new NotImplementedException(); } private static string DecryptValue(string value){ //RijndaelManagedオブジェクトを作成 System.Security.Cryptography.RijndaelManaged rijndael = new System.Security.Cryptography.RijndaelManaged(); //パスワードから共有キーと初期化ベクタを作成 byte[] key, iv; GenerateKeyFromPassword( rijndael.KeySize, out key, rijndael.BlockSize, out iv); rijndael.Key = key; rijndael.IV = iv; //文字列をバイト型配列に戻す byte[] strBytes = System.Convert.FromBase64String(value); //対称暗号化オブジェクトの作成 System.Security.Cryptography.ICryptoTransform decryptor = rijndael.CreateDecryptor(); //バイト型配列を復号化する //復号化に失敗すると例外CryptographicExceptionが発生 byte[] decBytes = decryptor.TransformFinalBlock(strBytes, 0, strBytes.Length); //閉じる decryptor.Dispose(); //バイト型配列を文字列に戻して返す return System.Text.Encoding.UTF8.GetString(decBytes); } private static void GenerateKeyFromPassword(int keySize, out byte[] key, int blockSize, out byte[] iv) { //パスワードから共有キーと初期化ベクタを作成する //saltを決める byte[] salt = System.Text.Encoding.UTF8.GetBytes("saltは必ず8バイト以上"); //Rfc2898DeriveBytesオブジェクトを作成する System.Security.Cryptography.Rfc2898DeriveBytes deriveBytes = new System.Security.Cryptography.Rfc2898DeriveBytes(PASS, salt); //反復処理回数を指定する デフォルトで1000回 deriveBytes.IterationCount = 1000; //共有キーと初期化ベクタを生成する key = deriveBytes.GetBytes(keySize / 8); iv = deriveBytes.GetBytes(blockSize / 8); } private static string LoadAndDecryptValue(string key){ string str = PlayerPrefs.GetString (EncryptKey(key), ""); if(string.IsNullOrEmpty(str)){ return ""; } return DecryptValue (str); } //================================================================================= //保存 //================================================================================= public static void Save(string key , int value){ PlayerPrefs.SetString (EncryptKey(key), EncryptValue(value.ToString()) ); } public static void Save(string key , float value){ PlayerPrefs.SetString (EncryptKey(key), EncryptValue(value.ToString()) ); } public static void Save(string key , string value){ PlayerPrefs.SetString (EncryptKey(key), EncryptValue(value) ); } public static void Save(string key, bool value){ if(value){ PlayerPrefs.SetString (key, key); } else{ PlayerPrefs.SetString (key, ""); } } //================================================================================= // //================================================================================= public static int Load(string key, int defaultValue){ string valueStr = LoadAndDecryptValue (key); if(string.IsNullOrEmpty(valueStr)){ return defaultValue; } return int.Parse (valueStr); } public static float Load(string key, float defaultValue){ string valueStr = LoadAndDecryptValue (key); if(string.IsNullOrEmpty(valueStr)){ return defaultValue; } return float.Parse (valueStr); } public static string Load(string key, string defaultValue){ string valueStr = LoadAndDecryptValue (key); if(string.IsNullOrEmpty(valueStr)){ return defaultValue; } return valueStr; } //================================================================================= // //================================================================================= private static string GetFilePath(string fileName) { string directoryPath = Application.persistentDataPath + "/" + DIRECTORY_NAME; //ディレクトリが無ければ作成 if(!Directory.Exists(directoryPath)) { Directory.CreateDirectory(directoryPath); } //ファイル名は暗号化する string encryptedFlieName = EncryptKey(fileName); string filePath = directoryPath + "/" + encryptedFlieName; //string filePath = directoryPath + "/" + fileName; return filePath; } public static void Save(Dictionary<string, object> dic, string fileName) { string jsonStr = Json.Serialize(dic); Debug.Log("serialized text = " + jsonStr); //jsonを暗号化する jsonStr = EncryptKey(jsonStr); string filePath = GetFilePath(fileName); File.WriteAllText(filePath, jsonStr); Debug.Log("saveFilePath = " + filePath); } public static Dictionary<string, object> Load(string fileName) { string filePath = GetFilePath(fileName); if(!File.Exists(filePath)) { return null; } string jsonStr = File.ReadAllText(filePath); jsonStr = DecryptValue(jsonStr); Dictionary<string, object> dic = Json.Deserialize(jsonStr) as Dictionary<string, object>; return dic; } }
/* * Copyright (c) 2013 Calvin Rien * * Based on the JSON parser by Patrick van Bergen * http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html * * Simplified it so that it doesn't throw exceptions * and can be used in Unity iPhone with maximum code stripping. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Text; namespace MiniJSON { // Example usage: // // using UnityEngine; // using System.Collections; // using System.Collections.Generic; // using MiniJSON; // // public class MiniJSONTest : MonoBehaviour { // void Start () { // var jsonString = "{ \"array\": [1.44,2,3], " + // "\"object\": {\"key1\":\"value1\", \"key2\":256}, " + // "\"string\": \"The quick brown fox \\\"jumps\\\" over the lazy dog \", " + // "\"unicode\": \"\\u3041 Men\u00fa sesi\u00f3n\", " + // "\"int\": 65536, " + // "\"float\": 3.1415926, " + // "\"bool\": true, " + // "\"null\": null }"; // // var dict = Json.Deserialize(jsonString) as Dictionary<string,object>; // // Debug.Log("deserialized: " + dict.GetType()); // Debug.Log("dict['array'][0]: " + ((List<object>) dict["array"])[0]); // Debug.Log("dict['string']: " + (string) dict["string"]); // Debug.Log("dict['float']: " + (double) dict["float"]); // floats come out as doubles // Debug.Log("dict['int']: " + (long) dict["int"]); // ints come out as longs // Debug.Log("dict['unicode']: " + (string) dict["unicode"]); // // var str = Json.Serialize(dict); // // Debug.Log("serialized: " + str); // } // } /// <summary> /// This class encodes and decodes JSON strings. /// Spec. details, see http://www.json.org/ /// /// JSON uses Arrays and Objects. These correspond here to the datatypes IList and IDictionary. /// All numbers are parsed to doubles. /// </summary> public static class Json { /// <summary> /// Parses the string json into a value /// </summary> /// <param name="json">A JSON string.</param> /// <returns>An List<object>, a Dictionary<string, object>, a double, an integer,a string, null, true, or false</returns> public static object Deserialize(string json) { // save the string for debug information if (json == null) { return null; } return Parser.Parse(json); } sealed class Parser : IDisposable { const string WORD_BREAK = "{}[],:\""; public static bool IsWordBreak(char c) { return Char.IsWhiteSpace(c) || WORD_BREAK.IndexOf(c) != -1; } enum TOKEN { NONE, CURLY_OPEN, CURLY_CLOSE, SQUARED_OPEN, SQUARED_CLOSE, COLON, COMMA, STRING, NUMBER, TRUE, FALSE, NULL }; StringReader json; Parser(string jsonString) { json = new StringReader(jsonString); } public static object Parse(string jsonString) { using (var instance = new Parser(jsonString)) { return instance.ParseValue(); } } public void Dispose() { json.Dispose(); json = null; } Dictionary<string, object> ParseObject() { Dictionary<string, object> table = new Dictionary<string, object>(); // ditch opening brace json.Read(); // { while (true) { switch (NextToken) { case TOKEN.NONE: return null; case TOKEN.COMMA: continue; case TOKEN.CURLY_CLOSE: return table; default: // name string name = ParseString(); if (name == null) { return null; } // : if (NextToken != TOKEN.COLON) { return null; } // ditch the colon json.Read(); // value table[name] = ParseValue(); break; } } } List<object> ParseArray() { List<object> array = new List<object>(); // ditch opening bracket json.Read(); // [ var parsing = true; while (parsing) { TOKEN nextToken = NextToken; switch (nextToken) { case TOKEN.NONE: return null; case TOKEN.COMMA: continue; case TOKEN.SQUARED_CLOSE: parsing = false; break; default: object value = ParseByToken(nextToken); array.Add(value); break; } } return array; } object ParseValue() { TOKEN nextToken = NextToken; return ParseByToken(nextToken); } object ParseByToken(TOKEN token) { switch (token) { case TOKEN.STRING: return ParseString(); case TOKEN.NUMBER: return ParseNumber(); case TOKEN.CURLY_OPEN: return ParseObject(); case TOKEN.SQUARED_OPEN: return ParseArray(); case TOKEN.TRUE: return true; case TOKEN.FALSE: return false; case TOKEN.NULL: return null; default: return null; } } string ParseString() { StringBuilder s = new StringBuilder(); char c; // ditch opening quote json.Read(); bool parsing = true; while (parsing) { if (json.Peek() == -1) { parsing = false; break; } c = NextChar; switch (c) { case '"': parsing = false; break; case '\\': if (json.Peek() == -1) { parsing = false; break; } c = NextChar; switch (c) { case '"': case '\\': case '/': s.Append(c); break; case 'b': s.Append('\b'); break; case 'f': s.Append('\f'); break; case 'n': s.Append('\n'); break; case 'r': s.Append('\r'); break; case 't': s.Append('\t'); break; case 'u': var hex = new char[4]; for (int i=0; i< 4; i++) { hex[i] = NextChar; } s.Append((char) Convert.ToInt32(new string(hex), 16)); break; } break; default: s.Append(c); break; } } return s.ToString(); } object ParseNumber() { string number = NextWord; if (number.IndexOf('.') == -1) { long parsedInt; Int64.TryParse(number, out parsedInt); return parsedInt; } double parsedDouble; Double.TryParse(number, out parsedDouble); return parsedDouble; } void EatWhitespace() { while (Char.IsWhiteSpace(PeekChar)) { json.Read(); if (json.Peek() == -1) { break; } } } char PeekChar { get { return Convert.ToChar(json.Peek()); } } char NextChar { get { return Convert.ToChar(json.Read()); } } string NextWord { get { StringBuilder word = new StringBuilder(); while (!IsWordBreak(PeekChar)) { word.Append(NextChar); if (json.Peek() == -1) { break; } } return word.ToString(); } } TOKEN NextToken { get { EatWhitespace(); if (json.Peek() == -1) { return TOKEN.NONE; } switch (PeekChar) { case '{': return TOKEN.CURLY_OPEN; case '}': json.Read(); return TOKEN.CURLY_CLOSE; case '[': return TOKEN.SQUARED_OPEN; case ']': json.Read(); return TOKEN.SQUARED_CLOSE; case ',': json.Read(); return TOKEN.COMMA; case '"': return TOKEN.STRING; case ':': return TOKEN.COLON; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '-': return TOKEN.NUMBER; } switch (NextWord) { case "false": return TOKEN.FALSE; case "true": return TOKEN.TRUE; case "null": return TOKEN.NULL; } return TOKEN.NONE; } } } /// <summary> /// Converts a IDictionary / IList object or a simple type (string, int, etc.) into a JSON string /// </summary> /// <param name="json">A Dictionary<string, object> / List<object></param> /// <returns>A JSON encoded string, or null if object 'json' is not serializable</returns> public static string Serialize(object obj) { return Serializer.Serialize(obj); } sealed class Serializer { StringBuilder builder; Serializer() { builder = new StringBuilder(); } public static string Serialize(object obj) { var instance = new Serializer(); instance.SerializeValue(obj); return instance.builder.ToString(); } void SerializeValue(object value) { IList asList; IDictionary asDict; string asStr; if (value == null) { builder.Append("null"); } else if ((asStr = value as string) != null) { SerializeString(asStr); } else if (value is bool) { builder.Append((bool) value ? "true" : "false"); } else if ((asList = value as IList) != null) { SerializeArray(asList); } else if ((asDict = value as IDictionary) != null) { SerializeObject(asDict); } else if (value is char) { SerializeString(new string((char) value, 1)); } else { SerializeOther(value); } } void SerializeObject(IDictionary obj) { bool first = true; builder.Append('{'); foreach (object e in obj.Keys) { if (!first) { builder.Append(','); } SerializeString(e.ToString()); builder.Append(':'); SerializeValue(obj[e]); first = false; } builder.Append('}'); } void SerializeArray(IList anArray) { builder.Append('['); bool first = true; foreach (object obj in anArray) { if (!first) { builder.Append(','); } SerializeValue(obj); first = false; } builder.Append(']'); } void SerializeString(string str) { builder.Append('\"'); char[] charArray = str.ToCharArray(); foreach (var c in charArray) { switch (c) { case '"': builder.Append("\\\""); break; case '\\': builder.Append("\\\\"); break; case '\b': builder.Append("\\b"); break; case '\f': builder.Append("\\f"); break; case '\n': builder.Append("\\n"); break; case '\r': builder.Append("\\r"); break; case '\t': builder.Append("\\t"); break; default: int codepoint = Convert.ToInt32(c); if ((codepoint >= 32) && (codepoint <= 126)) { builder.Append(c); } else { builder.Append("\\u"); builder.Append(codepoint.ToString("x4")); } break; } } builder.Append('\"'); } void SerializeOther(object value) { // NOTE: decimals lose precision during serialization. // They always have, I'm just letting you know. // Previously floats and doubles lost precision too. if (value is float) { builder.Append(((float) value).ToString("R")); } else if (value is int || value is uint || value is long || value is sbyte || value is byte || value is short || value is ushort || value is ulong) { builder.Append(value); } else if (value is double || value is decimal) { builder.Append(Convert.ToDouble(value).ToString("R")); } else { SerializeString(value.ToString()); } } } } }
相关推荐
正在进行下一个游戏项目吗? 需要一种简单的方法来保存和加载游戏吗? 不确定如何保存和加载游戏?这是适合您的插件。...提供AES加密的存档 自动保存和加载选项 支持WebGL! 包括自定义可保存字典类型。
Easy Save 是专门为 Unity 开发者设计的一款数据存储和加载工具。它旨在简化数据保存和恢复的过程,使开发者能够专注于游戏的核心逻辑,而不必在数据管理上花费过多的精力。 二、主要特点 (一)多种数据类型支持 ...
支持几乎所有常见的数据类型,包括整数、浮点数、字符串、数组、字典、自定义类等。 例如,可以轻松保存玩家的得分、等级、装备信息以及游戏中的各种配置参数。 (二)简单易用的 API 提供了简洁直观的 API 接口,...
实际项目中,用户数据应安全地存储在服务器上,而非本地,且通常会涉及到加密和哈希处理,以保护用户的隐私。 7. **界面切换**: 注册按钮点击后,登录面板隐藏,注册面板显示,这通过改变游戏对象的`SetActive`...
这部分描述了如何保护数据库免受未经授权的访问,包括用户权限设置、加密机制以及备份恢复策略,以保障数据的安全性和完整性。 5. 数据库验证验收标准 5.1 数据库数据体的验收 这部分规定了数据库内容的验证标准,...
8. **用户界面交互**:登录成功后,`LoginUI` 对象(登录界面)将被设置为非活动状态,而 `ShopUI` 对象(商店界面)将被激活,这表明用户已经登录并进入了商店界面。 9. **资源管理**:在登录和注册操作完成后,`...
- **加密技术**:使用加密算法保护敏感信息不被泄露。 #### 八、性能优化与部署 - **缓存机制**:页面输出缓存、数据缓存等提高响应速度。 - **代码优化**:减少不必要的网络请求,优化数据库查询逻辑。 - **部署...
由于标题并未提供过多细节,我们可以推测它可能是由个人开发者或者小团队创建的,旨在提供一种独特的游戏体验。 【描述】:“bossgame”的描述没有给出具体的细节,这使得我们只能根据通用的游戏开发框架来推测可能...
3. **集合与泛型**:数组、列表、字典等集合类型的使用,以及泛型的原理和应用。 4. **委托与事件**:事件驱动编程,委托和事件的使用,以及Lambda表达式。 5. **Lambda表达式与 LINQ**:C#中的Lambda表达式,用于...
4. **集合与数据结构**:涵盖数组、列表、队列、栈、字典等各种内置集合类型的使用方法,以及它们在实际问题中的应用。 5. **异常处理**:讲解如何使用try-catch-finally语句捕获和处理运行时错误,以及自定义异常...