diff --git a/Assets/CrazyZoo/Runtime/Logic/ModuleUI/GameHome/GameHomeUI.cs b/Assets/CrazyZoo/Runtime/Logic/ModuleUI/GameHome/GameHomeUI.cs index 6ad1fa8..625efe9 100644 --- a/Assets/CrazyZoo/Runtime/Logic/ModuleUI/GameHome/GameHomeUI.cs +++ b/Assets/CrazyZoo/Runtime/Logic/ModuleUI/GameHome/GameHomeUI.cs @@ -79,11 +79,12 @@ namespace ScrewsMaster is_first_login_go_to_h5 = false; GameHelper.is_first_login = loginModel.new_player; - if (GameHelper.IsGiftSwitch() && !loginModel.new_player && is_first_login_go_to_h5) - { - GotoH5(); - } - else if (GameHelper.IsGiftSwitch() && loginModel.new_player) + // if (GameHelper.IsGiftSwitch() && !loginModel.new_player && is_first_login_go_to_h5) + // { + // GotoH5(); + // } + // else + if (loginModel.new_player) { UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.FirstRewardUI_Open); loginModel.new_player = false; diff --git a/Assets/CrazyZoo/Runtime/Logic/ModuleUI/SaveingPot/SaveingPotUI.cs b/Assets/CrazyZoo/Runtime/Logic/ModuleUI/SaveingPot/SaveingPotUI.cs index 6a1568b..74001ad 100644 --- a/Assets/CrazyZoo/Runtime/Logic/ModuleUI/SaveingPot/SaveingPotUI.cs +++ b/Assets/CrazyZoo/Runtime/Logic/ModuleUI/SaveingPot/SaveingPotUI.cs @@ -139,13 +139,19 @@ namespace ScrewsMaster ui.btn_cash.SetClick(() => { + if (UIManager.Instance.IsExistUI(UIConst.SheepPlayUI)) + { + CtrlCloseUI(); + } + else + { + var level = ShowScrews.Instance.gameMode == GameHome.Mode_difficult ? 1 : GameHelper.GetLevel(); ; + ShowScrews.Instance.InitLogic(level); + AudioManager.Instance.PlayBGM(AudioConst.PlayingBg); + CtrlCloseUI(); + UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.GameHomeUI_Close); + } - var level = ShowScrews.Instance.gameMode == GameHome.Mode_difficult ? 1 : GameHelper.GetLevel(); ; - ShowScrews.Instance.InitLogic(level); - - AudioManager.Instance.PlayBGM(AudioConst.PlayingBg); - CtrlCloseUI(); - UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.GameHomeUI_Close); // UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.BuygoldUI_Open, false); }); diff --git a/Assets/CrazyZoo/Runtime/Logic/System/Network/LoginSystem.cs b/Assets/CrazyZoo/Runtime/Logic/System/Network/LoginSystem.cs index 86d89f8..acf4cad 100644 --- a/Assets/CrazyZoo/Runtime/Logic/System/Network/LoginSystem.cs +++ b/Assets/CrazyZoo/Runtime/Logic/System/Network/LoginSystem.cs @@ -3,6 +3,8 @@ using System.Collections; namespace ScrewsMaster { using DG.Tweening; + using MYp0ZVTT2QSDK; + using Newtonsoft.Json; using UnityEngine; public class LoginSystem : BaseSystem @@ -103,6 +105,7 @@ namespace ScrewsMaster private void OnLoginSuccess(LoginModel loginData) { + Debug.Log(JsonConvert.SerializeObject(loginData)); var loginModel = GameHelper.GetLoginModel(); loginModel.cdn_url = loginData.cdn_url; loginModel.setting = loginData.setting; diff --git a/Assets/CrazyZoo/Runtime/Logic/ToolKit/NetworkKit.cs b/Assets/CrazyZoo/Runtime/Logic/ToolKit/NetworkKit.cs index b57340a..3f7ea06 100644 --- a/Assets/CrazyZoo/Runtime/Logic/ToolKit/NetworkKit.cs +++ b/Assets/CrazyZoo/Runtime/Logic/ToolKit/NetworkKit.cs @@ -66,10 +66,10 @@ namespace ScrewsMaster } SetRequestContentType(loginRequest); - Debug.Log($"request url1======= {url1}"); + // Debug.Log($"request url1======= {url1}"); yield return loginRequest.SendWebRequest(); - Debug.Log($"requestData11111======={url1}=={requestJson}"); - Debug.Log($"requestData22222====={url1}==={JsonConvert.SerializeObject(loginRequest)}"); + // Debug.Log($"requestData11111======={url1}=={requestJson}"); + // Debug.Log($"requestData22222====={url1}==={JsonConvert.SerializeObject(loginRequest)}"); if (loginRequest.result is not UnityWebRequest.Result.Success) { onCompleted?.Invoke(false, default); @@ -85,7 +85,7 @@ namespace ScrewsMaster receiveContent = Base64Kit.Decode(receiveContent); } #endif - Debug.Log(receiveContent); + // Debug.Log(receiveContent); var response = SerializeUtil.ToObject(receiveContent); @@ -181,10 +181,10 @@ namespace ScrewsMaster }; statusDic.Add(reqData.type, true); - Debug.Log($"PostFunnelLogin requestData1111========={reqData.type}"); + // Debug.Log($"PostFunnelLogin requestData1111========={reqData.type}"); Post("event/funnelLogin", requestData, (isSuccess, data) => { - Debug.Log($"PostFunnelLogin responseData2222========={isSuccess} {reqData.type}"); + // Debug.Log($"PostFunnelLogin responseData2222========={isSuccess} {reqData.type}"); }); } public static void SendLogToServer(RespDebugData reqData) @@ -273,7 +273,7 @@ namespace ScrewsMaster androidPointObject.@event = eventname; androidPointObject.property = eventproperty; androidPointObject.n = integer; - Debug.Log("打点" + JsonConvert.SerializeObject(androidPointObject)); + // Debug.Log("打点" + JsonConvert.SerializeObject(androidPointObject)); PostWithHeader("/event/incrN", androidPointObject, (isSuccess, obj) => { }); diff --git a/Assets/Resources/CrazyZooAssets/FGUI/G007_makeup_fui.bytes b/Assets/Resources/CrazyZooAssets/FGUI/G007_makeup_fui.bytes index 7285a19..7041778 100644 Binary files a/Assets/Resources/CrazyZooAssets/FGUI/G007_makeup_fui.bytes and b/Assets/Resources/CrazyZooAssets/FGUI/G007_makeup_fui.bytes differ diff --git a/Assets/Resources/CrazyZooAssets/TextAsset/Privacy.txt b/Assets/Resources/CrazyZooAssets/TextAsset/Privacy.txt index 6b5055a..319dfc1 100644 --- a/Assets/Resources/CrazyZooAssets/TextAsset/Privacy.txt +++ b/Assets/Resources/CrazyZooAssets/TextAsset/Privacy.txt @@ -1,40 +1,51 @@ -Welcome to Twist & Turn ("we," "our," or "us"). We value your privacy and are committed to safeguarding your personal information. This Privacy Policy outlines how we collect, use, store, and share your information, as well as your rights under applicable privacy laws, including the California Consumer Privacy Act (CCPA) and the Children's Online Privacy Protection Act (COPPA). -1. Information Collection -We may collect the following types of information while you use Twist & Turn: -- Device Information: Information about your device, such as device model, operating system version, unique identifiers (e.g., IDFA, GAID), IP address, browser type, language settings, and mobile network information. -- Game Usage Data: Information about your interactions with the game, such as progress, scores, achievements, in-game items, friends, activities, login times, and play duration. -- Location Information: With your consent, we may collect location data to provide location-based services, such as leaderboards or friend recommendations. -- Payment Information: When purchasing in-game items or services, we may collect transaction details. Payment processing is handled by third-party services, and we only receive confirmation of payment. -- Social Media Information: If you log in via social media or share game experiences, we may access publicly available information from your social account. -2. Information Use -We use the collected data for the following purposes: -- Game Operation and Maintenance: Ensuring the smooth operation of the game, fixing bugs, backing up data, and providing technical support. -- Customer Support: Assisting you when you contact our customer service. -- Personalization: Tailoring content, recommendations, advertisements, and offers based on your preferences and usage. -- Marketing Communications: Sending updates, event notifications, or promotional information, which you can opt-out of anytime. -- Analytics and Improvement: Conducting data analysis to improve game features and develop new services. -3. Information Sharing -We do not sell your personal information to third parties. We may share data in these cases: -- Legal Compliance: If required by law or government authorities. -- Business Transfers: In the event of a merger, acquisition, or transfer of assets. -- Service Providers: Trusted partners for payment processing, analytics, or advertising services, bound by confidentiality agreements. -4. Data Security and Retention -We take data protection seriously: -- Retention: We retain your data only as long as necessary to fulfill the purposes outlined. -- Security Measures: We use encryption and other methods to protect your data. -- Data Transfers: When transferring data outside your jurisdiction, we comply with relevant privacy laws. -5. Your Rights Under CCPA -If you are a California resident, you have the following rights under CCPA: -- Right to Know: Request information about data collection, usage, and sharing. -- Right to Delete: Request deletion of your personal information, with some exceptions. -- Right to Opt-Out: Prevent the sale of your data. -- Right to Non-Discrimination: Exercise your rights without facing discrimination. -To exercise these rights, contact us at mtop17600@gmail.com. -6. Children's Privacy Under COPPA -If we discover a user is under 13, we will obtain parental consent before collecting data, and process data only for game-related purposes. -7. Cookies and Tracking -We use cookies and similar tools for personalization and analytics. You can manage cookies through browser settings. -8. Policy Changes -We may update this Privacy Policy to reflect changes in legal requirements or our practices. Significant changes will be communicated via email or in-app notification. -9. Contact Us -For any questions, email us at mtop17600@gmail.com. \ No newline at end of file +Welcome to **Our game**! We take your privacy extremely seriously. This Privacy Policy outlines how we collect, use, store, and protect your personal data. Please read this policy thoroughly to understand how we manage your personal information. + +1. Introduction +Thank you for using **Our game**! We are committed to protecting your privacy and ensuring that your data is handled appropriately, providing you with a safe and enjoyable gaming experience. + +2. Information We Collect +We may gather the following types of data: +- Personal Details: Personal information you provide when creating an account or using the game, such as your name, email address, and phone number. +- Device Data: Technical specifications like device model, operating system version, and unique device identifiers (e.g., IMEI, IDFA). +- Usage Logs: Activity records, game progress, purchase history, achievements, and rankings within the game. +- Location Data: Geographical location information if you authorize us to collect it, to provide more tailored services. +- Third-Party Data: Information gathered through social media platforms or other external services, such as linked social accounts. + +3. Purpose of Using Information +We collect and use your data for the following reasons: +- Provide and Enhance Services: To deliver game services, optimize user experience, fix errors, and improve features, ensuring the stability and performance of the game. +- Personalized Content: To offer customized game content and recommendations based on your interests and preferences, enhancing your gaming experience. +- Marketing and Promotion: To send game updates, promotional activities, and news, boosting user engagement. +- Data Analysis: To analyze user behavior, assess game performance, and conduct market research, continuously refining game quality. +- Legal Compliance: To meet legal requirements and protect our legitimate interests, ensuring the lawful and compliant operation of the game. + +4. Information Sharing and Disclosure +We do not sell your personal information. We may share your data with third parties in the following scenarios: +- Service Providers: With third-party service providers who assist us in operating the game, such as data analytics firms, payment processors, and cloud service providers. +- Partners: With partners to offer joint services or activities, enhancing user value. +- Legal Requirements: When required by law or to protect our legitimate interests, we may disclose your data to ensure legal compliance. + +5. Data Security +We implement reasonable security measures to protect your personal data from unauthorized access, disclosure, alteration, or destruction. While no internet transmission method or electronic storage method is completely secure, we continuously improve our security measures to ensure your data is as secure as possible. + +6. Your Rights +You have the right to access, correct, delete your personal data, or withdraw your consent to certain data processing. You can contact us through the following methods: +- Email: maxsource2031@outlook.com +- In-Game Support: Submit requests through the in-game customer support system, and we will process your requests as soon as possible. + +7. Third-Party Services +Our game may integrate third-party services, such as social media platforms and advertising networks. These third-party services may collect your data. We recommend that you review the privacy policies of these third-party services to understand how they handle your data. We are not responsible for the actions or policies of third-party services, but we strive to ensure that our partners adhere to high standards of data protection. + +8. Children's Privacy +We do not intentionally collect personal data from children under the age of 13. If we discover that we have collected personal data from a child under 13, we will immediately delete that data and take necessary measures to prevent similar occurrences. + +9. International Data Transfer +Your personal data may be transferred to and stored on servers located outside your country of residence. The data protection laws in these countries may differ from those in your country. By using our game, you agree to such transfers and storage, and you understand the potential legal differences. + +10. Changes to the Privacy Policy +We reserve the right to update this Privacy Policy at any time. We will notify you of any changes by posting the new policy within the game. We recommend that you regularly review this Privacy Policy to stay informed about the latest terms and conditions. If we make significant changes, we may provide additional notice, such as in-game notifications or emails, to ensure you are aware of the changes. + +11. Contact Us +If you have any questions or concerns about this Privacy Policy, please contact us through the following methods: +- Email: maxsource2031@outlook.com +- In-Game Support: Submit requests through the in-game customer support system, and we will respond to your inquiries as soon as possible to ensure your issues are resolved promptly. \ No newline at end of file diff --git a/Assets/Resources/CrazyZooAssets/TextAsset/Term.txt b/Assets/Resources/CrazyZooAssets/TextAsset/Term.txt index 26f22b7..2530700 100644 --- a/Assets/Resources/CrazyZooAssets/TextAsset/Term.txt +++ b/Assets/Resources/CrazyZooAssets/TextAsset/Term.txt @@ -1,34 +1,25 @@ -Welcome to Twist & Turn ("the Game" or "we"). Please read this User Agreement ("Agreement") carefully before using the Game. By downloading, installing, or using the Game, you indicate that you have read and agree to be bound by this Agreement. If you do not agree with any part of this Agreement, please do not use the Game. -1. Acceptance of Terms -1.1 This Agreement constitutes a legal agreement between you and Twist & Turn, governing your use of the Game. -1.2 We may modify or update this Agreement from time to time. The updated Agreement will be communicated via in-app notifications or other appropriate means. If you continue using the Game after the Agreement has been updated, it is considered acceptance of the updated terms. -2. Rules of Use -2.1 Account Creation and Management: You may need to create an account to access certain features of the Game. You must ensure that the information provided is accurate and up-to-date. -2.2 Age Restrictions: The Game is intended for users aged 13 and above. If you are under 18, parental or guardian consent is required before using the Game. -2.3 Game Conduct Rules: You agree to comply with all applicable laws and refrain from engaging in the following behaviors while using the Game: -- Violating the legal rights of others. -- Using unauthorized third-party software or tools. -- Distributing malware or viruses. -- Cheating or disrupting the fairness of the Game. -- Posting inappropriate, offensive, or illegal content. -2.4 Intellectual Property: All content within the Game (including but not limited to images, text, music, code) is protected by copyright and other intellectual property laws. You may not copy, modify, distribute, or use it for commercial purposes without authorization. -3. Payments and Virtual Items -3.1 Virtual Items and Currency: The Game may include virtual items or currency. Virtual items are for in-game use only, have no real-world monetary value, and cannot be transferred, traded, or exchanged for actual money. -3.2 Purchases and Refunds: When purchasing virtual items, you must comply with the payment rules of the app store. All purchases are final and non-refundable unless otherwise required by law or specifically stated by us. -4. User-Generated Content -4.1 Content License: If you publish, upload, or share content (such as text, images, videos) in the Game, you grant us a worldwide, non-exclusive, perpetual, royalty-free license to use it for purposes related to promoting and improving the Game. -4.2 Content Responsibility: You are responsible for the content you publish and must ensure it does not infringe any third-party rights or violate applicable laws. -5. Privacy Protection -We value your privacy. Please refer to our [Privacy Policy] for details on how we collect, use, and protect your personal information. -6. Disclaimer of Warranties -6.1 Service Provided "As Is" and "As Available": The Game is provided on an "as is" and "as available" basis. We do not guarantee that the Game will be uninterrupted or error-free. -6.2 Limitation of Liability: To the maximum extent permitted by applicable law, we shall not be liable for any direct, indirect, incidental, or consequential damages arising from your use of the Game. -7. Termination -7.1 User Termination: You may stop using the Game and delete your account at any time. -7.2 Our Termination: We may suspend or terminate your use of the Game without prior notice if you violate the terms of this Agreement. -8. Governing Law and Dispute Resolution -8.1 Governing Law: This Agreement is governed by the laws of your jurisdiction. -8.2 Dispute Resolution: In case of any disputes arising from this Agreement, both parties should seek to resolve them amicably. If resolution cannot be reached, the dispute should be submitted to the court in your jurisdiction. -9. Contact Us -If you have any questions about this Agreement, please contact us at: -- Email: mtop17600@gmail.com \ No newline at end of file +By downloading, installing, or playing (“the Game”), you agree to be bound by these Terms of Service. +1. The Service +The game is a casual puzzle game inspired by tile-matching mechanics. The Game is provided for your personal, non-commercial entertainment. +2. No Account Required +You may play the Game without creating an account or providing any personal information. +3. No In-App Purchases or Ads +The game contains no in-app purchases, no outbound links, and no third-party advertisements. The Game is a one-time download with no ongoing costs or distractions. +4. User Conduct +You agree to use the Game only for its intended purpose. You may not: +- Reverse engineer, modify, or create derivative works of the Game. +- Use the Game for any illegal or unauthorized purpose. +- Attempt to disrupt or damage the Game’s functionality. +5. Intellectual Property +All content in The game – including but not limited to the game name, artwork, sound effects, tile designs, and code – is the exclusive property of the developer. You may not copy, redistribute, or commercially exploit any part of the Game without explicit permission. +6. No Warranties +The Game is provided “as is.” We do not guarantee that it will be error-free or uninterrupted. To the fullest extent permitted by law, we disclaim all warranties, express or implied. +7. Limitation of Liability +In no event shall we be liable for any damages arising from your use or inability to use the Game, including but not limited to loss of progress, device issues, or emotional frustration. +8. Changes to These Terms +We may update these Terms from time to time. If we make material changes, we will post the revised version online. Continued use of the Game after changes take effect constitutes your acceptance. +9. Termination +We reserve the right to discontinue the Game at any time. You may stop using the Game at any time by uninstalling it. +10. Contact Us +For any questions regarding these Terms, please contact: +bingotornad0game@gmail.com \ No newline at end of file diff --git a/Assets/Scripts/Roy/newweb/ConfigSystem_sdk.cs b/Assets/Scripts/Roy/newweb/ConfigSystem_sdk.cs index 7496659..2436844 100644 --- a/Assets/Scripts/Roy/newweb/ConfigSystem_sdk.cs +++ b/Assets/Scripts/Roy/newweb/ConfigSystem_sdk.cs @@ -126,7 +126,7 @@ namespace BingoBrain if (!json.StartsWith("{")) { - json = Encoding.UTF8.GetString(Base64Kit_sdk.Decrypt(Encoding.UTF8.GetBytes(json), + json = Encoding.UTF8.GetString(Base64Kit_sdk.DecryptJson(Encoding.UTF8.GetBytes(json), NetworkManager.packName)); } Debug.Log("转化后的json" + json); diff --git a/Assets/Scripts/Roy/newweb/LoginSystem_sdk.cs b/Assets/Scripts/Roy/newweb/LoginSystem_sdk.cs index 31df802..30af837 100644 --- a/Assets/Scripts/Roy/newweb/LoginSystem_sdk.cs +++ b/Assets/Scripts/Roy/newweb/LoginSystem_sdk.cs @@ -32,8 +32,8 @@ public class LoginSystem_sdk // device_id ="E742FE8B-C32E-56A7-8F8A-6B3BC0F3169", pack_name = NetworkManager.packName, app_version = Application.version, - // channel = BingoBea.Instance.attribution, - // sim = WebviewManager.haveSimCard + secret = "FJC3WBAF2", // 这里的值要和你们项目约定的 Secret 保持一致 + }; Debug.Log(JsonConvert.SerializeObject(requestLoginData)); Debug.Log(SystemInfo.deviceUniqueIdentifier); @@ -77,7 +77,7 @@ public class LoginSystem_sdk // return; // } - + NetworkKit_sdk.CDNUrl = $"{loginData.cdn_url}/"; NetworkKit_sdk.SetCacheToken(loginData.token); @@ -88,7 +88,7 @@ public class LoginSystem_sdk // { // RequestHeart(); - // GameHelper.PostFunnelLogin("loginRecv", true); + // GameHelper.PostFunnelLogin("loginRecv", true); ConfigSystem_sdk.Instance.OnRequestGetConfig(); // if (GameHelper.IsGiftSwitch()) // { @@ -170,4 +170,5 @@ public class RequestLoginData_sdk public string app_version; public string channel; public bool sim; + public string secret; } \ No newline at end of file diff --git a/Assets/Scripts/Roy/newweb/NetworkKit_sdk.cs b/Assets/Scripts/Roy/newweb/NetworkKit_sdk.cs index 9772cc8..350dd96 100644 --- a/Assets/Scripts/Roy/newweb/NetworkKit_sdk.cs +++ b/Assets/Scripts/Roy/newweb/NetworkKit_sdk.cs @@ -12,6 +12,7 @@ using System.Linq; using System.Security.Cryptography; using FutureCore; using ScrewsMaster; +using System.IO; @@ -35,16 +36,16 @@ public class NetworkKit_sdk PlayerPrefs.SetString(JarvisToken_SDK, token); } public const string DomainDebugUrl = @"https://sdkapi.jsoncompare.online/"; - public static string DomainRelease = "zoomatchsolo.top"; - + public static string DomainRelease = "web.zoomatchsolo.top"; + // https://web.zoomatchsolo.top // 改为只读属性,实时获取(等调用时 DomainRelease 早就初始化好了) - public static string DomainReleaseUrl => $"https://{DomainRelease}/sdkapi/"; + public static string DomainReleaseUrl => $"https://{DomainRelease}/api/"; // 改为只读属性,实时获取 #if JarvisRelease public static string CrazyUrl => DomainReleaseUrl; #else - public static string CrazyUrl => DomainDebugUrl; + public static string CrazyUrl => DomainDebugUrl; #endif @@ -54,10 +55,10 @@ public class NetworkKit_sdk string requestJson = JsonConvert.SerializeObject(requestData); string url2 = url; -#if JarvisRelease - url2 = Base64Kit_sdk.Encode(url); - requestJson = Base64Kit_sdk.Encode(requestJson); -#endif + // #if JarvisRelease + // url2 = Base64Kit_sdk.Encode(url); + // requestJson = Base64Kit_sdk.Encode(requestJson); + // #endif byte[] bytes = Encoding.UTF8.GetBytes(requestJson); string url1 = CrazyUrl + url2; Debug.Log($"Url: {url1}"); @@ -79,22 +80,24 @@ public class NetworkKit_sdk yield return loginRequest.SendWebRequest(); if (loginRequest.result is not UnityWebRequest.Result.Success) { + string receiveContent = loginRequest.downloadHandler.text; onCompleted?.Invoke(false, default); + Debug.Log(url + "cuowude--------" + JsonConvert.SerializeObject(loginRequest)); + Debug.Log(url + "cuowude--------" + receiveContent); } else { string receiveContent = loginRequest.downloadHandler.text; + Debug.Log(url + "--------" + receiveContent); #if JarvisRelease if (!receiveContent.IsNullOrWhiteSpace()) { - receiveContent = receiveContent.Substring(0, receiveContent.Length - 1); - receiveContent = receiveContent.Substring(1); - receiveContent = Base64Kit_sdk.Decode(receiveContent); + receiveContent = Base64Kit_sdk.Decrypt(receiveContent, DomainRelease); } #endif - // Debug.Log(url + "--------" + loginRequest.downloadHandler.text); Debug.Log(url + "--------" + receiveContent); + var response = JsonConvert.DeserializeObject(receiveContent); if (response?.code == 0) @@ -347,72 +350,82 @@ public class NetworkKit_sdk } public class Base64Kit_sdk { - public static string Base64Encode(string source) + public static string Decrypt(string encryptedBase64, string secret) { - byte[] bytes = Encoding.UTF8.GetBytes(source); - string encode = Convert.ToBase64String(bytes); - return encode; - } - public static string Encode(string data, bool is_apple_pay = false) - { - var key = NetworkKit_sdk.DomainRelease; - //if (is_apple_pay) key = "com.leisuregames.crazygourmet"; - - var keyMD5 = MD5Kit.MD5String1(key); - //UnityEngine.Debug.Log("Base64 Encode Key: " + keyMD5); - var str = Base64EncodeUtil.Base64Encode(data + keyMD5); - - var bytes = Encoding.UTF8.GetBytes(str); - for (int i = 0, j = bytes.Length - 1; i < j; i += 1, j -= 1) + try { - if (i % 2 == 0) + if (string.IsNullOrEmpty(encryptedBase64)) return string.Empty; + + // 1. 容错处理:如果密文首尾有双引号,先去掉 + encryptedBase64 = encryptedBase64.Trim(); + if (encryptedBase64.StartsWith("\"") && encryptedBase64.EndsWith("\"")) { - (bytes[i], bytes[j]) = (bytes[j], bytes[i]); + encryptedBase64 = encryptedBase64.Substring(1, encryptedBase64.Length - 2); + } + + // 2. 将 URL 安全的 Base64 替换为标准 Base64 字符 + string standardBase64 = encryptedBase64.Replace('-', '+').Replace('_', '/'); + int mod4 = standardBase64.Length % 4; + if (mod4 > 0) + { + standardBase64 += new string('=', 4 - mod4); + } + + // 3. 将 Base64 转换为字节数组 + byte[] cipherData = Convert.FromBase64String(standardBase64); + + if (cipherData.Length < 16) + { + throw new Exception("密文长度过短,不满足 AES 块大小要求"); + } + + // 4. 【生成 Key】将 Secret 进行 SHA256 哈希,得到 32 字节的 AES Key + byte[] keyBytes; + using (SHA256 sha256 = SHA256.Create()) + { + keyBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(secret)); + } + + // 5. 【提取 IV】密文的前 16 字节是随机生成的初始化向量 (IV) + byte[] iv = new byte[16]; + Array.Copy(cipherData, 0, iv, 0, 16); + + // 6. 【提取实际密文】16 字节之后的数据才是真正的加密数据 + int encryptedDataLength = cipherData.Length - 16; + byte[] encryptedData = new byte[encryptedDataLength]; + Array.Copy(cipherData, 16, encryptedData, 0, encryptedDataLength); + + // 7. 进行 AES-256-CBC 解密 + using (Aes aes = Aes.Create()) + { + aes.KeySize = 256; + aes.BlockSize = 128; + aes.Mode = CipherMode.CBC; + aes.Padding = PaddingMode.PKCS7; // 对应 Go 的 PKCS7Padding + + aes.Key = keyBytes; + aes.IV = iv; + + using (ICryptoTransform decryptor = aes.CreateDecryptor()) + { + using (MemoryStream ms = new MemoryStream(encryptedData)) + { + using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read)) + { + using (StreamReader sr = new StreamReader(cs, Encoding.UTF8)) + { + return sr.ReadToEnd(); // 解密出来的明文 JSON 字符串 + } + } + } + } } } - - var loginData = Encoding.UTF8.GetString(bytes); - return loginData; - } - - public static string Decode(string data) - { - var bytes = Encoding.UTF8.GetBytes(data); - for (int i = 0, j = bytes.Length - 1; i < j; i += 1, j -= 1) + catch (Exception ex) { - if (i % 2 == 0) - { - (bytes[i], bytes[j]) = (bytes[j], bytes[i]); - } + UnityEngine.Debug.LogError("解密失败: " + ex.Message); + return string.Empty; } - - var str = Encoding.UTF8.GetString(bytes); - var str1 = Base64EncodeUtil.Base64Decode(str); - var key = NetworkKit_sdk.DomainRelease; - var keyMD5 = MD5Kit.MD5String1(key); - // Debug.Log("Base64 Decode Key: " + keyMD5); - // Debug.Log("Base64 Decode str1: " + str1); - var result = str1.Replace(keyMD5, string.Empty); - return result; - } - - public static string Decode(string data, string key) - { - var bytes = Encoding.UTF8.GetBytes(data); - for (int i = 0, j = bytes.Length - 1; i < j; i += 1, j -= 1) - { - if (i % 2 == 0) - { - (bytes[i], bytes[j]) = (bytes[j], bytes[i]); - } - } - - var str = Encoding.UTF8.GetString(bytes); - var str1 = Base64EncodeUtil.Base64Decode(str); - // var key = NetworkManager.DomainRelease; - var keyMD5 = MD5Kit.MD5String1(key); - var result = str1.Replace(keyMD5, string.Empty); - return result; } private static byte[] GenerateKey(string secret) { @@ -420,30 +433,7 @@ public class Base64Kit_sdk return sha256.ComputeHash(Encoding.UTF8.GetBytes(secret)); } - internal static byte[] Encrypt(byte[] plainText, string secret) - { - if (plainText == null || plainText.Length == 0) return plainText; - var key = GenerateKey(secret); - using var aes = Aes.Create(); - aes.Key = key; - aes.Mode = CipherMode.CBC; - aes.Padding = PaddingMode.None; - aes.GenerateIV(); - var iv = aes.IV; - var blockSize = aes.BlockSize / 8; - var padding = blockSize - plainText.Length % blockSize; - var padded = new byte[plainText.Length + padding]; - Buffer.BlockCopy(plainText, 0, padded, 0, plainText.Length); - for (var i = plainText.Length; i < padded.Length; i++) padded[i] = (byte)padding; - using var encryptor = aes.CreateEncryptor(); - var encrypted = encryptor.TransformFinalBlock(padded, 0, padded.Length); - var result = new byte[iv.Length + encrypted.Length]; - Buffer.BlockCopy(iv, 0, result, 0, iv.Length); - Buffer.BlockCopy(encrypted, 0, result, iv.Length, encrypted.Length); - return ToUrlSafeBase64(result); - } - - internal static byte[] Decrypt(byte[] encryptedBase64, string secret) + internal static byte[] DecryptJson(byte[] encryptedBase64, string secret) { if (encryptedBase64 == null || encryptedBase64.Length == 0) return encryptedBase64; var key = GenerateKey(secret); @@ -464,36 +454,6 @@ public class Base64Kit_sdk return result; } - // 用双引号包裹字节数组 - private static byte[] QuoteBytes(byte[] input) - { - var result = new byte[input.Length + 2]; - result[0] = (byte)'"'; - Buffer.BlockCopy(input, 0, result, 1, input.Length); - result[result.Length - 1] = (byte)'"'; - return result; - } - - // 去除双引号(如果存在) - internal static byte[] UnquoteBytes(byte[] input) - { - if (input.Length >= 2 && input[0] == (byte)'"' && input[input.Length - 1] == (byte)'"') - { - var result = new byte[input.Length - 2]; - Buffer.BlockCopy(input, 1, result, 0, result.Length); - return result; - } - - return input; - } - - private static byte[] ToUrlSafeBase64(byte[] data) - { - var base64 = Convert.ToBase64String(data); - var urlSafe = base64.Replace('+', '-').Replace('/', '_'); - return Encoding.UTF8.GetBytes(urlSafe); - } - private static byte[] FromUrlSafeBase64(byte[] urlSafe) { var base64 = Encoding.UTF8.GetString(urlSafe).Replace('-', '+').Replace('_', '/');