Compare commits
10 Commits
073dd25857
...
main
Author | SHA1 | Date | |
---|---|---|---|
64e0bf2282 | |||
41d502b239 | |||
6271171ab4 | |||
7906203f84 | |||
dfa00340f5 | |||
9b9264a6cc | |||
3c962267ab | |||
344260266c | |||
040f167b6d | |||
7887695a67 |
@@ -1,7 +1,4 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Convention.SO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -12,7 +9,7 @@ namespace Convention
|
||||
[MenuItem("Convention/AssetBundle/Create for Android")]
|
||||
static void CreatAssetBundle()
|
||||
{
|
||||
string path = Path.Combine(Application.streamingAssetsPath, "AssetBundle", "Android");
|
||||
string path = Path.Combine(Application.dataPath, "../", "AssetBundle", "Android");
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
@@ -24,7 +21,7 @@ namespace Convention
|
||||
[MenuItem("Convention/AssetBundle/Create for IOS")]
|
||||
static void BuildAllAssetBundlesForIOS()
|
||||
{
|
||||
string dirName = "AssetBundles/IOS/IOS";
|
||||
string dirName = "AssetBundles/IOS/";
|
||||
if (!Directory.Exists(dirName))
|
||||
{
|
||||
Directory.CreateDirectory(dirName);
|
||||
@@ -37,7 +34,7 @@ namespace Convention
|
||||
[MenuItem("Convention/AssetBundle/Create for Windows")]
|
||||
static void CreatPCAssetBundleForwINDOWS()
|
||||
{
|
||||
string path = Path.Combine(Application.streamingAssetsPath, "AssetBundle", "Windows");
|
||||
string path = Path.Combine(Application.dataPath, "../", "AssetBundle", "Windows");
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
@@ -49,7 +46,7 @@ namespace Convention
|
||||
[MenuItem("Convention/AssetBundle/Create for Mac")]
|
||||
static void CreatPCAssetBundleForMac()
|
||||
{
|
||||
string path = Path.Combine(Application.streamingAssetsPath, "AssetBundle", "Mac");
|
||||
string path = Path.Combine(Application.dataPath, "../", "AssetBundle", "Mac");
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
|
@@ -96,8 +96,10 @@ MonoBehaviour:
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_CurrentContextKey: 0
|
||||
m_AllContextPlane: []
|
||||
WindowPlane: {fileID: 6262932319296346077}
|
||||
m_AllContextPlane:
|
||||
- plane: {fileID: 1743752460056994028}
|
||||
root: {fileID: 6898088878883608404}
|
||||
WindowPlane: {fileID: 2851218872878303137}
|
||||
WindowBar: {fileID: 5431686027440357681}
|
||||
--- !u!114 &8120993653923732271
|
||||
MonoBehaviour:
|
||||
@@ -350,6 +352,7 @@ MonoBehaviour:
|
||||
anchorMin: {x: 0, y: 0}
|
||||
pivot: {x: 0, y: 0}
|
||||
BeforeMaximizeWindowBackgroundColorA: 1
|
||||
IsMaximizeWindowMode: 0
|
||||
AdjustSizeToContainsRect: {fileID: 0}
|
||||
--- !u!114 &6852005934204649840
|
||||
MonoBehaviour:
|
||||
@@ -707,6 +710,17 @@ PrefabInstance:
|
||||
addedObject: {fileID: 1225826108170619254}
|
||||
m_AddedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 9f83398a7d855e44493acb9b240c01ca, type: 3}
|
||||
--- !u!114 &2851218872878303137 stripped
|
||||
MonoBehaviour:
|
||||
m_CorrespondingSourceObject: {fileID: 6525725186002079832, guid: 9f83398a7d855e44493acb9b240c01ca, type: 3}
|
||||
m_PrefabInstance: {fileID: 9007647915676817401}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 999be728ad5e8324baf45ccaf0f9c3d2, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!224 &6898088878883608404 stripped
|
||||
RectTransform:
|
||||
m_CorrespondingSourceObject: {fileID: 2502725167534981293, guid: 9f83398a7d855e44493acb9b240c01ca, type: 3}
|
||||
|
@@ -1085,6 +1085,7 @@ MonoBehaviour:
|
||||
anchorMin: {x: 0, y: 0}
|
||||
pivot: {x: 0, y: 0}
|
||||
BeforeMaximizeWindowBackgroundColorA: 1
|
||||
IsMaximizeWindowMode: 0
|
||||
AdjustSizeToContainsRect: {fileID: 0}
|
||||
--- !u!114 &3897188892033144510
|
||||
MonoBehaviour:
|
||||
|
@@ -1459,6 +1459,7 @@ MonoBehaviour:
|
||||
anchorMin: {x: 0, y: 0}
|
||||
pivot: {x: 0, y: 0}
|
||||
BeforeMaximizeWindowBackgroundColorA: 1
|
||||
IsMaximizeWindowMode: 0
|
||||
AdjustSizeToContainsRect: {fileID: 0}
|
||||
--- !u!114 &682559958368963457
|
||||
MonoBehaviour:
|
||||
|
@@ -22,7 +22,7 @@ namespace ES3Internal
|
||||
|
||||
public StreamReader baseReader;
|
||||
|
||||
internal ES3JSONReader(Stream stream, ES3Settings settings, bool readHeaderAndFooter = true) : base(settings, readHeaderAndFooter)
|
||||
public ES3JSONReader(Stream stream, ES3Settings settings, bool readHeaderAndFooter = true) : base(settings, readHeaderAndFooter)
|
||||
{
|
||||
this.baseReader = new StreamReader(stream);
|
||||
|
||||
|
@@ -13,6 +13,7 @@ using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.Scripting;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace UnityEditor
|
||||
@@ -56,6 +57,19 @@ namespace Convention
|
||||
public static string PersistentDataPath => Application.persistentDataPath;
|
||||
|
||||
public static string DataPath => Application.dataPath;
|
||||
|
||||
public static string CurrentWorkPath => Environment.CurrentDirectory;
|
||||
|
||||
public static string Combine(string a, string b) => Path.Combine(a, b);
|
||||
public static string CombineAsDir(string a, string b)
|
||||
{
|
||||
string name = b.Replace("\\", "/");
|
||||
if (name.EndsWith("/") == false)
|
||||
{
|
||||
name += "/";
|
||||
}
|
||||
return Path.Combine(a, name);
|
||||
}
|
||||
}
|
||||
|
||||
public static partial class Utility
|
||||
@@ -425,7 +439,7 @@ namespace Convention
|
||||
public static _T convert_xvalue<_T>([In] string str)
|
||||
{
|
||||
Type type = typeof(_T);
|
||||
var parse_method = type.GetMethod("Parse");
|
||||
var parse_method = type.GetMethod(nameof(int.Parse), BindingFlags.Static | BindingFlags.Public, null, new Type[] { typeof(string) }, null);
|
||||
if (parse_method != null &&
|
||||
(parse_method.ReturnType.IsSubclassOf(type) || parse_method.ReturnType == type) &&
|
||||
parse_method.GetParameters().Length == 1 &&
|
||||
@@ -2192,3 +2206,29 @@ namespace Convention
|
||||
}
|
||||
}
|
||||
|
||||
namespace Convention
|
||||
{
|
||||
public static partial class ConventionUtility
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Unity engine function to disable the GC
|
||||
/// </summary>
|
||||
public static void GC_disable()
|
||||
{
|
||||
#if !UNITY_EDITOR
|
||||
GarbageCollector.GCMode = GarbageCollector.Mode.Disabled;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unity engine function to enable the GC
|
||||
/// </summary>
|
||||
public static void GC_enable()
|
||||
{
|
||||
#if !UNITY_EDITOR
|
||||
GarbageCollector.GCMode = GarbageCollector.Mode.Enabled;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,6 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
@@ -58,24 +57,28 @@ namespace Convention
|
||||
};
|
||||
}
|
||||
|
||||
private string FullPath;
|
||||
private string OriginPath;
|
||||
private FileSystemInfo OriginInfo;
|
||||
public ToolFile(string path)
|
||||
{
|
||||
FullPath = Path.GetFullPath(Environment.ExpandEnvironmentVariables(path));
|
||||
OriginPath = Environment.ExpandEnvironmentVariables(path).Replace('\\', '/');
|
||||
Refresh();
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return this.FullPath;
|
||||
return this.OriginPath;
|
||||
}
|
||||
|
||||
#region Path
|
||||
|
||||
public static implicit operator string(ToolFile data) => data.FullPath;
|
||||
public static implicit operator string(ToolFile data) => data.OriginPath;
|
||||
public string GetAbsPath()
|
||||
{
|
||||
return Path.GetFullPath(OriginPath);
|
||||
}
|
||||
public string GetFullPath()
|
||||
{
|
||||
return this.FullPath;
|
||||
return this.OriginPath;
|
||||
}
|
||||
public string GetName(bool is_ignore_extension = false)
|
||||
{
|
||||
@@ -86,13 +89,13 @@ namespace Convention
|
||||
else if (OriginInfo is DirectoryInfo dinfo)
|
||||
return dinfo.Name;
|
||||
}
|
||||
var result = this.FullPath[..(
|
||||
(this.FullPath.Contains('.') && is_ignore_extension)
|
||||
? this.FullPath.LastIndexOf('.')
|
||||
var result = this.OriginPath[..(
|
||||
(this.OriginPath.Contains('.') && is_ignore_extension)
|
||||
? this.OriginPath.LastIndexOf('.')
|
||||
: ^0
|
||||
)]
|
||||
[..(
|
||||
(this.FullPath[^1] == '/' || this.FullPath[^1] == '\\')
|
||||
(this.OriginPath[^1] == '/' || this.OriginPath[^1] == '\\')
|
||||
? ^1
|
||||
: ^0
|
||||
)];
|
||||
@@ -103,32 +106,32 @@ namespace Convention
|
||||
{
|
||||
if (IsDir())
|
||||
return "";
|
||||
return this.FullPath[(
|
||||
(this.FullPath.Contains('.'))
|
||||
? this.FullPath.LastIndexOf('.')
|
||||
return this.OriginPath[(
|
||||
(this.OriginPath.Contains('.'))
|
||||
? this.OriginPath.LastIndexOf('.')
|
||||
: ^0
|
||||
)..];
|
||||
}
|
||||
|
||||
public string GetFilename(bool is_without_extension = false)
|
||||
{
|
||||
if (is_without_extension && Path.HasExtension(FullPath))
|
||||
if (is_without_extension && Path.HasExtension(OriginPath))
|
||||
{
|
||||
return Path.GetFileNameWithoutExtension(FullPath);
|
||||
return Path.GetFileNameWithoutExtension(OriginPath);
|
||||
}
|
||||
else if (FullPath.EndsWith(Path.DirectorySeparatorChar.ToString()) || FullPath.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
|
||||
else if (OriginPath.EndsWith(Path.DirectorySeparatorChar.ToString()) || OriginPath.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
|
||||
{
|
||||
return Path.GetFileName(FullPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
|
||||
return Path.GetFileName(OriginPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
|
||||
}
|
||||
else
|
||||
{
|
||||
return Path.GetFileName(FullPath);
|
||||
return Path.GetFileName(OriginPath);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetDir()
|
||||
{
|
||||
return Path.GetDirectoryName(FullPath);
|
||||
return Path.GetDirectoryName(OriginPath);
|
||||
}
|
||||
|
||||
public ToolFile GetDirToolFile()
|
||||
@@ -138,7 +141,7 @@ namespace Convention
|
||||
|
||||
public string GetCurrentDirName()
|
||||
{
|
||||
return Path.GetDirectoryName(FullPath);
|
||||
return Path.GetDirectoryName(OriginPath);
|
||||
}
|
||||
|
||||
public ToolFile GetParentDir()
|
||||
@@ -150,7 +153,7 @@ namespace Convention
|
||||
|
||||
#region Exists
|
||||
|
||||
public bool Exists() => File.Exists(FullPath) || Directory.Exists(FullPath);
|
||||
public bool Exists() => File.Exists(OriginPath) || Directory.Exists(OriginPath);
|
||||
|
||||
public static implicit operator bool(ToolFile file) => file.Exists();
|
||||
|
||||
@@ -162,13 +165,13 @@ namespace Convention
|
||||
OriginInfo = null;
|
||||
else if (IsDir())
|
||||
{
|
||||
OriginInfo = new DirectoryInfo(FullPath);
|
||||
FullPath = Path.GetFullPath(FullPath);
|
||||
OriginInfo = new DirectoryInfo(OriginPath);
|
||||
OriginPath = Path.GetFullPath(OriginPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
OriginInfo = new FileInfo(FullPath);
|
||||
FullPath = Path.GetFullPath(FullPath);
|
||||
OriginInfo = new FileInfo(OriginPath);
|
||||
OriginPath = Path.GetFullPath(OriginPath);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -181,7 +184,7 @@ namespace Convention
|
||||
}
|
||||
public T LoadAsJson<T>(string key = "data")
|
||||
{
|
||||
return ES3.Load<T>(key, FullPath);
|
||||
return ES3.Load<T>(key, OriginPath);
|
||||
}
|
||||
public string LoadAsText()
|
||||
{
|
||||
@@ -217,7 +220,7 @@ namespace Convention
|
||||
if (IsFile() == false)
|
||||
throw new InvalidOperationException("Target is not a file");
|
||||
|
||||
var lines = File.ReadAllLines(FullPath);
|
||||
var lines = File.ReadAllLines(OriginPath);
|
||||
var result = new List<string[]>();
|
||||
|
||||
foreach (var line in lines)
|
||||
@@ -244,11 +247,11 @@ namespace Convention
|
||||
|
||||
public Texture2D LoadAsImage()
|
||||
{
|
||||
return ES3Plugin.LoadImage(FullPath);
|
||||
return ES3Plugin.LoadImage(OriginPath);
|
||||
}
|
||||
public IEnumerator LoadAsImage([In] Action<Texture2D> callback)
|
||||
{
|
||||
UnityWebRequest request = UnityWebRequestTexture.GetTexture(FullPath);
|
||||
UnityWebRequest request = UnityWebRequestTexture.GetTexture(OriginPath);
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.result == UnityWebRequest.Result.Success)
|
||||
@@ -259,11 +262,11 @@ namespace Convention
|
||||
}
|
||||
public AudioClip LoadAsAudio()
|
||||
{
|
||||
return ES3Plugin.LoadAudio(FullPath, GetAudioType(FullPath));
|
||||
return ES3Plugin.LoadAudio(OriginPath, GetAudioType(OriginPath));
|
||||
}
|
||||
public IEnumerator LoadAsAudio([In] Action<AudioClip> callback)
|
||||
{
|
||||
UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(FullPath, GetAudioType(FullPath));
|
||||
UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(OriginPath, GetAudioType(OriginPath));
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.result == UnityWebRequest.Result.Success)
|
||||
@@ -274,18 +277,18 @@ namespace Convention
|
||||
}
|
||||
public AssetBundle LoadAsAssetBundle()
|
||||
{
|
||||
return AssetBundle.LoadFromFile(FullPath);
|
||||
return AssetBundle.LoadFromFile(OriginPath);
|
||||
}
|
||||
public IEnumerator LoadAsAssetBundle([In] Action<AssetBundle> callback)
|
||||
{
|
||||
AssetBundleCreateRequest result = AssetBundle.LoadFromFileAsync(FullPath);
|
||||
AssetBundleCreateRequest result = AssetBundle.LoadFromFileAsync(OriginPath);
|
||||
yield return result;
|
||||
callback(result.assetBundle);
|
||||
yield return null;
|
||||
}
|
||||
public IEnumerator LoadAsAssetBundle([In]Action<float> progress, [In] Action<AssetBundle> callback)
|
||||
{
|
||||
AssetBundleCreateRequest result = AssetBundle.LoadFromFileAsync(FullPath);
|
||||
AssetBundleCreateRequest result = AssetBundle.LoadFromFileAsync(OriginPath);
|
||||
while (result.isDone == false)
|
||||
{
|
||||
progress(result.progress);
|
||||
@@ -311,11 +314,11 @@ namespace Convention
|
||||
}
|
||||
public void SaveAsJson<T>(T data, string key = "data")
|
||||
{
|
||||
ES3.Save(key, data,FullPath);
|
||||
ES3.Save(key, data,OriginPath);
|
||||
}
|
||||
public void SaveAsText(string data)
|
||||
{
|
||||
using var fs = new FileStream(FullPath, FileMode.CreateNew, FileAccess.Write);
|
||||
using var fs = new FileStream(OriginPath, FileMode.CreateNew, FileAccess.Write);
|
||||
using var sw = new StreamWriter(fs);
|
||||
sw.Write(data);
|
||||
sw.Flush();
|
||||
@@ -337,7 +340,7 @@ namespace Convention
|
||||
|
||||
public void SaveAsBinary(byte[] data)
|
||||
{
|
||||
SaveDataAsBinary(FullPath, data, (OriginInfo as FileInfo).OpenWrite());
|
||||
SaveDataAsBinary(OriginPath, data, (OriginInfo as FileInfo).OpenWrite());
|
||||
}
|
||||
|
||||
public void SaveAsCsv(List<string[]> csvData)
|
||||
@@ -346,7 +349,7 @@ namespace Convention
|
||||
throw new InvalidOperationException("Target is not a file");
|
||||
|
||||
var lines = csvData.Select(row => string.Join(",", row));
|
||||
File.WriteAllLines(FullPath, lines);
|
||||
File.WriteAllLines(OriginPath, lines);
|
||||
}
|
||||
|
||||
public void SaveAsXml(string xmlData)
|
||||
@@ -380,9 +383,9 @@ namespace Convention
|
||||
{
|
||||
if (Exists())
|
||||
{
|
||||
return Directory.Exists(this.FullPath);
|
||||
return Directory.Exists(this.OriginPath);
|
||||
}
|
||||
return this.FullPath[^1] == '\\' || this.FullPath[^1] == '/';
|
||||
return this.OriginPath[^1] == '\\' || this.OriginPath[^1] == '/';
|
||||
}
|
||||
|
||||
public bool IsFile()
|
||||
@@ -420,7 +423,7 @@ namespace Convention
|
||||
{
|
||||
if (IsDir())
|
||||
{
|
||||
return GetDirectorySize(FullPath);
|
||||
return GetDirectorySize(OriginPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -458,6 +461,20 @@ namespace Convention
|
||||
#region Operator
|
||||
|
||||
public static ToolFile operator |(ToolFile left, string rightPath)
|
||||
{
|
||||
if (rightPath == null)
|
||||
{
|
||||
return new ToolFile(left.IsDir() ? left.GetFullPath() : $"{left.GetFullPath().Replace('\\', '/')}/");
|
||||
}
|
||||
string first = left.GetFullPath().Replace('\\','/');
|
||||
string second = rightPath.Replace('\\', '/');
|
||||
if (first == "./")
|
||||
return new ToolFile(second);
|
||||
else if (first == "../")
|
||||
return new ToolFile($"{new ToolFile(left.GetAbsPath()).GetParentDir()}/{second}");
|
||||
return new ToolFile($"{first}/{second}");
|
||||
}
|
||||
public static ToolFile operator |(ToolFile left, ToolFile rightPath)
|
||||
{
|
||||
string lp = left.GetFullPath();
|
||||
return new ToolFile(Path.Combine(lp, rightPath));
|
||||
@@ -467,19 +484,19 @@ namespace Convention
|
||||
{
|
||||
if (obj is ToolFile other)
|
||||
{
|
||||
return Path.GetFullPath(FullPath).Equals(Path.GetFullPath(other.FullPath), StringComparison.OrdinalIgnoreCase);
|
||||
return Path.GetFullPath(OriginPath).Equals(Path.GetFullPath(other.OriginPath), StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Path.GetFullPath(FullPath).GetHashCode();
|
||||
return Path.GetFullPath(OriginPath).GetHashCode();
|
||||
}
|
||||
|
||||
public ToolFile Open(string path)
|
||||
{
|
||||
this.FullPath = path;
|
||||
this.OriginPath = path;
|
||||
Refresh();
|
||||
return this;
|
||||
}
|
||||
@@ -492,9 +509,9 @@ namespace Convention
|
||||
if (Exists() == false)
|
||||
{
|
||||
if (IsDir())
|
||||
Directory.CreateDirectory(this.FullPath);
|
||||
Directory.CreateDirectory(this.OriginPath);
|
||||
else
|
||||
File.Create(this.FullPath).Close();
|
||||
File.Create(this.OriginPath).Close();
|
||||
Refresh();
|
||||
}
|
||||
return this;
|
||||
@@ -511,7 +528,7 @@ namespace Convention
|
||||
var file = OriginInfo as FileInfo;
|
||||
file.MoveTo(newPath);
|
||||
}
|
||||
FullPath = newPath;
|
||||
OriginPath = newPath;
|
||||
return this;
|
||||
}
|
||||
public ToolFile Move(string path)
|
||||
@@ -537,7 +554,7 @@ namespace Convention
|
||||
public ToolFile Copy(string targetPath = null)
|
||||
{
|
||||
if (targetPath == null)
|
||||
return new ToolFile(FullPath);
|
||||
return new ToolFile(OriginPath);
|
||||
|
||||
if (!Exists())
|
||||
throw new FileNotFoundException("File not found");
|
||||
@@ -547,9 +564,9 @@ namespace Convention
|
||||
targetFile = targetFile | GetFilename();
|
||||
|
||||
if (IsDir())
|
||||
CopyDirectory(FullPath, targetFile.GetFullPath());
|
||||
CopyDirectory(OriginPath, targetFile.GetFullPath());
|
||||
else
|
||||
File.Copy(FullPath, targetFile.GetFullPath());
|
||||
File.Copy(OriginPath, targetFile.GetFullPath());
|
||||
|
||||
return targetFile;
|
||||
}
|
||||
@@ -575,9 +592,9 @@ namespace Convention
|
||||
public ToolFile Delete()
|
||||
{
|
||||
if (IsDir())
|
||||
Directory.Delete(FullPath);
|
||||
Directory.Delete(OriginPath);
|
||||
else
|
||||
File.Delete(FullPath);
|
||||
File.Delete(OriginPath);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -598,7 +615,7 @@ namespace Convention
|
||||
}
|
||||
public ToolFile TryCreateParentPath()
|
||||
{
|
||||
string dirPath = Path.GetDirectoryName(FullPath);
|
||||
string dirPath = Path.GetDirectoryName(OriginPath);
|
||||
if (!string.IsNullOrEmpty(dirPath) && !Directory.Exists(dirPath))
|
||||
{
|
||||
Directory.CreateDirectory(dirPath);
|
||||
@@ -609,14 +626,14 @@ namespace Convention
|
||||
{
|
||||
if (!IsDir())
|
||||
throw new InvalidOperationException("Target is not a directory");
|
||||
return Directory.GetFileSystemEntries(FullPath).ToList();
|
||||
return Directory.GetFileSystemEntries(OriginPath).ToList();
|
||||
}
|
||||
public List<ToolFile> DirToolFileIter()
|
||||
{
|
||||
if (!IsDir())
|
||||
throw new InvalidOperationException("Target is not a directory");
|
||||
var result = new List<ToolFile>();
|
||||
foreach (var entry in Directory.GetFileSystemEntries(FullPath))
|
||||
foreach (var entry in Directory.GetFileSystemEntries(OriginPath))
|
||||
{
|
||||
result.Add(new ToolFile(entry));
|
||||
}
|
||||
@@ -624,7 +641,7 @@ namespace Convention
|
||||
}
|
||||
public ToolFile BackToParentDir()
|
||||
{
|
||||
FullPath = GetDir();
|
||||
OriginPath = GetDir();
|
||||
Refresh();
|
||||
return this;
|
||||
}
|
||||
@@ -633,7 +650,7 @@ namespace Convention
|
||||
if (!IsDir())
|
||||
throw new InvalidOperationException("Target is not a directory");
|
||||
|
||||
var entries = Directory.GetFileSystemEntries(FullPath);
|
||||
var entries = Directory.GetFileSystemEntries(OriginPath);
|
||||
if (ignore_folder)
|
||||
{
|
||||
return entries.Count(entry => File.Exists(entry));
|
||||
@@ -740,13 +757,13 @@ namespace Convention
|
||||
{
|
||||
if (IsDir())
|
||||
{
|
||||
ZipFile.CreateFromDirectory(FullPath, outputPath);
|
||||
ZipFile.CreateFromDirectory(OriginPath, outputPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var archive = ZipFile.Open(outputPath, ZipArchiveMode.Create))
|
||||
{
|
||||
archive.CreateEntryFromFile(FullPath, GetFilename());
|
||||
archive.CreateEntryFromFile(OriginPath, GetFilename());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -778,7 +795,7 @@ namespace Convention
|
||||
|
||||
try
|
||||
{
|
||||
ZipFile.ExtractToDirectory(FullPath, outputPath);
|
||||
ZipFile.ExtractToDirectory(OriginPath, outputPath);
|
||||
return new ToolFile(outputPath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -897,7 +914,7 @@ namespace Convention
|
||||
try
|
||||
{
|
||||
using (var hashAlgorithm = GetHashAlgorithm(algorithm))
|
||||
using (var stream = File.OpenRead(FullPath))
|
||||
using (var stream = File.OpenRead(OriginPath))
|
||||
{
|
||||
byte[] hash = hashAlgorithm.ComputeHash(stream);
|
||||
return BitConverter.ToString(hash).Replace("-", "").ToLower();
|
||||
@@ -955,7 +972,7 @@ namespace Convention
|
||||
|
||||
// 注意:这是一个简化实现,实际的文件监控需要更复杂的实现
|
||||
// 可以使用 FileSystemWatcher 来实现完整功能
|
||||
var watcher = new FileSystemWatcher(FullPath)
|
||||
var watcher = new FileSystemWatcher(OriginPath)
|
||||
{
|
||||
IncludeSubdirectories = recursive,
|
||||
EnableRaisingEvents = true
|
||||
@@ -1087,7 +1104,7 @@ namespace Convention
|
||||
|
||||
try
|
||||
{
|
||||
var fileInfo = new FileInfo(FullPath);
|
||||
var fileInfo = new FileInfo(OriginPath);
|
||||
var attributes = fileInfo.Attributes;
|
||||
|
||||
permissions["read"] = true; // 如果能获取到文件信息,说明可读
|
||||
@@ -1114,7 +1131,7 @@ namespace Convention
|
||||
|
||||
try
|
||||
{
|
||||
var fileInfo = new FileInfo(FullPath);
|
||||
var fileInfo = new FileInfo(OriginPath);
|
||||
var attributes = fileInfo.Attributes;
|
||||
|
||||
if (write.HasValue)
|
||||
|
679
Convention/[Runtime]/Interaction.cs
Normal file
679
Convention/[Runtime]/Interaction.cs
Normal file
@@ -0,0 +1,679 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace Convention
|
||||
{
|
||||
/// <summary>
|
||||
/// 统一的文件交互类,支持本地文件、网络文件和localhost路径的自适应处理
|
||||
/// 使用UnityWebRequest实现跨平台兼容,支持WebGL和IL2CPP
|
||||
///
|
||||
/// <list type="bullet"><see cref="ToolFile"/>是依赖项</list>
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public sealed class Interaction
|
||||
{
|
||||
#region Fields and Properties
|
||||
|
||||
private string originalPath;
|
||||
private string processedPath;
|
||||
private PathType pathType;
|
||||
private object cachedData;
|
||||
|
||||
public string OriginalPath => originalPath;
|
||||
public string ProcessedPath => processedPath;
|
||||
public PathType Type => pathType;
|
||||
|
||||
public enum PathType
|
||||
{
|
||||
LocalFile, // 本地文件 (file://)
|
||||
NetworkHTTP, // 网络HTTP (http://)
|
||||
NetworkHTTPS, // 网络HTTPS (https://)
|
||||
LocalServer, // 本地服务器 (localhost)
|
||||
StreamingAssets // StreamingAssets目录
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public Interaction(string path)
|
||||
{
|
||||
SetPath(path);
|
||||
}
|
||||
|
||||
#region Setup
|
||||
|
||||
/// <summary>
|
||||
/// 设置并处理路径
|
||||
/// </summary>
|
||||
public Interaction SetPath(string path)
|
||||
{
|
||||
originalPath = path;
|
||||
processedPath = ProcessPath(path);
|
||||
pathType = DeterminePathType(path);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理路径,转换为UnityWebRequest可识别的格式
|
||||
/// </summary>
|
||||
private string ProcessPath(string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
return path;
|
||||
|
||||
// 网络路径直接返回
|
||||
if (path.StartsWith("http://") || path.StartsWith("https://"))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
// localhost处理
|
||||
if (path.StartsWith("localhost"))
|
||||
{
|
||||
return path.StartsWith("localhost/") ? "http://" + path : "http://localhost/" + path;
|
||||
}
|
||||
|
||||
// StreamingAssets路径处理
|
||||
if (path.StartsWith("StreamingAssets/") || path.StartsWith("StreamingAssets\\"))
|
||||
{
|
||||
return Path.Combine(Application.streamingAssetsPath, path.Substring(16)).Replace("\\", "/");
|
||||
}
|
||||
|
||||
// 本地文件路径处理
|
||||
string fullPath = Path.IsPathRooted(path) ? path : Path.GetFullPath(path);
|
||||
|
||||
// WebGL平台特殊处理
|
||||
if (Application.platform == RuntimePlatform.WebGLPlayer)
|
||||
{
|
||||
// WebGL只能访问StreamingAssets,尝试构建StreamingAssets路径
|
||||
return Application.streamingAssetsPath + "/" + Path.GetFileName(fullPath);
|
||||
}
|
||||
|
||||
// 其他平台使用file://协议
|
||||
return "file:///" + fullPath.Replace("\\", "/");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 确定路径类型
|
||||
/// </summary>
|
||||
private PathType DeterminePathType(string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
return PathType.LocalFile;
|
||||
|
||||
if (path.StartsWith("https://"))
|
||||
return PathType.NetworkHTTPS;
|
||||
if (path.StartsWith("http://"))
|
||||
return PathType.NetworkHTTP;
|
||||
if (path.StartsWith("localhost"))
|
||||
return PathType.LocalServer;
|
||||
if (path.StartsWith("StreamingAssets"))
|
||||
return PathType.StreamingAssets;
|
||||
|
||||
return PathType.LocalFile;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Load
|
||||
|
||||
#region LoadAsync
|
||||
|
||||
public IEnumerator LoadAsTextAsync(Action<string> onSuccess, Action<string> onError = null)
|
||||
{
|
||||
using UnityWebRequest request = UnityWebRequest.Get(processedPath);
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.result == UnityWebRequest.Result.Success)
|
||||
{
|
||||
cachedData = request.downloadHandler.text;
|
||||
onSuccess?.Invoke((string)cachedData);
|
||||
}
|
||||
else
|
||||
{
|
||||
string errorMsg = $"Failed to load text from {originalPath}: {request.error}";
|
||||
onError?.Invoke(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator LoadAsBinaryAsync(Action<byte[]> onSuccess, Action<string> onError = null)
|
||||
{
|
||||
using UnityWebRequest request = UnityWebRequest.Get(processedPath);
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.result == UnityWebRequest.Result.Success)
|
||||
{
|
||||
cachedData = request.downloadHandler.data;
|
||||
onSuccess?.Invoke((byte[])cachedData);
|
||||
}
|
||||
else
|
||||
{
|
||||
string errorMsg = $"Failed to load binary from {originalPath}: {request.error}";
|
||||
onError?.Invoke(errorMsg);
|
||||
}
|
||||
}
|
||||
public IEnumerator LoadAsBinaryAsync(Action<float> progress, Action<byte[]> onSuccess, Action<string> onError = null)
|
||||
{
|
||||
using UnityWebRequest request = UnityWebRequest.Get(processedPath);
|
||||
var result = request.SendWebRequest();
|
||||
while (result.isDone == false)
|
||||
{
|
||||
progress(result.progress);
|
||||
yield return null;
|
||||
}
|
||||
if (request.result == UnityWebRequest.Result.Success)
|
||||
{
|
||||
cachedData = request.downloadHandler.data;
|
||||
onSuccess?.Invoke((byte[])cachedData);
|
||||
}
|
||||
else
|
||||
{
|
||||
string errorMsg = $"Failed to load binary from {originalPath}: {request.error}";
|
||||
onError?.Invoke(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator LoadAsRawJsonAsync<T>(Action<T> onSuccess, Action<string> onError = null)
|
||||
{
|
||||
yield return LoadAsTextAsync(
|
||||
text =>
|
||||
{
|
||||
try
|
||||
{
|
||||
T result = JsonUtility.FromJson<T>(text);
|
||||
cachedData = result;
|
||||
onSuccess?.Invoke(result);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
onError?.Invoke($"Failed to parse JSON: {e.Message}");
|
||||
}
|
||||
},
|
||||
onError
|
||||
);
|
||||
}
|
||||
|
||||
public IEnumerator LoadAsJsonAsync<T>(Action<T> onSuccess, Action<string> onError = null)
|
||||
{
|
||||
yield return LoadAsTextAsync(
|
||||
text =>
|
||||
{
|
||||
try
|
||||
{
|
||||
using StreamReader reader = new(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(text)));
|
||||
var jsonReader = new ES3Internal.ES3JSONReader(reader.BaseStream, new(originalPath));
|
||||
onSuccess?.Invoke(jsonReader.Read<T>());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
onError?.Invoke($"Failed to parse JSON: {e.Message}");
|
||||
}
|
||||
},
|
||||
onError
|
||||
);
|
||||
}
|
||||
|
||||
public IEnumerator LoadAsImageAsync(Action<Texture2D> onSuccess, Action<string> onError = null)
|
||||
{
|
||||
using (UnityWebRequest request = UnityWebRequestTexture.GetTexture(processedPath))
|
||||
{
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.result == UnityWebRequest.Result.Success)
|
||||
{
|
||||
Texture2D texture = DownloadHandlerTexture.GetContent(request);
|
||||
cachedData = texture;
|
||||
onSuccess?.Invoke(texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
string errorMsg = $"Failed to load image from {originalPath}: {request.error}";
|
||||
onError?.Invoke(errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator LoadAsAudioAsync(Action<AudioClip> onSuccess, Action<string> onError = null, AudioType audioType = AudioType.UNKNOWN)
|
||||
{
|
||||
if (audioType == AudioType.UNKNOWN)
|
||||
audioType = GetAudioType(originalPath);
|
||||
|
||||
using (UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(processedPath, audioType))
|
||||
{
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.result == UnityWebRequest.Result.Success)
|
||||
{
|
||||
AudioClip audioClip = DownloadHandlerAudioClip.GetContent(request);
|
||||
cachedData = audioClip;
|
||||
onSuccess?.Invoke(audioClip);
|
||||
}
|
||||
else
|
||||
{
|
||||
string errorMsg = $"Failed to load audio from {originalPath}: {request.error}";
|
||||
onError?.Invoke(errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator LoadAsAssetBundle(Action<float> progress, Action<AssetBundle> onSuccess, Action<string> onError = null)
|
||||
{
|
||||
AssetBundleCreateRequest request = null;
|
||||
yield return LoadAsBinaryAsync(x => progress(x * 0.5f), data => request = AssetBundle.LoadFromMemoryAsync(data), onError);
|
||||
while (request.isDone == false)
|
||||
{
|
||||
progress(0.5f + request.progress * 0.5f);
|
||||
yield return null;
|
||||
}
|
||||
try
|
||||
{
|
||||
AssetBundle bundle = request.assetBundle;
|
||||
if (bundle != null)
|
||||
{
|
||||
cachedData = bundle;
|
||||
onSuccess?.Invoke(bundle);
|
||||
}
|
||||
else
|
||||
{
|
||||
onError?.Invoke($"Failed to load AssetBundle from data.");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
onError?.Invoke($"Failed to load AssetBundle: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Load Sync
|
||||
|
||||
public string LoadAsText()
|
||||
{
|
||||
string buffer = null;
|
||||
bool isEnd = false;
|
||||
bool IsError = false;
|
||||
var it = LoadAsTextAsync(x =>
|
||||
{
|
||||
buffer = x;
|
||||
isEnd = true;
|
||||
}, e =>
|
||||
{
|
||||
IsError = true;
|
||||
throw new Exception(e);
|
||||
});
|
||||
try
|
||||
{
|
||||
while (!isEnd)
|
||||
{
|
||||
it.MoveNext();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
if(IsError)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public byte[] LoadAsBinary()
|
||||
{
|
||||
byte[] buffer = null;
|
||||
bool isEnd = false;
|
||||
bool IsError = false;
|
||||
var it = LoadAsBinaryAsync(x =>
|
||||
{
|
||||
buffer = x;
|
||||
isEnd = true;
|
||||
}, e =>
|
||||
{
|
||||
IsError = true;
|
||||
throw new Exception(e);
|
||||
});
|
||||
try
|
||||
{
|
||||
while (!isEnd)
|
||||
{
|
||||
it.MoveNext();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (IsError)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public T LoadAsRawJson<T>()
|
||||
{
|
||||
T buffer = default;
|
||||
bool isEnd = false;
|
||||
bool IsError = false;
|
||||
var it = LoadAsRawJsonAsync<T>(x =>
|
||||
{
|
||||
buffer = x;
|
||||
isEnd = true;
|
||||
}, e =>
|
||||
{
|
||||
IsError = true;
|
||||
throw new Exception(e);
|
||||
});
|
||||
try
|
||||
{
|
||||
while (!isEnd)
|
||||
{
|
||||
it.MoveNext();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (IsError)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public T LoadAsJson<T>()
|
||||
{
|
||||
T buffer = default;
|
||||
bool isEnd = false;
|
||||
bool IsError = false;
|
||||
var it = LoadAsJsonAsync<T>(x =>
|
||||
{
|
||||
buffer = x;
|
||||
isEnd = true;
|
||||
}, e =>
|
||||
{
|
||||
IsError = true;
|
||||
throw new Exception(e);
|
||||
});
|
||||
try
|
||||
{
|
||||
while (!isEnd)
|
||||
{
|
||||
it.MoveNext();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (IsError)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public Texture2D LoadAsImage()
|
||||
{
|
||||
Texture2D buffer = null;
|
||||
bool isEnd = false;
|
||||
bool IsError = false;
|
||||
var it = LoadAsImageAsync(x =>
|
||||
{
|
||||
buffer = x;
|
||||
isEnd = true;
|
||||
}, e =>
|
||||
{
|
||||
IsError = true;
|
||||
throw new Exception(e);
|
||||
});
|
||||
try
|
||||
{
|
||||
while (!isEnd)
|
||||
{
|
||||
it.MoveNext();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (IsError)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public AudioClip LoadAsAudio(AudioType audioType = AudioType.UNKNOWN)
|
||||
{
|
||||
AudioClip buffer = null;
|
||||
bool isEnd = false;
|
||||
bool IsError = false;
|
||||
var it = LoadAsAudioAsync(x =>
|
||||
{
|
||||
buffer = x;
|
||||
isEnd = true;
|
||||
}, e =>
|
||||
{
|
||||
IsError = true;
|
||||
throw new Exception(e);
|
||||
}, audioType);
|
||||
try
|
||||
{
|
||||
while (!isEnd)
|
||||
{
|
||||
it.MoveNext();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (IsError)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Save
|
||||
|
||||
public Interaction SaveAsText(string content)
|
||||
{
|
||||
if (Application.platform == RuntimePlatform.WebGLPlayer)
|
||||
{
|
||||
throw new NotSupportedException("WebGL平台不支持文件保存。");
|
||||
}
|
||||
|
||||
if (pathType != PathType.LocalFile)
|
||||
{
|
||||
throw new NotSupportedException("仅支持保存到本地文件路径。");
|
||||
}
|
||||
|
||||
new ToolFile(originalPath).SaveAsText(content);
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
public Interaction SaveAsBinary(byte[] data)
|
||||
{
|
||||
if (Application.platform == RuntimePlatform.WebGLPlayer)
|
||||
{
|
||||
throw new NotSupportedException("WebGL平台不支持文件保存。");
|
||||
}
|
||||
|
||||
if (pathType != PathType.LocalFile)
|
||||
{
|
||||
throw new NotSupportedException("仅支持保存到本地文件路径。");
|
||||
}
|
||||
|
||||
new ToolFile(originalPath).SaveAsBinary(data);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Interaction SaveAsRawJson<T>(T obj)
|
||||
{
|
||||
new ToolFile(originalPath).SaveAsRawJson(obj);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Interaction SaveAsJson<T>(T obj)
|
||||
{
|
||||
new ToolFile(originalPath).SaveAsJson(obj);
|
||||
return this;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tools
|
||||
|
||||
/// <summary>
|
||||
/// 获取本地文件路径
|
||||
/// </summary>
|
||||
private string GetLocalPath()
|
||||
{
|
||||
if (processedPath.StartsWith("file:///"))
|
||||
{
|
||||
return processedPath.Substring(8);
|
||||
}
|
||||
return originalPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据文件扩展名获取音频类型
|
||||
/// </summary>
|
||||
private AudioType GetAudioType(string path)
|
||||
{
|
||||
return BasicAudioSystem.GetAudioType(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查文件是否存在
|
||||
/// </summary>
|
||||
public bool Exists()
|
||||
{
|
||||
if (pathType == PathType.LocalFile && Application.platform != RuntimePlatform.WebGLPlayer)
|
||||
{
|
||||
return File.Exists(GetLocalPath());
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO : 网络文件和WebGL平台需要通过请求检查
|
||||
// 当前默认存在
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步检查文件是否存在
|
||||
/// </summary>
|
||||
public IEnumerator ExistsAsync(Action<bool> callback)
|
||||
{
|
||||
using UnityWebRequest request = UnityWebRequest.Head(processedPath);
|
||||
yield return request.SendWebRequest();
|
||||
callback?.Invoke(request.result == UnityWebRequest.Result.Success);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Operator
|
||||
|
||||
public static implicit operator string(Interaction interaction) => interaction?.originalPath;
|
||||
|
||||
public override string ToString() => originalPath;
|
||||
|
||||
/// <summary>
|
||||
/// 路径连接操作符
|
||||
/// </summary>
|
||||
public static Interaction operator |(Interaction left, string rightPath)
|
||||
{
|
||||
if (left.pathType == PathType.NetworkHTTP || left.pathType == PathType.NetworkHTTPS || left.pathType == PathType.LocalServer)
|
||||
{
|
||||
string baseUrl = left.originalPath;
|
||||
string newUrl = baseUrl.EndsWith("/") ? baseUrl + rightPath : baseUrl + "/" + rightPath;
|
||||
return new Interaction(newUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
string newPath = Path.Combine(left.originalPath, rightPath);
|
||||
return new Interaction(newPath);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tools
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件名
|
||||
/// </summary>
|
||||
public string GetFilename()
|
||||
{
|
||||
if (pathType == PathType.NetworkHTTP || pathType == PathType.NetworkHTTPS || pathType == PathType.LocalServer)
|
||||
{
|
||||
var uri = new Uri(processedPath);
|
||||
return Path.GetFileName(uri.AbsolutePath);
|
||||
}
|
||||
return Path.GetFileName(originalPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件扩展名
|
||||
/// </summary>
|
||||
public string GetExtension()
|
||||
{
|
||||
return Path.GetExtension(GetFilename());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查扩展名
|
||||
/// </summary>
|
||||
public bool ExtensionIs(params string[] extensions)
|
||||
{
|
||||
string ext = GetExtension().ToLower();
|
||||
string extWithoutDot = ext.Length > 1 ? ext[1..] : "";
|
||||
|
||||
foreach (string extension in extensions)
|
||||
{
|
||||
string checkExt = extension.ToLower();
|
||||
if (ext == checkExt || extWithoutDot == checkExt || ext == "." + checkExt)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tools
|
||||
|
||||
/// <summary>
|
||||
/// 创建一个新的Interaction实例
|
||||
/// </summary>
|
||||
public static Interaction Create(string path) => new(path);
|
||||
|
||||
/// <summary>
|
||||
/// 从StreamingAssets创建
|
||||
/// </summary>
|
||||
public static Interaction FromStreamingAssets(string relativePath)
|
||||
{
|
||||
return new Interaction("StreamingAssets/" + relativePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从本地服务器创建
|
||||
/// </summary>
|
||||
public static Interaction FromLocalhost(string path, int port = 80)
|
||||
{
|
||||
string url = port == 80 ? $"localhost/{path}" : $"localhost:{port}/{path}";
|
||||
return new Interaction(url);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
11
Convention/[Runtime]/Interaction.cs.meta
Normal file
11
Convention/[Runtime]/Interaction.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 731a0091a68afe9458917e4dd0267656
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -18,7 +18,7 @@ namespace Convention.WindowsUI
|
||||
|
||||
[Content, OnlyPlayMode, Ignore] public RectTransformInfo BeforeMaximizeWindow = null;
|
||||
[Content, OnlyPlayMode, Ignore] public float BeforeMaximizeWindowBackgroundColorA = 1f;
|
||||
private bool IsMaximizeWindowMode = false;
|
||||
[SerializeField] private bool IsMaximizeWindowMode = false;
|
||||
[Content, OnlyPlayMode]
|
||||
public void MaximizeWindow()
|
||||
{
|
||||
|
@@ -118,6 +118,14 @@ namespace Convention.WindowsUI.Variant
|
||||
dropdownImage.eulerAngles = new(0, 0, 0);
|
||||
}
|
||||
|
||||
public virtual void RefreshChilds()
|
||||
{
|
||||
ConventionUtility.CreateSteps()
|
||||
.Next(() => Switch())
|
||||
.Next(() => Switch())
|
||||
.Invoke();
|
||||
}
|
||||
|
||||
public List<ItemEntry> CreateSubPropertyItem([In] PropertiesWindow propertyWindow, int count)
|
||||
{
|
||||
List<ItemEntry> result = new();
|
||||
|
Reference in New Issue
Block a user