Files
Liubing\LB 3d8d4d18f3 first commit
先修复一下,错误的场景

删除不必要的钓场资产

修复into场景

update:更新meta文件,修复报错

update:修复资源

修复第一章节建造

修复建造第三章

update:删除多余内容

update:更新README.md

update:还原图标

update:更新README

update:更新配置
2026-04-28 02:17:22 +08:00

371 lines
14 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.IO;
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 = "{\"StaticResURL\":\"https://sls-cloudfunction-ap-beijing-code-1305151099.cos.ap-beijing.myqcloud.com/mini/0_47\",\"PlayFabTitle\":\"108EE8\",\"Origin_Addressable_URL\":\"https://sls-cloudfunction-ap-beijing-code-1305151099.cos.ap-beijing.myqcloud.com/mini/0_47/Android\",\"HeartBeat\":300,\"CustomID\":\"{{input}}\",\"GM\":\"1\",\"FuncUrl\":\"http://62.234.191.215:7071\",\"FuncKey\":\"testKey\",\"Ver\":\"0.47.2f4aa9f\"}";
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)
{
var staticResURL = GConstant.V_Static_Res_URL;
if (ChannelManager.IsRustoreStore)
staticResURL = GConstant.V_Static_Res_URL_RU;
RemoteConfigUrl = string.Format(staticResURL, VersionTool.PackVer);
}
JSONNode remoteConfig = await GetRemoteConfig();
if (remoteConfig == null)
{
Debug.LogWarning($"[GConfig] Remote config download failed, using default config");
remoteConfig = JSON.Parse(defaultconfig);
remoteConfig["Ver"] = VersionTool.FromLocal().ToVerString();
isSuccessLoadRemoteConfigFile = false;
}
else
{
Debug.Log($"[GConfig] Remote config downloaded: Ver={remoteConfig["Ver"]}, StaticResURL={remoteConfig["StaticResURL"]}");
}
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);
Debug.Log($"[GConfig] Final config: Ver={config.Get(GConstant.K_Ver, "N/A")}, StaticResURL={RemoteConfigUrl}, isSuccessLoadRemote={isSuccessLoadRemoteConfigFile}");
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)
{
var requestUrl = $"{RemoteConfigUrl}/{GConstant.V_Remote_Config_Path}";
Debug.Log($"[GConfig] Requesting remote config: {requestUrl}");
using (var req = UnityWebRequest.Get(requestUrl))
{
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)
{
Debug.Log($"[GConfig] Remote config raw response length={req.downloadHandler.text.Length}");
return 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);
* }
*/
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;
}
}