This commit is contained in:
2026-06-12 14:41:59 +08:00
parent 9e56e25db3
commit 23d49410bd
6 changed files with 203 additions and 120 deletions
@@ -16,42 +16,51 @@ using UnityEditor;
#if USE_ADDRESSABLES
#endif
namespace SGModule.ConfigLoader {
public class FileNetworkManager : SingletonMonoBehaviour<FileNetworkManager> {
namespace SGModule.ConfigLoader
{
public class FileNetworkManager : SingletonMonoBehaviour<FileNetworkManager>
{
public const string FolderName = "Configs";
private const string FolderLabel = "config";
private string _configFolderPath;
protected override void Awake() {
protected override void Awake()
{
base.Awake();
_configFolderPath = Path.Combine(Application.persistentDataPath, FolderName);
}
public string GetConfigFOlderPath() {
public string GetConfigFOlderPath()
{
return _configFolderPath;
}
// 示例解析文件列表方法(你可以根据实际需求实现)
private List<string> ParseFileList(string data) {
private List<string> ParseFileList(string data)
{
// 假设 data 是文件列表的文本,解析文件名
// 根据实际情况解析,例如通过换行符分割
return data.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries).ToList();
}
public void CopyStreamingAssetsToPersistentDataPath(Action<bool> onComplete = null) {
public void CopyStreamingAssetsToPersistentDataPath(Action<bool> onComplete = null)
{
// 如果目标文件夹不存在,创建它
if (!Directory.Exists(_configFolderPath)) {
if (!Directory.Exists(_configFolderPath))
{
Directory.CreateDirectory(_configFolderPath);
}
StartCoroutine(CopyFile(onComplete));
}
private void HandleInitializationError() {
private void HandleInitializationError()
{
// 检查文件是否存在
var path = $"{Application.dataPath}/Library/com.unity.addressables/aa/Android/settings.json";
if (!File.Exists(path)) {
if (!File.Exists(path))
{
Log.ConfigLoader.Warning(
$"Settings file not found at: {path}. Rebuilding Addressables may be required.");
}
@@ -61,67 +70,75 @@ namespace SGModule.ConfigLoader {
// 比如:显示弹窗或退出程序
}
private IEnumerator CopyFile(Action<bool> onComplete = null) {
private IEnumerator CopyFile(Action<bool> onComplete = null)
{
#if USE_ADDRESSABLES
var handle = Addressables.LoadResourceLocationsAsync(FolderLabel);
yield return handle;
if (handle.Status == AsyncOperationStatus.Succeeded) {
// 查找以 ".json" 结尾的文件
var jsonLocation = handle.Result.FirstOrDefault(loc => loc.PrimaryKey.EndsWith(".json"));
// if (handle.Status == AsyncOperationStatus.Succeeded) {
// 查找以 ".json" 结尾的文件
// var jsonLocation = handle.Result.FirstOrDefault(loc => loc.PrimaryKey.EndsWith(".json"));
if (jsonLocation != null) {
var jsonFileName = Path.GetFileName(jsonLocation.PrimaryKey);
// 加载 JSON 文件
var textAssetAsync = Addressables.LoadAssetAsync<TextAsset>(jsonLocation);
// if (jsonLocation != null) {
// var jsonFileName = Path.GetFileName(jsonLocation.PrimaryKey);
// 加载 JSON 文件
// var textAssetAsync = Addressables.LoadAssetAsync<TextAsset>(jsonLocation);
TextAsset[] files = Resources.LoadAll<TextAsset>("Configs");
// yield return textAssetAsync;
yield return textAssetAsync;
if (textAssetAsync.Status == AsyncOperationStatus.Succeeded) {
var jsonFile = textAssetAsync.Result;
Log.ConfigLoader.Info($"Loaded JSON Name:{jsonFileName} content: " + jsonFile.text);
// if (textAssetAsync.Status == AsyncOperationStatus.Succeeded)
// {
TextAsset jsonFile = files[0];
string jsonFileName = jsonFile.name;
Log.ConfigLoader.Info($"Loaded JSON Name:{jsonFileName} content: " + jsonFile.text);
var destFilePath = Path.Combine(_configFolderPath, jsonFileName);
File.WriteAllBytes(destFilePath, jsonFile.bytes);
onComplete?.Invoke(true);
}
else {
Log.ConfigLoader.Error("Failed to load JSON file");
var destFilePath = Path.Combine(_configFolderPath, jsonFileName);
File.WriteAllBytes(destFilePath, jsonFile.bytes);
onComplete?.Invoke(true);
// }
// else {
// Log.ConfigLoader.Error("Failed to load JSON file");
onComplete?.Invoke(false);
}
}
else {
Log.ConfigLoader.Error("No JSON file found in folder");
// onComplete?.Invoke(false);
// }
// }
// else {
// Log.ConfigLoader.Error("No JSON file found in folder");
onComplete?.Invoke(false);
}
}
else {
Log.ConfigLoader.Error("Failed to load folder resources");
// onComplete?.Invoke(false);
// }
// }
// else
// {
// Log.ConfigLoader.Error("Failed to load folder resources");
onComplete?.Invoke(false);
}
// onComplete?.Invoke(false);
// }
#else
Log.Error( "没有 Addressables 插件,请检查 ");
yield break;
#endif
}
private IEnumerator CopyFile(string sourceFile, string destFile, Action<bool> onComplete = null) {
private IEnumerator CopyFile(string sourceFile, string destFile, Action<bool> onComplete = null)
{
var filePath = "file://" + sourceFile;
using (var www = UnityWebRequest.Get(filePath)) {
using (var www = UnityWebRequest.Get(filePath))
{
yield return www.SendWebRequest();
if (www.result == UnityWebRequest.Result.Success) {
if (www.result == UnityWebRequest.Result.Success)
{
File.WriteAllBytes(destFile, www.downloadHandler.data);
Log.ConfigLoader.Info($"File copied to {destFile}");
onComplete?.Invoke(true);
}
else {
else
{
Log.ConfigLoader.Error("Failed to copy file: " + www.error);
onComplete?.Invoke(false);
@@ -134,7 +151,8 @@ namespace SGModule.ConfigLoader {
/// </summary>
/// <param name="path"></param>
/// <param name="callback"></param>
public void ReadData(string path, Action<string> callback) {
public void ReadData(string path, Action<string> callback)
{
StartCoroutine(ReadDataEnumerator(path, callback));
}
@@ -144,14 +162,17 @@ namespace SGModule.ConfigLoader {
/// <param name="path"></param>
/// <param name="callback"></param>
/// <returns></returns>
private IEnumerator ReadDataEnumerator(string path, Action<string> callback) {
private IEnumerator ReadDataEnumerator(string path, Action<string> callback)
{
string fullPath;
// 判断是网络URL还是本地文件路径
if (path.StartsWith("http://") || path.StartsWith("https://")) {
if (path.StartsWith("http://") || path.StartsWith("https://"))
{
fullPath = path; // 网络URL
#if UNITY_EDITOR
if (path.StartsWith("http://") && PlayerSettings.insecureHttpOption == InsecureHttpOption.NotAllowed) {
if (path.StartsWith("http://") && PlayerSettings.insecureHttpOption == InsecureHttpOption.NotAllowed)
{
Log.ConfigLoader.Error("发起了 HTTP 链接,但设置了不允许非Https连接,请检查设置!!!");
callback?.Invoke(null);
@@ -159,22 +180,26 @@ namespace SGModule.ConfigLoader {
}
#endif
}
else {
else
{
// 本地文件路径
fullPath = "file://" + path;
}
// 使用UnityWebRequest读取数据
using (var webRequest = UnityWebRequest.Get(fullPath)) {
using (var webRequest = UnityWebRequest.Get(fullPath))
{
yield return webRequest.SendWebRequest();
if (webRequest.result == UnityWebRequest.Result.ConnectionError ||
webRequest.result == UnityWebRequest.Result.ProtocolError) {
webRequest.result == UnityWebRequest.Result.ProtocolError)
{
Log.ConfigLoader.Error($"Error while reading file: {webRequest.error} path: {fullPath}");
callback?.Invoke(null); // 返回null表示出错
}
else {
else
{
var data = webRequest.downloadHandler.text;
callback?.Invoke(data); // 通过回调传出数据
}
@@ -187,18 +212,21 @@ namespace SGModule.ConfigLoader {
/// <param name="folderName">文件夹名称</param>
/// <param name="fileName">文件名称</param>
/// <param name="content">要写入的内容</param>
public void WriteToPersistentData(string folderName, string fileName, string content) {
public void WriteToPersistentData(string folderName, string fileName, string content)
{
// 获取持久化数据路径
var folderPath = Path.Combine(Application.persistentDataPath, folderName);
// 如果文件夹不存在,则创建它
if (!Directory.Exists(folderPath)) {
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
// 删除原有文件
var existingFiles = Directory.GetFiles(folderPath);
foreach (var file in existingFiles) {
foreach (var file in existingFiles)
{
File.Delete(file);
}
@@ -217,11 +245,12 @@ namespace SGModule.ConfigLoader {
/// </summary>
/// <param name="subdirectory"></param>
/// <returns></returns>
public string[] GetFileNamesFromPersistentDataPath(string subdirectory) {
public string[] GetFileNamesFromPersistentDataPath(string subdirectory)
{
var directoryPath = Path.Combine(Application.persistentDataPath, subdirectory);
if (Directory.Exists(directoryPath))
// 获取目录中的所有文件名
// 获取目录中的所有文件名
{
return Directory.GetFiles(directoryPath)
.Select(Path.GetFileName) // 只提取文件名