备份CatanBuilding瘦身独立工程

This commit is contained in:
JSD\13999
2026-05-26 16:15:54 +08:00
commit 2d0e6a61b7
12001 changed files with 2431925 additions and 0 deletions

View File

@@ -0,0 +1,372 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using asap.core;
using SimpleJSON;
using UnityEngine;
using UnityEngine.Networking;
public static class ConfigExtension
{
private const string defaultconfig = "9Nf/P8vm2+7Ciph2jH1QnEaHCK3cAl7lNnCJc/uxSKGVqcJgWilN3VgaC/74coHRiRpxEelC2+ia7qcjnHhA3OQN82rcVJOP24pGKrSbSgOIGbH9cCEUhdYRo5vnVgLBqlTS/c/AajowTkN59O0AYxDC7J3jq6ptLXdmuG27JYS9NXOQDkgxpzEpG7JTtczHKxhWAv+9uSzbJRCs16KeusbJX1YtNZM8wjCD9esTv4zXXMIpZPlXb86NjHiI02TakAdHo0plO+Di9n5UCC8/4+QGoKNyQgtvIkzMyoGziO4DOLy/VkfITenFv/+9DY0LmpZGa7Cog89znaYyVMTiC/3R2IefXXh04+8uqmyzeVKqh0grcU9qmz485wCoUl/TM9F8+s1Jhp/eaB/E7luOjc57Kz0Eyw2Qko7Fo+lCaRJE1uex9fB46v0LhddSHCEWw8QERmqG9KcmvG4LsyafupA8kliDzj7a7XIzGrgnNnsMxLgeYsSbNiBvXXESeeNCoqiOQTTBpk/br0QuTHTG2DRxUZZ4KM3SKZtHEZ2bZV2FUS4azFpfDXUGoc86O+xz6hAIMbdKCHyqyEeKMmHIzQI9OlIaa3KGwk+w1eFDUuq4zyTh+qGuClZynanUkfNe8mTmFtBax2f3MJHjGpXJT0VdtY/R+5ZQO0nCU30THfnryG0GURsrv6MQYiQX5hsLqG9Z72ybbbbqIR2rvE2w13DM/tqTb4i/hN0+pbeTKkUpdNIWEsR94Q==";
private static string RemoteConfigUrl { get; set; }
public static void Rest(this IConfig config)
{
RemoteConfigUrl = null;
}
public static async Task<bool> InitConfig(this IConfig config)
{
JSONNode streamingAssetConfig = null;
JSONNode persistConfig = null;
bool isSuccessLoadRemoteConfigFile = true;
if (RemoteConfigUrl == null)
{
streamingAssetConfig = GetStreamingAssetConfig();
persistConfig = GetPersistConfig();
}
if (RemoteConfigUrl == null)
{
RemoteConfigUrl = string.Format(GConstant.V_Static_Res_URL, VersionTool.PackVer);
}
JSONNode remoteConfig = await GetRemoteConfig();
if (remoteConfig == null)
{
var remoteConfigStr = Decrypt(defaultconfig);
remoteConfig = JSON.Parse(remoteConfigStr);
remoteConfig["Ver"] = VersionTool.FromLocal().ToVerString();
isSuccessLoadRemoteConfigFile = false;
}
foreach (var element in remoteConfig)
{
config.Set(element.Key, element.Value.Value);
}
if (streamingAssetConfig != null)
{
foreach (var element in streamingAssetConfig)
{
config.Set(element.Key, element.Value.Value);
}
}
if (persistConfig != null)
{
foreach (var element in persistConfig)
{
config.Set(element.Key, element.Value.Value);
}
}
config.Set(GConstant.K_Static_Res_URL, RemoteConfigUrl);
return isSuccessLoadRemoteConfigFile;
}
private static readonly float[] timeoutValues = new float[] { 1, 2, 2 };
public static async Task<JSONNode> GetRemoteConfig()
{
UnityEngine.Assertions.Assert.IsNotNull(RemoteConfigUrl, "Config is not inited");
await Awaiters.NextFrame;
var maxRetryTimes = timeoutValues.Length;
for (int retryTime = 0; retryTime < maxRetryTimes; retryTime++)
{
var rawConfig = await DoGetRawConfigUWR(timeoutValues[retryTime], retryTime, maxRetryTimes);
if (!string.IsNullOrEmpty(rawConfig))
{
Debug.Log($"<color=orange>Load remote config success {retryTime + 1}/{maxRetryTimes}</color>");
return JSON.Parse(rawConfig);
}
}
return null;
}
private static async Task<string> DoGetRawConfigUWR(float timeoutInSec, int retryTimes, int maxRetryTimes)
{
using (var req = UnityWebRequest.Get($"{RemoteConfigUrl}/{GConstant.V_Remote_Config_Path}"))
{
var stopwatch = new System.Diagnostics.Stopwatch();
var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(timeoutInSec));
var ct = cts.Token;
stopwatch.Start();
req.timeout = (int)timeoutInSec;
req.SetRequestHeader("Accept", "application/json");
var op = req.SendWebRequest();
try
{
while (!op.isDone && !ct.IsCancellationRequested)
{
await Awaiters.NextFrame;
}
ct.ThrowIfCancellationRequested();
stopwatch.Stop();
if (req.result == UnityWebRequest.Result.Success)
{
return Decrypt(req.downloadHandler.text);
}
#if AGG
using (var e = GEvent.TackEvent("retry"))
{
e.AddContent("type", "config");
e.AddContent("duration_ms", stopwatch.ElapsedMilliseconds);
e.AddContent("reason", req.result.ToString());
e.AddContent("skip", retryTimes >= maxRetryTimes - 1);
e.AddContent("error", req.error);
}
#endif // AGG
Debug.LogWarning($"Load remote config failed {req.result.ToString()} {req.error} {retryTimes + 1}/{maxRetryTimes}");
}
catch (OperationCanceledException)
{
req.Abort();
stopwatch.Stop();
#if AGG
using (var e = GEvent.TackEvent("retry"))
{
e.AddContent("type", "config");
e.AddContent("duration_ms", stopwatch.ElapsedMilliseconds);
e.AddContent("reason", "cancel");
e.AddContent("skip", retryTimes >= maxRetryTimes - 1);
e.AddContent("error", req.error ?? "cancel");
}
#endif // AGG
Debug.LogWarning($"Load remote config cancel {req.result.ToString()} {req.error} {retryTimes + 1}/{maxRetryTimes}");
}
finally
{
cts.Dispose();
}
return null;
}
}
/**
private static async Task<string> DoGetRawConfig(float timeoutInSec, int retryTimes)
{
var timeout = TimeSpan.FromSeconds(timeoutInSec);
var handler = new System.Net.Http.HttpClientHandler(){
SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls,
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; }
};
using (var httpClient = new System.Net.Http.HttpClient(handler))
{
httpClient.Timeout = timeout;
var stopwatch = new System.Diagnostics.Stopwatch();
try
{
stopwatch.Start();
var respon = await httpClient.GetAsync($"{RemoteConfigUrl}/{GConstant.V_Remote_Config_Path}");
stopwatch.Stop();
if (respon.IsSuccessStatusCode)
{
string remoteConfigStr = await respon.Content.ReadAsStringAsync();
await Awaiters.NextFrame;
return Decrypt(remoteConfigStr);
}
else
{
var elapsed = stopwatch.ElapsedMilliseconds;
Debug.LogWarning($"Load remote config failed {respon.StatusCode.ToString()}");
#if AGG
using (var e = GEvent.TackEvent("retry"))
{
e.AddContent("type", "config");
e.AddContent("duration_ms", elapsed);
e.AddContent("reason", respon.StatusCode.ToString());
e.AddContent("skip", retryTimes >= 2);
e.AddContent("error", "http_request_failed");
}
#endif//AGG
}
}
catch (System.Net.Http.HttpRequestException httpEx)
{
if (stopwatch.IsRunning)
stopwatch.Stop();
var elapsed = stopwatch.Elapsed;
var errorMessage = $"HTTP request failed: {httpEx.Message}";
if (httpEx.InnerException != null)
{
errorMessage += $" Inner: {httpEx.InnerException.Message}";
if(httpEx.InnerException.InnerException != null)
{
errorMessage += $" InnerInner: {httpEx.InnerException.InnerException.Message}";
}
}
Debug.LogWarning(errorMessage);
#if AGG
using (var e = GEvent.TackEvent("retry"))
{
e.AddContent("type", "config");
e.AddContent("duration_ms", elapsed.TotalMilliseconds);
e.AddContent("reason", "httpEx");
e.AddContent("skip", retryTimes >= 2);
e.AddContent("error", errorMessage);
}
#endif//AGG
}
catch (System.Threading.Tasks.TaskCanceledException timeoutEx)
{
if (stopwatch.IsRunning)
stopwatch.Stop();
var elapsed = stopwatch.Elapsed;
Debug.LogWarning($"Request timeout after {timeoutInSec}s: {timeoutEx.Message}");
#if AGG
using (var e = GEvent.TackEvent("retry"))
{
e.AddContent("type", "config");
e.AddContent("duration_ms", elapsed.TotalMilliseconds);
e.AddContent("reason", $"timeout");
e.AddContent("skip", retryTimes >= 2);
e.AddContent("error", timeoutEx.Message);
}
#endif//AGG
}
catch (System.Security.Cryptography.CryptographicException cryptoEx)
{
if (stopwatch.IsRunning)
stopwatch.Stop();
var elapsed = stopwatch.Elapsed;
Debug.LogError($"Decryption failed: {cryptoEx.Message}");
#if AGG
using (var e = GEvent.TackEvent("retry"))
{
e.AddContent("type", "config");
e.AddContent("duration_ms", elapsed.TotalMilliseconds);
e.AddContent("reason", "cryptoEx");
e.AddContent("skip", retryTimes >= 2);
e.AddContent("error", cryptoEx.Message);
}
#endif//AGG
}
catch (Exception exception)
{
if (stopwatch.IsRunning)
stopwatch.Stop();
var elapsed = stopwatch.ElapsedMilliseconds;
var errorMessage = $"Unexpected error loading remote config: {exception.Message}";
if (exception.InnerException != null)
{
errorMessage += $" Inner: {exception.InnerException.Message}";
}
Debug.LogError(errorMessage);
#if AGG
using (var e = GEvent.TackEvent("retry"))
{
e.AddContent("type", "config");
e.AddContent("duration_ms", elapsed);
e.AddContent("reason", "unexpected_error");
e.AddContent("skip", retryTimes >= 2);
e.AddContent("error", errorMessage);
}
#endif//AGG
}
}
return null;
}
*/
/*
* public static async Task<JSONNode> GetRemoteConfig()
* {
* UnityEngine.Assertions.Assert.IsNotNull(RemoteConfigUrl, "Config is not inited");
* var request = UnityWebRequest.Get($"{RemoteConfigUrl}/{GConstant.V_Remote_Config_Path}");
* request.timeout = 5;
* await request.SendWebRequest();
*
* if (request.result != UnityWebRequest.Result.Success)
* {
* return null;
* }
*
* string remoteConfigStr = request.downloadHandler.text;
* remoteConfigStr = Decrypt(remoteConfigStr);
* return SimpleJSON.JSON.Parse(remoteConfigStr);
* }
*/
const string RTMKey = "tbambooz";
private static string Decrypt(string text)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
des.Key = Encoding.ASCII.GetBytes(RTMKey);
des.IV = Encoding.ASCII.GetBytes(RTMKey);
ICryptoTransform decryptor = des.CreateDecryptor(des.Key, des.IV);
byte[] inputBytes = Convert.FromBase64String(text);
byte[] outputBytes = decryptor.TransformFinalBlock(inputBytes, 0, inputBytes.Length);
return Encoding.UTF8.GetString(outputBytes);
}
private static JSONNode GetStreamingAssetConfig()
{
var debugConfigPath = GConstant.V_Debug_Config_Path;
var text = BetterStreamingAssets.ReadAllText(debugConfigPath);
//如果第一个字符是#e就返回false
if (!text.StartsWith("#"))
{
var debugConfig = SimpleJSON.JSON.Parse(text);
if (debugConfig.HasKey(GConstant.K_Static_Res_URL))
{
RemoteConfigUrl = debugConfig[GConstant.K_Static_Res_URL];
Debug.Log($"<color=yellow>Debug Static Res URL => {RemoteConfigUrl}</color>");
}
return debugConfig;
}
return null;
}
private static JSONNode GetPersistConfig()
{
var debugConfigPath = Path.Combine(Application.persistentDataPath, GConstant.V_Debug_Config_Path);
if (File.Exists(debugConfigPath))
{
var debugConfig = SimpleJSON.JSON.Parse(File.ReadAllText(debugConfigPath));
if (debugConfig.HasKey(GConstant.K_Static_Res_URL))
{
RemoteConfigUrl = debugConfig[GConstant.K_Static_Res_URL];
Debug.Log($"<color=yellow>Debug Static Res URL => {RemoteConfigUrl}</color>");
}
return debugConfig;
}
return null;
}
}