NBC修改
This commit is contained in:
@@ -29,7 +29,7 @@ namespace NBF
|
||||
|
||||
public DefRunner()
|
||||
{
|
||||
MonoManager.Inst.OnUpdate += Update;
|
||||
App.OnUpdate += Update;
|
||||
StartCoroutine(new RunnerProcess("DefRunner", Coroutines, ReadyTask, FlushingOperation));
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,12 @@ namespace NBF
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class UIExtensionAutoBindAttribute : BaseAttribute
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class InputIconAttribute : BaseAttribute
|
||||
{
|
||||
|
||||
@@ -6,8 +6,8 @@ namespace NBF
|
||||
{
|
||||
public static void InputInit()
|
||||
{
|
||||
UI.Inst.On(UIEvents.UIShow, UIShow, null, 1);
|
||||
UI.Inst.On(UIEvents.UIHide, UIHide, null, 1);
|
||||
// UI.Inst.On(UIEvents.UIShow, UIShow, null, 1);
|
||||
// UI.Inst.On(UIEvents.UIHide, UIHide, null, 1);
|
||||
}
|
||||
|
||||
public static void Dispose()
|
||||
@@ -27,7 +27,7 @@ namespace NBF
|
||||
|
||||
private static void CheckUICursor()
|
||||
{
|
||||
var uis = UI.Inst.GetAllUI();
|
||||
var uis = App.UI.GetAllUI();
|
||||
bool showCursor = false;
|
||||
foreach (var ui in uis)
|
||||
{
|
||||
|
||||
@@ -44,10 +44,5 @@ namespace NBF.Setting
|
||||
var lang = LanguageConst.LanguageList[GetValue()];
|
||||
Lan.Inst.UseLanguage(lang.Language);
|
||||
}
|
||||
|
||||
// public override string GetDisplayString()
|
||||
// {
|
||||
// return ((SystemLanguage)GetValue()).ToString();
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -249,7 +249,7 @@ public class RuntimePreviewEditor : EditorWindow
|
||||
|
||||
if (isPreviewing)
|
||||
{
|
||||
_previewPanel = UI.Inst.GetUI<PreviewPanel>();
|
||||
_previewPanel = App.UI.GetUI<PreviewPanel>();
|
||||
if (_previewPanel == null)
|
||||
{
|
||||
isPreviewing = false;
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace NBF
|
||||
private void OnLoadBattleDone()
|
||||
{
|
||||
Debug.LogError("加载关卡结束===");
|
||||
UI.Inst.OpenUI<FishingPanel>();
|
||||
FishingPanel.Show();
|
||||
|
||||
|
||||
// BaseCamera.AddStack(StageCamera.main);
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace NBF
|
||||
{
|
||||
Fishing()
|
||||
{
|
||||
MonoManager.Inst.OnUpdate += Update;
|
||||
App.OnUpdate += Update;
|
||||
}
|
||||
|
||||
private static Fishing _inst;
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"name": "NBC.Asset",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:b3c9c3fa0cbae6e438ac062aa5d78b76"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f1730001a164742976be57710e92549
|
||||
timeCreated: 1715239743
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8922eeb5251f469eb8b055035568bef6
|
||||
timeCreated: 1715241124
|
||||
@@ -1,9 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class BaseAttribute: Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏框架异常类
|
||||
/// </summary>
|
||||
public class WhootException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化游戏框架异常类的新实例
|
||||
/// </summary>
|
||||
public WhootException()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用指定错误消息初始化游戏框架异常类的新实例
|
||||
/// </summary>
|
||||
/// <param name="message">描述错误的消息</param>
|
||||
public WhootException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用指定错误消息和对作为此异常原因的内部异常的引用来初始化游戏框架异常类的新实例
|
||||
/// </summary>
|
||||
/// <param name="message">解释异常原因的错误消息</param>
|
||||
/// <param name="innerException">导致当前异常的异常。如果 innerException 参数不为空引用,则在处理内部异常的 catch 块中引发当前异常。</param>
|
||||
public WhootException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae413443f2a549eeb99383d1206cdae2
|
||||
timeCreated: 1603355057
|
||||
@@ -1,285 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
/// <summary>
|
||||
/// 一些基础类型的扩展
|
||||
/// </summary>
|
||||
public static class BasicValueExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否相等
|
||||
///
|
||||
/// 示例:
|
||||
/// <code>
|
||||
/// if (this.Is(player))
|
||||
/// {
|
||||
/// ...
|
||||
/// }
|
||||
/// </code>
|
||||
/// </summary>
|
||||
/// <param name="selfObj"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static bool Is(this object selfObj, object value)
|
||||
{
|
||||
return selfObj == value;
|
||||
}
|
||||
|
||||
public static bool Is<T>(this T selfObj, Func<T, bool> condition)
|
||||
{
|
||||
return condition(selfObj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 表达式成立 则执行 Action
|
||||
///
|
||||
/// 示例:
|
||||
/// <code>
|
||||
/// (1 == 1).Do(()=>XLog.Log("1 == 1");
|
||||
/// </code>
|
||||
/// </summary>
|
||||
/// <param name="selfCondition"></param>
|
||||
/// <param name="action"></param>
|
||||
/// <returns></returns>
|
||||
public static bool Do(this bool selfCondition, Action action)
|
||||
{
|
||||
if (selfCondition)
|
||||
{
|
||||
action();
|
||||
}
|
||||
|
||||
return selfCondition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 不管表达成不成立 都执行 Action,并把结果返回
|
||||
///
|
||||
/// 示例:
|
||||
/// <code>
|
||||
/// (1 == 1).Do((result)=>XLog.Log("1 == 1:" + result);
|
||||
/// </code>
|
||||
/// </summary>
|
||||
/// <param name="selfCondition"></param>
|
||||
/// <param name="action"></param>
|
||||
/// <returns></returns>
|
||||
public static bool Do(this bool selfCondition, Action<bool> action)
|
||||
{
|
||||
action(selfCondition);
|
||||
|
||||
return selfCondition;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 通用的扩展,类的扩展
|
||||
/// </summary>
|
||||
public static class ClassExtention
|
||||
{
|
||||
/// <summary>
|
||||
/// 功能:判断是否为空
|
||||
///
|
||||
/// 示例:
|
||||
/// <code>
|
||||
/// var simpleObject = new object();
|
||||
///
|
||||
/// if (simpleObject.IsNull()) // 等价于 simpleObject == null
|
||||
/// {
|
||||
/// // do sth
|
||||
/// }
|
||||
/// </code>
|
||||
/// </summary>
|
||||
/// <param name="selfObj">判断对象(this)</param>
|
||||
/// <typeparam name="T">对象的类型(可不填)</typeparam>
|
||||
/// <returns>是否为空</returns>
|
||||
public static bool IsNull<T>(this T selfObj) where T : class
|
||||
{
|
||||
return null == selfObj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 功能:判断不是为空
|
||||
/// 示例:
|
||||
/// <code>
|
||||
/// var simpleObject = new object();
|
||||
///
|
||||
/// if (simpleObject.IsNotNull()) // 等价于 simpleObject != null
|
||||
/// {
|
||||
/// // do sth
|
||||
/// }
|
||||
/// </code>
|
||||
/// </summary>
|
||||
/// <param name="selfObj">判断对象(this)</param>
|
||||
/// <typeparam name="T">对象的类型(可不填)</typeparam>
|
||||
/// <returns>是否不为空</returns>
|
||||
public static bool IsNotNull<T>(this T selfObj) where T : class
|
||||
{
|
||||
return null != selfObj;
|
||||
}
|
||||
|
||||
public static void DoIfNotNull<T>(this T selfObj, Action<T> action) where T : class
|
||||
{
|
||||
if (selfObj != null)
|
||||
{
|
||||
action(selfObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 泛型工具
|
||||
///
|
||||
/// 实例:
|
||||
/// <code>
|
||||
/// 示例:
|
||||
/// var typeName = GenericExtention.GetTypeName<string>();
|
||||
/// typeName.LogInfo(); // string
|
||||
/// </code>
|
||||
/// </summary>
|
||||
public static class GenericUtil
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取泛型名字
|
||||
/// <code>
|
||||
/// var typeName = GenericExtention.GetTypeName<string>();
|
||||
/// typeName.LogInfo(); // string
|
||||
/// </code>
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static string GetTypeName<T>()
|
||||
{
|
||||
return typeof(T).ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对 System.IO 的一些扩展
|
||||
/// </summary>
|
||||
public static class IOExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 检测路径是否存在,如果不存在则创建
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
public static string CreateDirIfNotExists4FilePath(this string path)
|
||||
{
|
||||
var direct = Path.GetDirectoryName(path);
|
||||
|
||||
if (!Directory.Exists(direct))
|
||||
{
|
||||
Directory.CreateDirectory(direct);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建新的文件夹,如果存在则不创建
|
||||
/// <code>
|
||||
/// var testDir = "Assets/TestFolder";
|
||||
/// testDir.CreateDirIfNotExists();
|
||||
/// // 结果为,在 Assets 目录下创建 TestFolder
|
||||
/// </code>
|
||||
/// </summary>
|
||||
public static string CreateDirIfNotExists(this string dirFullPath)
|
||||
{
|
||||
if (!Directory.Exists(dirFullPath))
|
||||
{
|
||||
Directory.CreateDirectory(dirFullPath);
|
||||
}
|
||||
|
||||
return dirFullPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除文件夹,如果存在
|
||||
/// <code>
|
||||
/// var testDir = "Assets/TestFolder";
|
||||
/// testDir.DeleteDirIfExists();
|
||||
/// // 结果为,在 Assets 目录下删除了 TestFolder
|
||||
/// </code>
|
||||
/// </summary>
|
||||
public static void DeleteDirIfExists(this string dirFullPath)
|
||||
{
|
||||
if (Directory.Exists(dirFullPath))
|
||||
{
|
||||
Directory.Delete(dirFullPath, true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空 Dir(保留目录),如果存在。
|
||||
/// <code>
|
||||
/// var testDir = "Assets/TestFolder";
|
||||
/// testDir.EmptyDirIfExists();
|
||||
/// // 结果为,清空了 TestFolder 里的内容
|
||||
/// </code>
|
||||
/// </summary>
|
||||
public static void EmptyDirIfExists(this string dirFullPath)
|
||||
{
|
||||
if (Directory.Exists(dirFullPath))
|
||||
{
|
||||
Directory.Delete(dirFullPath, true);
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(dirFullPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除文件 如果存在
|
||||
/// <code>
|
||||
/// // 示例
|
||||
/// var filePath = "Assets/Test.txt";
|
||||
/// File.Create("Assets/Test);
|
||||
/// filePath.DeleteFileIfExists();
|
||||
/// // 结果为,删除了 Test.txt
|
||||
/// </code>
|
||||
/// </summary>
|
||||
/// <param name="fileFullPath"></param>
|
||||
/// <returns> 是否进行了删除操作 </returns>
|
||||
public static bool DeleteFileIfExists(this string fileFullPath)
|
||||
{
|
||||
if (File.Exists(fileFullPath))
|
||||
{
|
||||
File.Delete(fileFullPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 合并路径
|
||||
/// <code>
|
||||
/// // 示例:
|
||||
/// Application.dataPath.CombinePath("Resources").LogInfo(); // /projectPath/Assets/Resources
|
||||
/// </code>
|
||||
/// </summary>
|
||||
/// <param name="selfPath"></param>
|
||||
/// <param name="toCombinePath"></param>
|
||||
/// <returns> 合并后的路径 </returns>
|
||||
public static string CombinePath(this string selfPath, string toCombinePath)
|
||||
{
|
||||
return Path.Combine(selfPath, toCombinePath);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 类型扩展
|
||||
/// </summary>
|
||||
public static class TypeEx
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取默认值
|
||||
/// </summary>
|
||||
/// <param name="targetType"></param>
|
||||
/// <returns></returns>
|
||||
public static object DefaultForType(this Type targetType)
|
||||
{
|
||||
return targetType.IsValueType ? Activator.CreateInstance(targetType) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac644ae7280c4a65ae705cb0e4dd782d
|
||||
timeCreated: 1680837299
|
||||
@@ -1,47 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public static class Log
|
||||
{
|
||||
public static bool Open = false;
|
||||
|
||||
static Log()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
Open = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// [Conditional("UNITY_EDITOR"), Conditional("LOG")]
|
||||
public static void Info(object message)
|
||||
{
|
||||
UnityEngine.Debug.Log(message);
|
||||
}
|
||||
|
||||
// [Conditional("UNITY_EDITOR"), Conditional("LOG")]
|
||||
public static void Warning(object message)
|
||||
{
|
||||
UnityEngine.Debug.LogWarning(message);
|
||||
}
|
||||
|
||||
// [Conditional("UNITY_EDITOR"), Conditional("LOG"), Conditional("ERROR")]
|
||||
public static void Error(object message)
|
||||
{
|
||||
UnityEngine.Debug.LogError(message);
|
||||
}
|
||||
|
||||
// [Conditional("UNITY_EDITOR"), Conditional("LOG"), Conditional("ERROR")]
|
||||
public static void Exception(Exception exception)
|
||||
{
|
||||
UnityEngine.Debug.LogException(exception);
|
||||
}
|
||||
|
||||
// [Conditional("UNITY_EDITOR"), Conditional("LOG"), Conditional("ERROR")]
|
||||
public static void Exception(Exception exception, UnityEngine.Object context)
|
||||
{
|
||||
UnityEngine.Debug.LogException(exception, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 03ea3505028b46fb8356fcd77001236c
|
||||
timeCreated: 1680834940
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"name": "NBC.Core"
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public static class App
|
||||
{
|
||||
static App()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#region Singletons
|
||||
|
||||
private static readonly Stack<Type> Stack = new();
|
||||
private static readonly Dictionary<Type, ASingleton> Singletons = new();
|
||||
|
||||
public static void AddSingleton(ASingleton singleton)
|
||||
{
|
||||
Type type = singleton.GetType();
|
||||
if (singleton is ISingletonReverseDispose)
|
||||
{
|
||||
Stack.Push(type);
|
||||
}
|
||||
|
||||
Singletons[type] = singleton;
|
||||
|
||||
singleton.Register();
|
||||
}
|
||||
|
||||
public static T AddSingleton<T>() where T : ASingleton, ISingletonAwake, new()
|
||||
{
|
||||
T singleton = new();
|
||||
singleton.Awake();
|
||||
|
||||
AddSingleton(singleton);
|
||||
return singleton;
|
||||
}
|
||||
|
||||
public static T AddSingleton<T, A>(A a) where T : ASingleton, ISingletonAwake<A>, new()
|
||||
{
|
||||
T singleton = new();
|
||||
singleton.Awake(a);
|
||||
|
||||
AddSingleton(singleton);
|
||||
return singleton;
|
||||
}
|
||||
|
||||
public static T AddSingleton<T, A, B>(A a, B b) where T : ASingleton, ISingletonAwake<A, B>, new()
|
||||
{
|
||||
T singleton = new();
|
||||
singleton.Awake(a, b);
|
||||
|
||||
AddSingleton(singleton);
|
||||
return singleton;
|
||||
}
|
||||
|
||||
public static T AddSingleton<T, A, B, C>(A a, B b, C c) where T : ASingleton, ISingletonAwake<A, B, C>, new()
|
||||
{
|
||||
T singleton = new();
|
||||
singleton.Awake(a, b, c);
|
||||
|
||||
AddSingleton(singleton);
|
||||
return singleton;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69ddfc81fb2f45fb94c0cc7fa5ddba7f
|
||||
timeCreated: 1733995455
|
||||
@@ -1,135 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct IdStruct
|
||||
{
|
||||
public short Process; // 14bit
|
||||
public uint Time; // 30bit
|
||||
public uint Value; // 20bit
|
||||
|
||||
public long ToLong()
|
||||
{
|
||||
ulong result = 0;
|
||||
result |= (ushort)this.Process;
|
||||
result <<= 30;
|
||||
result |= this.Time;
|
||||
result <<= 20;
|
||||
result |= this.Value;
|
||||
return (long)result;
|
||||
}
|
||||
|
||||
public IdStruct(uint time, short process, uint value)
|
||||
{
|
||||
this.Process = process;
|
||||
this.Time = time;
|
||||
this.Value = value;
|
||||
}
|
||||
|
||||
public IdStruct(long id)
|
||||
{
|
||||
ulong result = (ulong)id;
|
||||
this.Value = (uint)(result & IdGenerater.Mask20bit);
|
||||
result >>= 20;
|
||||
this.Time = (uint)result & IdGenerater.Mask30bit;
|
||||
result >>= 30;
|
||||
this.Process = (short)(result & IdGenerater.Mask14bit);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"process: {this.Process}, time: {this.Time}, value: {this.Value}";
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct InstanceIdStruct
|
||||
{
|
||||
public uint Time; // 32bit
|
||||
public uint Value; // 32bit
|
||||
|
||||
public long ToLong()
|
||||
{
|
||||
ulong result = 0;
|
||||
result |= this.Time;
|
||||
result <<= 32;
|
||||
result |= this.Value;
|
||||
return (long)result;
|
||||
}
|
||||
|
||||
public InstanceIdStruct(uint time, uint value)
|
||||
{
|
||||
this.Time = time;
|
||||
this.Value = value;
|
||||
}
|
||||
|
||||
public InstanceIdStruct(long id)
|
||||
{
|
||||
ulong result = (ulong)id;
|
||||
this.Value = (uint)(result & uint.MaxValue);
|
||||
result >>= 32;
|
||||
this.Time = (uint)(result & uint.MaxValue);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"time: {this.Time}, value: {this.Value}";
|
||||
}
|
||||
}
|
||||
|
||||
public class IdGenerater : Singleton<IdGenerater>, ISingletonAwake
|
||||
{
|
||||
public const int MaxZone = 1024;
|
||||
|
||||
public const int Mask14bit = 0x3fff;
|
||||
public const int Mask30bit = 0x3fffffff;
|
||||
public const int Mask20bit = 0xfffff;
|
||||
|
||||
private long epoch2022;
|
||||
|
||||
private int value;
|
||||
private int instanceIdValue;
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
long epoch1970tick = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000;
|
||||
this.epoch2022 = new DateTime(2022, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000 - epoch1970tick;
|
||||
}
|
||||
|
||||
private uint TimeSince2022()
|
||||
{
|
||||
uint a = (uint)((TimeInfo.Instance.FrameTime - this.epoch2022) / 1000);
|
||||
return a;
|
||||
}
|
||||
|
||||
public long GenerateId()
|
||||
{
|
||||
uint time = TimeSince2022();
|
||||
int v = 0;
|
||||
// 这里必须加锁
|
||||
lock (this)
|
||||
{
|
||||
if (++this.value > Mask20bit - 1)
|
||||
{
|
||||
this.value = 0;
|
||||
}
|
||||
|
||||
v = this.value;
|
||||
}
|
||||
|
||||
IdStruct idStruct = new(time, 3, (uint)v);
|
||||
return idStruct.ToLong();
|
||||
}
|
||||
|
||||
public long GenerateInstanceId()
|
||||
{
|
||||
uint time = this.TimeSince2022();
|
||||
uint v = (uint)Interlocked.Add(ref this.instanceIdValue, 1);
|
||||
InstanceIdStruct instanceIdStruct = new(time, v);
|
||||
return instanceIdStruct.ToLong();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be7c9a4c9ef34fadae987d40419f7509
|
||||
timeCreated: 1733994882
|
||||
@@ -1,85 +0,0 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public class MonoManager : MonoBehaviour
|
||||
{
|
||||
public event Action OnUpdate;
|
||||
public event Action OnLateUpdate;
|
||||
public event Action OnFixedUpdate;
|
||||
public event Action OnApplicationQuitAction;
|
||||
public event Action<bool> OnApplicationPauseAction;
|
||||
|
||||
private static bool IsQuiting { get; set; }
|
||||
|
||||
private static MonoManager _inst;
|
||||
|
||||
public static MonoManager Inst
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_inst != null || IsQuiting) return _inst;
|
||||
_inst = FindObjectOfType<MonoManager>();
|
||||
if (_inst == null)
|
||||
{
|
||||
_inst = new GameObject("_MonoTimer").AddComponent<MonoManager>();
|
||||
}
|
||||
|
||||
return _inst;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///Creates the MonoManager singleton
|
||||
public static void Create()
|
||||
{
|
||||
_inst = Inst;
|
||||
}
|
||||
|
||||
protected void OnApplicationQuit()
|
||||
{
|
||||
IsQuiting = true;
|
||||
OnApplicationQuitAction?.Invoke();
|
||||
}
|
||||
|
||||
protected void OnApplicationPause(bool isPause)
|
||||
{
|
||||
OnApplicationPauseAction?.Invoke(isPause);
|
||||
}
|
||||
|
||||
protected void Awake()
|
||||
{
|
||||
if (_inst != null && _inst != this)
|
||||
{
|
||||
DestroyImmediate(this.gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
DontDestroyOnLoad(gameObject);
|
||||
_inst = this;
|
||||
}
|
||||
|
||||
protected void Update()
|
||||
{
|
||||
try
|
||||
{
|
||||
OnUpdate?.Invoke();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void LateUpdate()
|
||||
{
|
||||
OnLateUpdate?.Invoke();
|
||||
}
|
||||
|
||||
protected void FixedUpdate()
|
||||
{
|
||||
OnFixedUpdate?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f5a966ae39a544c9b345cf9f8e178615
|
||||
timeCreated: 1733995883
|
||||
@@ -1,144 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public class DoubleMap<K, V>
|
||||
{
|
||||
private readonly Dictionary<K, V> kv = new();
|
||||
private readonly Dictionary<V, K> vk = new();
|
||||
|
||||
public DoubleMap()
|
||||
{
|
||||
}
|
||||
|
||||
public DoubleMap(int capacity)
|
||||
{
|
||||
kv = new Dictionary<K, V>(capacity);
|
||||
vk = new Dictionary<V, K>(capacity);
|
||||
}
|
||||
|
||||
public void ForEach(Action<K, V> action)
|
||||
{
|
||||
if (action == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Dictionary<K, V>.KeyCollection keys = kv.Keys;
|
||||
foreach (K key in keys)
|
||||
{
|
||||
action(key, kv[key]);
|
||||
}
|
||||
}
|
||||
|
||||
public List<K> Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
return new List<K>(kv.Keys);
|
||||
}
|
||||
}
|
||||
|
||||
public List<V> Values
|
||||
{
|
||||
get
|
||||
{
|
||||
return new List<V>(vk.Keys);
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(K key, V value)
|
||||
{
|
||||
if (key == null || value == null || kv.ContainsKey(key) || vk.ContainsKey(value))
|
||||
{
|
||||
return;
|
||||
}
|
||||
kv.Add(key, value);
|
||||
vk.Add(value, key);
|
||||
}
|
||||
|
||||
public V GetValueByKey(K key)
|
||||
{
|
||||
if (key != null && kv.ContainsKey(key))
|
||||
{
|
||||
return kv[key];
|
||||
}
|
||||
return default(V);
|
||||
}
|
||||
|
||||
public K GetKeyByValue(V value)
|
||||
{
|
||||
if (value != null && vk.ContainsKey(value))
|
||||
{
|
||||
return vk[value];
|
||||
}
|
||||
return default(K);
|
||||
}
|
||||
|
||||
public void RemoveByKey(K key)
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
V value;
|
||||
if (!kv.TryGetValue(key, out value))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
kv.Remove(key);
|
||||
vk.Remove(value);
|
||||
}
|
||||
|
||||
public void RemoveByValue(V value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
K key;
|
||||
if (!vk.TryGetValue(value, out key))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
kv.Remove(key);
|
||||
vk.Remove(value);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
kv.Clear();
|
||||
vk.Clear();
|
||||
}
|
||||
|
||||
public bool ContainsKey(K key)
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return kv.ContainsKey(key);
|
||||
}
|
||||
|
||||
public bool ContainsValue(V value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return vk.ContainsKey(value);
|
||||
}
|
||||
|
||||
public bool Contains(K key, V value)
|
||||
{
|
||||
if (key == null || value == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return kv.ContainsKey(key) && vk.ContainsKey(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public class UnOrderMultiMapSet<T, K> : Dictionary<T, HashSet<K>>
|
||||
{
|
||||
// 重用HashSet
|
||||
public new HashSet<K> this[T t]
|
||||
{
|
||||
get
|
||||
{
|
||||
HashSet<K> set;
|
||||
if (!this.TryGetValue(t, out set))
|
||||
{
|
||||
set = new HashSet<K>();
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<T, HashSet<K>> GetDictionary()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Add(T t, K k)
|
||||
{
|
||||
HashSet<K> set;
|
||||
this.TryGetValue(t, out set);
|
||||
if (set == null)
|
||||
{
|
||||
set = new HashSet<K>();
|
||||
base[t] = set;
|
||||
}
|
||||
|
||||
set.Add(k);
|
||||
}
|
||||
|
||||
public bool Remove(T t, K k)
|
||||
{
|
||||
HashSet<K> set;
|
||||
this.TryGetValue(t, out set);
|
||||
if (set == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!set.Remove(k))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (set.Count == 0)
|
||||
{
|
||||
this.Remove(t);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Contains(T t, K k)
|
||||
{
|
||||
HashSet<K> set;
|
||||
this.TryGetValue(t, out set);
|
||||
if (set == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return set.Contains(k);
|
||||
}
|
||||
|
||||
public new int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
int count = 0;
|
||||
foreach (KeyValuePair<T, HashSet<K>> kv in this)
|
||||
{
|
||||
count += kv.Value.Count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7f20db4c53f4bd1959c0bfcb4e1c8db
|
||||
timeCreated: 1733995067
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 603802d919d844e4a925c31a134040cb
|
||||
timeCreated: 1715240502
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0af3ab5ef5304e1fa7551bdcbbc99929
|
||||
timeCreated: 1716186772
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace NBC
|
||||
{
|
||||
public class Flag
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 57ed4dea58b7413b91b3156bcd12b97a
|
||||
timeCreated: 1716186802
|
||||
@@ -1,408 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public class IOCGroup : MonoBehaviour
|
||||
{
|
||||
private IOCContainer _container = new IOCContainer();
|
||||
public IOCContainer Container => _container;
|
||||
}
|
||||
|
||||
public class IOCContainer
|
||||
{
|
||||
private class Item
|
||||
{
|
||||
public object Instance;
|
||||
public MulticastDelegate Function;
|
||||
|
||||
public Item(object instance)
|
||||
{
|
||||
Instance = instance;
|
||||
}
|
||||
|
||||
public Item(MulticastDelegate function)
|
||||
{
|
||||
Function = function;
|
||||
}
|
||||
|
||||
public T Resolve<T>()
|
||||
{
|
||||
if (Instance != null)
|
||||
{
|
||||
return (T)Instance;
|
||||
}
|
||||
|
||||
return ((Func<T>)Function)();
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<Type, Dictionary<string, Item>> m_named = new Dictionary<Type, Dictionary<string, Item>>();
|
||||
private Dictionary<Type, Item> m_registered = new Dictionary<Type, Item>();
|
||||
private Dictionary<Type, Item> m_fallbacks = new Dictionary<Type, Item>();
|
||||
|
||||
public bool IsRegistered<T>(string name)
|
||||
{
|
||||
if (!m_named.TryGetValue(typeof(T), out Dictionary<string, Item> nameToItem))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return nameToItem.ContainsKey(name);
|
||||
}
|
||||
|
||||
public void Register<T>(string name, Func<T> func)
|
||||
{
|
||||
if (func == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(func));
|
||||
}
|
||||
|
||||
if (!m_named.TryGetValue(typeof(T), out var nameToItem))
|
||||
{
|
||||
nameToItem = new Dictionary<string, Item>();
|
||||
m_named.Add(typeof(T), nameToItem);
|
||||
}
|
||||
|
||||
if (nameToItem.ContainsKey(name))
|
||||
{
|
||||
Debug.LogWarningFormat("item with name {0} already registered", name);
|
||||
}
|
||||
|
||||
nameToItem[name] = new Item(func);
|
||||
}
|
||||
|
||||
public void Register<T>(string name, T instance)
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
throw new ArgumentNullException("func");
|
||||
}
|
||||
|
||||
if (!m_named.TryGetValue(typeof(T), out var nameToItem))
|
||||
{
|
||||
nameToItem = new Dictionary<string, Item>();
|
||||
m_named.Add(typeof(T), nameToItem);
|
||||
}
|
||||
|
||||
if (nameToItem.ContainsKey(name))
|
||||
{
|
||||
Debug.LogWarningFormat("item with name {0} already registered", name);
|
||||
}
|
||||
|
||||
nameToItem[name] = new Item(instance);
|
||||
}
|
||||
|
||||
public bool IsRegistered<T>()
|
||||
{
|
||||
return m_registered.ContainsKey(typeof(T));
|
||||
}
|
||||
|
||||
public void Register<T>(Func<T> func)
|
||||
{
|
||||
if (func == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(func));
|
||||
}
|
||||
|
||||
if (m_registered.ContainsKey(typeof(T)))
|
||||
{
|
||||
Debug.LogWarningFormat("type {0} already registered.", typeof(T).FullName);
|
||||
}
|
||||
|
||||
m_registered[typeof(T)] = new Item(func);
|
||||
}
|
||||
|
||||
public void Register<T>(T instance)
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(instance));
|
||||
}
|
||||
|
||||
if (m_registered.ContainsKey(typeof(T)))
|
||||
{
|
||||
Debug.LogWarningFormat("type {0} already registered.", typeof(T).FullName);
|
||||
}
|
||||
|
||||
m_registered[typeof(T)] = new Item(instance);
|
||||
}
|
||||
|
||||
public void Unregister<T>(string name, Func<T> func)
|
||||
{
|
||||
if (m_named.TryGetValue(typeof(T), out var nameToItem))
|
||||
{
|
||||
if (nameToItem.TryGetValue(name, out var item))
|
||||
{
|
||||
if (item.Function != null && item.Function.Equals(func))
|
||||
{
|
||||
nameToItem.Remove(name);
|
||||
if (nameToItem.Count == 0)
|
||||
{
|
||||
m_named.Remove(typeof(T));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Unregister<T>(string name, T instance)
|
||||
{
|
||||
if (m_named.TryGetValue(typeof(T), out var nameToItem))
|
||||
{
|
||||
if (nameToItem.TryGetValue(name, out var item))
|
||||
{
|
||||
if (ReferenceEquals(item.Instance, instance))
|
||||
{
|
||||
nameToItem.Remove(name);
|
||||
if (nameToItem.Count == 0)
|
||||
{
|
||||
m_named.Remove(typeof(T));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Unregister<T>(Func<T> func)
|
||||
{
|
||||
if (m_registered.TryGetValue(typeof(T), out var item))
|
||||
{
|
||||
if (item.Function != null && item.Function.Equals(func))
|
||||
{
|
||||
m_registered.Remove(typeof(T));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Unregister<T>(T instance)
|
||||
{
|
||||
if (m_registered.TryGetValue(typeof(T), out var item))
|
||||
{
|
||||
if (ReferenceEquals(item.Instance, instance))
|
||||
{
|
||||
m_registered.Remove(typeof(T));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Unregister<T>()
|
||||
{
|
||||
m_registered.Remove(typeof(T));
|
||||
}
|
||||
|
||||
public bool IsFallbackRegistered<T>()
|
||||
{
|
||||
return m_fallbacks.ContainsKey(typeof(T));
|
||||
}
|
||||
|
||||
public void RegisterFallback<T>(Func<T> func)
|
||||
{
|
||||
if (func == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(func));
|
||||
}
|
||||
|
||||
if (m_fallbacks.ContainsKey(typeof(T)))
|
||||
{
|
||||
Debug.LogWarningFormat("fallback for type {0} already registered.", typeof(T).FullName);
|
||||
}
|
||||
|
||||
m_fallbacks[typeof(T)] = new Item(func);
|
||||
}
|
||||
|
||||
public void RegisterFallback<T>(T instance)
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(instance));
|
||||
}
|
||||
|
||||
if (m_fallbacks.ContainsKey(typeof(T)))
|
||||
{
|
||||
Debug.LogWarningFormat("type {0} already registered.", typeof(T).FullName);
|
||||
}
|
||||
|
||||
m_fallbacks[typeof(T)] = new Item(instance);
|
||||
}
|
||||
|
||||
public void UnregisterFallback<T>(Func<T> func)
|
||||
{
|
||||
if (m_fallbacks.TryGetValue(typeof(T), out var item))
|
||||
{
|
||||
if (item.Function != null && item.Function.Equals(func))
|
||||
{
|
||||
m_fallbacks.Remove(typeof(T));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UnregisterFallback<T>(T instance)
|
||||
{
|
||||
if (m_fallbacks.TryGetValue(typeof(T), out var item))
|
||||
{
|
||||
if (ReferenceEquals(item.Instance, instance))
|
||||
{
|
||||
m_fallbacks.Remove(typeof(T));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UnregisterFallback<T>()
|
||||
{
|
||||
m_fallbacks.Remove(typeof(T));
|
||||
}
|
||||
|
||||
public T Resolve<T>(string name)
|
||||
{
|
||||
if (m_named.TryGetValue(typeof(T), out var nameToItem))
|
||||
{
|
||||
if (nameToItem.TryGetValue(name, out var item))
|
||||
{
|
||||
return item.Resolve<T>();
|
||||
}
|
||||
}
|
||||
|
||||
return default(T);
|
||||
}
|
||||
|
||||
public T Resolve<T>()
|
||||
{
|
||||
if (m_registered.TryGetValue(typeof(T), out var item))
|
||||
{
|
||||
return item.Resolve<T>();
|
||||
}
|
||||
|
||||
if (m_fallbacks.TryGetValue(typeof(T), out item))
|
||||
{
|
||||
return item.Resolve<T>();
|
||||
}
|
||||
|
||||
return default(T);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
m_registered.Clear();
|
||||
m_fallbacks.Clear();
|
||||
m_named.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public class IOC
|
||||
{
|
||||
public static bool IsRegistered<T>(string name)
|
||||
{
|
||||
return _defaultContainer.IsRegistered<T>(name);
|
||||
}
|
||||
|
||||
public static void Register<T>(string name, Func<T> func)
|
||||
{
|
||||
_defaultContainer.Register(name, func);
|
||||
}
|
||||
|
||||
public static void Register<T>(string name, T instance)
|
||||
{
|
||||
_defaultContainer.Register(name, instance);
|
||||
}
|
||||
|
||||
public static void Unregister<T>(string name, Func<T> func)
|
||||
{
|
||||
_defaultContainer.Unregister(name, func);
|
||||
}
|
||||
|
||||
public static void Unregister<T>(string name, T instance)
|
||||
{
|
||||
_defaultContainer.Unregister(name, instance);
|
||||
}
|
||||
|
||||
public static bool IsRegistered<T>()
|
||||
{
|
||||
return _defaultContainer.IsRegistered<T>();
|
||||
}
|
||||
|
||||
public static void Register<T>(Func<T> func)
|
||||
{
|
||||
_defaultContainer.Register(func);
|
||||
}
|
||||
|
||||
public static void Register<T>(T instance)
|
||||
{
|
||||
_defaultContainer.Register(instance);
|
||||
}
|
||||
|
||||
public static void Unregister<T>(Func<T> func)
|
||||
{
|
||||
_defaultContainer.Unregister(func);
|
||||
}
|
||||
|
||||
public static void Unregister<T>(T instance)
|
||||
{
|
||||
_defaultContainer.Unregister(instance);
|
||||
}
|
||||
|
||||
public static void Unregister<T>()
|
||||
{
|
||||
_defaultContainer.Unregister<T>();
|
||||
}
|
||||
|
||||
public static bool IsFallbackRegistered<T>()
|
||||
{
|
||||
return _defaultContainer.IsFallbackRegistered<T>();
|
||||
}
|
||||
|
||||
public static void RegisterFallback<T>(Func<T> func)
|
||||
{
|
||||
_defaultContainer.RegisterFallback(func);
|
||||
}
|
||||
|
||||
public static void RegisterFallback<T>(T instance)
|
||||
{
|
||||
_defaultContainer.RegisterFallback(instance);
|
||||
}
|
||||
|
||||
public static void UnregisterFallback<T>(Func<T> func)
|
||||
{
|
||||
_defaultContainer.UnregisterFallback(func);
|
||||
}
|
||||
|
||||
public static void UnregisterFallback<T>(T instance)
|
||||
{
|
||||
_defaultContainer.UnregisterFallback(instance);
|
||||
}
|
||||
|
||||
public static void UnregisterFallback<T>()
|
||||
{
|
||||
_defaultContainer.UnregisterFallback<T>();
|
||||
}
|
||||
|
||||
public static T Resolve<T>(string name)
|
||||
{
|
||||
return _defaultContainer.Resolve<T>(name);
|
||||
}
|
||||
|
||||
public static T Resolve<T>()
|
||||
{
|
||||
return _defaultContainer.Resolve<T>();
|
||||
}
|
||||
|
||||
public static void ClearAll()
|
||||
{
|
||||
_defaultContainer.Clear();
|
||||
}
|
||||
|
||||
private static readonly IOCContainer _defaultContainer = new IOCContainer();
|
||||
|
||||
public static IOCContainer GetContainerFor(MonoBehaviour monoBehaviour = null)
|
||||
{
|
||||
if (monoBehaviour == null)
|
||||
{
|
||||
return _defaultContainer;
|
||||
}
|
||||
|
||||
IOCGroup group = monoBehaviour.GetComponentInParent<IOCGroup>();
|
||||
return group != null ? group.Container : _defaultContainer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf3b404ec20d46068f285c3f75db31c2
|
||||
timeCreated: 1716780264
|
||||
@@ -1,92 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
// 支持多线程
|
||||
public static class RandomGenerator
|
||||
{
|
||||
[ThreadStatic] private static Random random;
|
||||
|
||||
private static Random GetRandom()
|
||||
{
|
||||
return random ??= new Random(Guid.NewGuid().GetHashCode() ^ Environment.TickCount);
|
||||
}
|
||||
|
||||
public static ulong RandUInt64()
|
||||
{
|
||||
int r1 = RandInt32();
|
||||
int r2 = RandInt32();
|
||||
return ((ulong)r1 << 32) | (uint)r2;
|
||||
}
|
||||
|
||||
public static int RandInt32()
|
||||
{
|
||||
return GetRandom().Next();
|
||||
}
|
||||
|
||||
public static uint RandUInt32()
|
||||
{
|
||||
return (uint)GetRandom().Next();
|
||||
}
|
||||
|
||||
public static long RandInt64()
|
||||
{
|
||||
uint r1 = RandUInt32();
|
||||
uint r2 = RandUInt32();
|
||||
return (long)(((ulong)r1 << 32) | r2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取lower与Upper之间的随机数,包含下限,不包含上限
|
||||
/// </summary>
|
||||
/// <param name="lower"></param>
|
||||
/// <param name="upper"></param>
|
||||
/// <returns></returns>
|
||||
public static int RandomNumber(int lower, int upper)
|
||||
{
|
||||
int value = GetRandom().Next(lower, upper);
|
||||
return value;
|
||||
}
|
||||
|
||||
public static bool RandomBool()
|
||||
{
|
||||
return GetRandom().Next(2) == 0;
|
||||
}
|
||||
|
||||
public static T RandomArray<T>(T[] array)
|
||||
{
|
||||
return array[RandomNumber(0, array.Length)];
|
||||
}
|
||||
|
||||
public static T RandomArray<T>(List<T> array)
|
||||
{
|
||||
return array[RandomNumber(0, array.Count)];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 打乱数组
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="arr">要打乱的数组</param>
|
||||
public static void BreakRank<T>(List<T> arr)
|
||||
{
|
||||
if (arr == null || arr.Count < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < arr.Count; i++)
|
||||
{
|
||||
int index = GetRandom().Next(0, arr.Count);
|
||||
(arr[index], arr[i]) = (arr[i], arr[index]);
|
||||
}
|
||||
}
|
||||
|
||||
public static float RandFloat01()
|
||||
{
|
||||
int a = RandomNumber(0, 1000000);
|
||||
return a / 1000000f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4fcef27fa83a45efaa4f85df9acbdf42
|
||||
timeCreated: 1733994673
|
||||
8
Assets/Scripts/NBC/Editor.meta
Normal file
8
Assets/Scripts/NBC/Editor.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6deb0dcf8adbd4f8f92d5482999b05bf
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e54d4b9d5d9fd9c4bae1cd40f3d9698d
|
||||
guid: e8ba5b17cffbb4ffea892f674fc8629f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
16
Assets/Scripts/NBC/Editor/Runtime/CheckUnityVersion.cs
Normal file
16
Assets/Scripts/NBC/Editor/Runtime/CheckUnityVersion.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
internal static class CheckUnityVersion
|
||||
{
|
||||
[InitializeOnLoadMethod]
|
||||
private static void OnInitializeOnLoad()
|
||||
{
|
||||
#if !UNITY_2021_3_OR_NEWER
|
||||
Debug.LogError("Fantasy支持的最低版本为Unity2021.3.14f1c1");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 455f338921e74471841971fd6b79db01
|
||||
timeCreated: 1725943424
|
||||
49
Assets/Scripts/NBC/Editor/Runtime/FantasyStartup.cs
Normal file
49
Assets/Scripts/NBC/Editor/Runtime/FantasyStartup.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
public static class FantasyStartup
|
||||
{
|
||||
private const string ScriptAssemblies = "Library/ScriptAssemblies/";
|
||||
|
||||
static FantasyStartup()
|
||||
{
|
||||
if (!FantasySettingsScriptableObject.Instance.autoCopyAssembly)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var hotUpdatePath = FantasySettingsScriptableObject.Instance.hotUpdatePath;
|
||||
|
||||
if (string.IsNullOrEmpty(hotUpdatePath))
|
||||
{
|
||||
Debug.LogError("请先在菜单Fantasy-Fantasy Settings里设置HotUpdatePath目录位置");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Directory.Exists(hotUpdatePath))
|
||||
{
|
||||
Directory.CreateDirectory(hotUpdatePath);
|
||||
}
|
||||
|
||||
// ReSharper disable once StringLastIndexOfIsCultureSpecific.1
|
||||
if (hotUpdatePath.LastIndexOf("/") != hotUpdatePath.Length - 1)
|
||||
{
|
||||
FantasySettingsScriptableObject.Instance.hotUpdatePath += "/";
|
||||
hotUpdatePath = FantasySettingsScriptableObject.Instance.hotUpdatePath;
|
||||
}
|
||||
|
||||
foreach (var instanceHotUpdateAssemblyDefinition in FantasySettingsScriptableObject.Instance.hotUpdateAssemblyDefinitions)
|
||||
{
|
||||
var dll = instanceHotUpdateAssemblyDefinition.name;
|
||||
File.Copy($"{ScriptAssemblies}{dll}.dll", $"{hotUpdatePath}/{dll}.dll.bytes", true);
|
||||
File.Copy($"{ScriptAssemblies}{dll}.pdb", $"{hotUpdatePath}/{dll}.pdb.bytes", true);
|
||||
}
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/NBC/Editor/Runtime/FantasyStartup.cs.meta
Normal file
3
Assets/Scripts/NBC/Editor/Runtime/FantasyStartup.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42156ba2865a4aa4a3e1e57b3ac9b984
|
||||
timeCreated: 1688276977
|
||||
52
Assets/Scripts/NBC/Editor/Runtime/LinkXmlGenerator.cs
Normal file
52
Assets/Scripts/NBC/Editor/Runtime/LinkXmlGenerator.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public class LinkXmlGenerator
|
||||
{
|
||||
private const string LinkPath = "Assets/link.xml";
|
||||
// 在Unity编辑器中运行该方法来生成link.xml文件
|
||||
[UnityEditor.MenuItem("Fantasy/Generate link.xml")]
|
||||
public static void GenerateLinkXml()
|
||||
{
|
||||
using (var writer = new StreamWriter("Assets/link.xml"))
|
||||
{
|
||||
writer.WriteLine("<linker>");
|
||||
|
||||
foreach (var assembly in FantasySettingsScriptableObject.Instance.includeAssembly)
|
||||
{
|
||||
GenerateLinkXml(writer, assembly, LinkPath);
|
||||
Debug.Log($"{assembly} Link generation completed");
|
||||
}
|
||||
|
||||
if (FantasySettingsScriptableObject.Instance?.linkAssemblyDefinitions != null)
|
||||
{
|
||||
foreach (var linkAssembly in FantasySettingsScriptableObject.Instance.linkAssemblyDefinitions)
|
||||
{
|
||||
GenerateLinkXml(writer, linkAssembly.name, LinkPath);
|
||||
Debug.Log($"{linkAssembly.name} Link generation completed");
|
||||
}
|
||||
}
|
||||
writer.WriteLine("</linker>");
|
||||
}
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
Debug.Log("link.xml generated successfully!");
|
||||
}
|
||||
|
||||
private static void GenerateLinkXml(StreamWriter writer, string assemblyName, string outputPath)
|
||||
{
|
||||
var assembly = System.Reflection.Assembly.Load(assemblyName);
|
||||
var types = assembly.GetTypes();
|
||||
writer.WriteLine($" <assembly fullname=\"{assembly.GetName().Name}\">");
|
||||
foreach (var type in types)
|
||||
{
|
||||
var typeName = type.FullName.Replace('<', '+').Replace('>', '+');
|
||||
writer.WriteLine($" <type fullname=\"{typeName}\" preserve=\"all\"/>");
|
||||
}
|
||||
writer.WriteLine(" </assembly>");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cda4c9403de946df9c31654416193a21
|
||||
timeCreated: 1722743236
|
||||
@@ -1,9 +1,8 @@
|
||||
{
|
||||
"name": "NBC.Asset.Editor",
|
||||
"name": "NBC.Editor",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:3f4a88279c0696a488a2e08f8bccf903",
|
||||
"GUID:b3c9c3fa0cbae6e438ac062aa5d78b76"
|
||||
"GUID:0b7224b83ba514121aa026f3857f820a"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3c9c3fa0cbae6e438ac062aa5d78b76
|
||||
guid: 36410968656dd49358af485aad0b0c4c
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
3
Assets/Scripts/NBC/Editor/Runtime/Settings.meta
Normal file
3
Assets/Scripts/NBC/Editor/Runtime/Settings.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a6997d946f3400e8c423fe1b9245f65
|
||||
timeCreated: 1688277110
|
||||
@@ -0,0 +1,13 @@
|
||||
using UnityEditor;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public class FantasySettings
|
||||
{
|
||||
[MenuItem("Fantasy/Fantasy Settings")]
|
||||
public static void OpenFantasySettings()
|
||||
{
|
||||
SettingsService.OpenProjectSettings("Project/Fantasy Settings");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 977a7c172c30403da60286ba39b7bc72
|
||||
timeCreated: 1686913667
|
||||
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public class FantasySettingsProvider : SettingsProvider
|
||||
{
|
||||
private SerializedObject _serializedObject;
|
||||
private SerializedProperty _autoCopyAssembly;
|
||||
private SerializedProperty _hotUpdatePath;
|
||||
private SerializedProperty _hotUpdateAssemblyDefinitions;
|
||||
private SerializedProperty _linkAssemblyDefinitions;
|
||||
private SerializedProperty _includeAssembly;
|
||||
public FantasySettingsProvider() : base("Project/Fantasy Settings", SettingsScope.Project) { }
|
||||
|
||||
public override void OnActivate(string searchContext, VisualElement rootElement)
|
||||
{
|
||||
Init();
|
||||
base.OnActivate(searchContext, rootElement);
|
||||
}
|
||||
|
||||
public override void OnDeactivate()
|
||||
{
|
||||
base.OnDeactivate();
|
||||
FantasySettingsScriptableObject.Save();
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
_serializedObject?.Dispose();
|
||||
_serializedObject = new SerializedObject(FantasySettingsScriptableObject.Instance);
|
||||
_autoCopyAssembly = _serializedObject.FindProperty("autoCopyAssembly");
|
||||
_hotUpdatePath = _serializedObject.FindProperty("hotUpdatePath");
|
||||
_hotUpdateAssemblyDefinitions = _serializedObject.FindProperty("hotUpdateAssemblyDefinitions");
|
||||
_linkAssemblyDefinitions = _serializedObject.FindProperty("linkAssemblyDefinitions");
|
||||
_includeAssembly = _serializedObject.FindProperty("includeAssembly");
|
||||
}
|
||||
|
||||
public override void OnGUI(string searchContext)
|
||||
{
|
||||
if (_serializedObject == null || !_serializedObject.targetObject)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
using (CreateSettingsWindowGUIScope())
|
||||
{
|
||||
_serializedObject!.Update();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(_autoCopyAssembly);
|
||||
EditorGUILayout.PropertyField(_hotUpdatePath);
|
||||
EditorGUILayout.PropertyField(_hotUpdateAssemblyDefinitions);
|
||||
EditorGUILayout.PropertyField(_includeAssembly);
|
||||
EditorGUILayout.PropertyField(_linkAssemblyDefinitions);
|
||||
// EditorGUILayout.HelpBox("默认包括Fantasy.Unity,所以不需要再次指定。", MessageType.Info);
|
||||
|
||||
if (GUILayout.Button("GenerateLinkXml"))
|
||||
{
|
||||
LinkXmlGenerator.GenerateLinkXml();
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
_serializedObject.ApplyModifiedProperties();
|
||||
FantasySettingsScriptableObject.Save();
|
||||
EditorApplication.RepaintHierarchyWindow();
|
||||
}
|
||||
|
||||
base.OnGUI(searchContext);
|
||||
}
|
||||
}
|
||||
|
||||
private IDisposable CreateSettingsWindowGUIScope()
|
||||
{
|
||||
var unityEditorAssembly = System.Reflection.Assembly.GetAssembly(typeof(EditorWindow));
|
||||
var type = unityEditorAssembly.GetType("UnityEditor.SettingsWindow+GUIScope");
|
||||
return Activator.CreateInstance(type) as IDisposable;
|
||||
}
|
||||
|
||||
static FantasySettingsProvider _provider;
|
||||
|
||||
[SettingsProvider]
|
||||
public static SettingsProvider CreateMyCustomSettingsProvider()
|
||||
{
|
||||
if (FantasySettingsScriptableObject.Instance && _provider == null)
|
||||
{
|
||||
_provider = new FantasySettingsProvider();
|
||||
using (var so = new SerializedObject(FantasySettingsScriptableObject.Instance))
|
||||
{
|
||||
_provider.keywords = GetSearchKeywordsFromSerializedObject(so);
|
||||
}
|
||||
}
|
||||
return _provider;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 047b2f13e73f413fa000bf7be979fb4a
|
||||
timeCreated: 1688380387
|
||||
@@ -0,0 +1,25 @@
|
||||
using UnityEditor;
|
||||
using UnityEditor.Compilation;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
[ScriptableObjectPath("ProjectSettings/FantasySettings.asset")]
|
||||
public class FantasySettingsScriptableObject : ScriptableObjectSingleton<FantasySettingsScriptableObject>, ISerializationCallbackReceiver
|
||||
{
|
||||
[FormerlySerializedAs("AutoCopyAssembly")] [Header("自动拷贝程序集到HotUpdatePath目录中")]
|
||||
public bool autoCopyAssembly = false;
|
||||
[FormerlySerializedAs("HotUpdatePath")] [Header("HotUpdate目录(Unity编译后会把所有HotUpdate程序集Copy一份到这个目录下)")]
|
||||
public string hotUpdatePath;
|
||||
[FormerlySerializedAs("HotUpdateAssemblyDefinitions")] [Header("HotUpdate程序集")]
|
||||
public AssemblyDefinitionAsset[] hotUpdateAssemblyDefinitions;
|
||||
[FormerlySerializedAs("LinkAssemblyDefinitions")] [Header("指定要生成Link.xml的程序集")]
|
||||
public AssemblyDefinitionAsset[] linkAssemblyDefinitions;
|
||||
[FormerlySerializedAs("IncludeAssembly")] [Header("生成Link.xml时候默认包含的程序集")]
|
||||
public string[] includeAssembly = new[] { "Assembly-CSharp", "Fantasy.Unity" };
|
||||
public void OnBeforeSerialize() { }
|
||||
public void OnAfterDeserialize() { }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 27a37e930ca3454fb57bc895f50d2106
|
||||
timeCreated: 1688277120
|
||||
@@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
// ReSharper disable AssignNullToNotNullAttribute
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public class ScriptableObjectSingleton<T> : ScriptableObject where T : ScriptableObject
|
||||
{
|
||||
private static T _instance;
|
||||
|
||||
public static T Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = Load();
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
private static T Load()
|
||||
{
|
||||
var scriptableObjectPath = GetScriptableObjectPath();
|
||||
|
||||
if (string.IsNullOrEmpty(scriptableObjectPath))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var loadSerializedFileAndForget = InternalEditorUtility.LoadSerializedFileAndForget(scriptableObjectPath);
|
||||
|
||||
if (loadSerializedFileAndForget.Length <= 0)
|
||||
{
|
||||
return CreateInstance<T>();
|
||||
}
|
||||
|
||||
return loadSerializedFileAndForget[0] as T;
|
||||
}
|
||||
|
||||
public static void Save(bool saveAsText = true)
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
Debug.LogError("Cannot save ScriptableObjectSingleton: no instance!");
|
||||
return;
|
||||
}
|
||||
|
||||
var scriptableObjectPath = GetScriptableObjectPath();
|
||||
|
||||
if (string.IsNullOrEmpty(scriptableObjectPath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var directoryName = Path.GetDirectoryName(scriptableObjectPath);
|
||||
|
||||
if (!Directory.Exists(directoryName))
|
||||
{
|
||||
Directory.CreateDirectory(directoryName);
|
||||
}
|
||||
|
||||
UnityEngine.Object[] obj = { _instance };
|
||||
InternalEditorUtility.SaveToSerializedFileAndForget(obj, scriptableObjectPath, saveAsText);
|
||||
}
|
||||
|
||||
private static string GetScriptableObjectPath()
|
||||
{
|
||||
var scriptableObjectPathAttribute = typeof(T).GetCustomAttribute(typeof(ScriptableObjectPathAttribute)) as ScriptableObjectPathAttribute;
|
||||
return scriptableObjectPathAttribute?.ScriptableObjectPath;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
|
||||
public class ScriptableObjectPathAttribute : Attribute
|
||||
{
|
||||
internal readonly string ScriptableObjectPath;
|
||||
|
||||
public ScriptableObjectPathAttribute(string scriptableObjectPath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(scriptableObjectPath))
|
||||
{
|
||||
throw new ArgumentException("Invalid relative path (it is empty)");
|
||||
}
|
||||
|
||||
if (scriptableObjectPath[0] == '/')
|
||||
{
|
||||
scriptableObjectPath = scriptableObjectPath.Substring(1);
|
||||
}
|
||||
|
||||
ScriptableObjectPath = scriptableObjectPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c77f5208dc14542ae7497d59321ef76
|
||||
timeCreated: 1688278016
|
||||
8
Assets/Scripts/NBC/Editor/Runtime/WSocket.meta
Normal file
8
Assets/Scripts/NBC/Editor/Runtime/WSocket.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b9e5c7d1436ec414fa3f69a23aaafc3b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
229
Assets/Scripts/NBC/Editor/Runtime/WSocket/SettingsWindow.cs
Normal file
229
Assets/Scripts/NBC/Editor/Runtime/WSocket/SettingsWindow.cs
Normal file
@@ -0,0 +1,229 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEngine.Networking;
|
||||
using System.IO;
|
||||
using System;
|
||||
|
||||
namespace UnityWebSocket.Editor
|
||||
{
|
||||
internal class SettingsWindow : EditorWindow
|
||||
{
|
||||
static SettingsWindow window = null;
|
||||
[MenuItem("Tools/UnityWebSocket", priority = 100)]
|
||||
internal static void Open()
|
||||
{
|
||||
if (window != null)
|
||||
{
|
||||
window.Close();
|
||||
}
|
||||
|
||||
window = GetWindow<SettingsWindow>(true, "UnityWebSocket");
|
||||
window.minSize = window.maxSize = new Vector2(600, 310);
|
||||
window.Show();
|
||||
window.BeginCheck();
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
DrawLogo();
|
||||
DrawVersion();
|
||||
DrawSeparator(80);
|
||||
DrawSeparator(186);
|
||||
DrawHelper();
|
||||
DrawFooter();
|
||||
}
|
||||
|
||||
Texture2D logoTex = null;
|
||||
private void DrawLogo()
|
||||
{
|
||||
if (logoTex == null)
|
||||
{
|
||||
logoTex = new Texture2D(66, 66);
|
||||
logoTex.LoadImage(Convert.FromBase64String(LOGO_BASE64.VALUE));
|
||||
for (int i = 0; i < 66; i++) for (int j = 0; j < 15; j++) logoTex.SetPixel(i, j, Color.clear);
|
||||
logoTex.Apply();
|
||||
}
|
||||
|
||||
var logoPos = new Rect(10, 10, 66, 66);
|
||||
GUI.DrawTexture(logoPos, logoTex);
|
||||
var title = "<color=#3A9AD8><b>UnityWebSocket</b></color>";
|
||||
var titlePos = new Rect(80, 20, 500, 50);
|
||||
GUI.Label(titlePos, title, TextStyle(24));
|
||||
}
|
||||
|
||||
private void DrawSeparator(int y)
|
||||
{
|
||||
EditorGUI.DrawRect(new Rect(10, y, 580, 1), Color.white * 0.5f);
|
||||
}
|
||||
|
||||
private GUIStyle TextStyle(int fontSize = 10, TextAnchor alignment = TextAnchor.UpperLeft, float alpha = 0.85f)
|
||||
{
|
||||
var style = new GUIStyle();
|
||||
style.fontSize = fontSize;
|
||||
style.normal.textColor = (EditorGUIUtility.isProSkin ? Color.white : Color.black) * alpha;
|
||||
style.alignment = alignment;
|
||||
style.richText = true;
|
||||
return style;
|
||||
}
|
||||
|
||||
private void DrawVersion()
|
||||
{
|
||||
GUI.Label(new Rect(440, 10, 150, 10), "Current Version: " + Settings.VERSION, TextStyle(alignment: TextAnchor.MiddleLeft));
|
||||
if (string.IsNullOrEmpty(latestVersion))
|
||||
{
|
||||
GUI.Label(new Rect(440, 30, 150, 10), "Checking for Updates...", TextStyle(alignment: TextAnchor.MiddleLeft));
|
||||
}
|
||||
else if (latestVersion == "unknown")
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.Label(new Rect(440, 30, 150, 10), "Latest Version: " + latestVersion, TextStyle(alignment: TextAnchor.MiddleLeft));
|
||||
if (Settings.VERSION == latestVersion)
|
||||
{
|
||||
if (GUI.Button(new Rect(440, 50, 150, 18), "Check Update"))
|
||||
{
|
||||
latestVersion = "";
|
||||
changeLog = "";
|
||||
BeginCheck();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GUI.Button(new Rect(440, 50, 150, 18), "Update to | " + latestVersion))
|
||||
{
|
||||
ShowUpdateDialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowUpdateDialog()
|
||||
{
|
||||
var isOK = EditorUtility.DisplayDialog("UnityWebSocket",
|
||||
"Update UnityWebSocket now?\n" + changeLog,
|
||||
"Update Now", "Cancel");
|
||||
|
||||
if (isOK)
|
||||
{
|
||||
UpdateVersion();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateVersion()
|
||||
{
|
||||
Application.OpenURL(Settings.GITHUB + "/releases");
|
||||
}
|
||||
|
||||
private void DrawHelper()
|
||||
{
|
||||
GUI.Label(new Rect(330, 200, 100, 18), "GitHub:", TextStyle(10, TextAnchor.MiddleRight));
|
||||
if (GUI.Button(new Rect(440, 200, 150, 18), "UnityWebSocket"))
|
||||
{
|
||||
Application.OpenURL(Settings.GITHUB);
|
||||
}
|
||||
|
||||
GUI.Label(new Rect(330, 225, 100, 18), "Report:", TextStyle(10, TextAnchor.MiddleRight));
|
||||
if (GUI.Button(new Rect(440, 225, 150, 18), "Report an Issue"))
|
||||
{
|
||||
Application.OpenURL(Settings.GITHUB + "/issues/new");
|
||||
}
|
||||
|
||||
GUI.Label(new Rect(330, 250, 100, 18), "Email:", TextStyle(10, TextAnchor.MiddleRight));
|
||||
if (GUI.Button(new Rect(440, 250, 150, 18), Settings.EMAIL))
|
||||
{
|
||||
var uri = new Uri(string.Format("mailto:{0}?subject={1}", Settings.EMAIL, "UnityWebSocket Feedback"));
|
||||
Application.OpenURL(uri.AbsoluteUri);
|
||||
}
|
||||
|
||||
GUI.Label(new Rect(330, 275, 100, 18), "QQ群:", TextStyle(10, TextAnchor.MiddleRight));
|
||||
if (GUI.Button(new Rect(440, 275, 150, 18), Settings.QQ_GROUP))
|
||||
{
|
||||
Application.OpenURL(Settings.QQ_GROUP_LINK);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawFooter()
|
||||
{
|
||||
EditorGUI.DropShadowLabel(new Rect(10, 230, 400, 20), "Developed by " + Settings.AUHTOR);
|
||||
EditorGUI.DropShadowLabel(new Rect(10, 250, 400, 20), "All rights reserved");
|
||||
}
|
||||
|
||||
UnityWebRequest req;
|
||||
string changeLog = "";
|
||||
string latestVersion = "";
|
||||
void BeginCheck()
|
||||
{
|
||||
EditorApplication.update -= VersionCheckUpdate;
|
||||
EditorApplication.update += VersionCheckUpdate;
|
||||
|
||||
req = UnityWebRequest.Get(Settings.GITHUB + "/releases/latest");
|
||||
req.SendWebRequest();
|
||||
}
|
||||
|
||||
private void VersionCheckUpdate()
|
||||
{
|
||||
#if UNITY_2020_3_OR_NEWER
|
||||
if (req == null
|
||||
|| req.result == UnityWebRequest.Result.ConnectionError
|
||||
|| req.result == UnityWebRequest.Result.DataProcessingError
|
||||
|| req.result == UnityWebRequest.Result.ProtocolError)
|
||||
#elif UNITY_2018_1_OR_NEWER
|
||||
if (req == null || req.isNetworkError || req.isHttpError)
|
||||
#else
|
||||
if (req == null || req.isError)
|
||||
#endif
|
||||
{
|
||||
EditorApplication.update -= VersionCheckUpdate;
|
||||
latestVersion = "unknown";
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.isDone)
|
||||
{
|
||||
EditorApplication.update -= VersionCheckUpdate;
|
||||
latestVersion = req.url.Substring(req.url.LastIndexOf("/") + 1).TrimStart('v');
|
||||
|
||||
if (Settings.VERSION != latestVersion)
|
||||
{
|
||||
var text = req.downloadHandler.text;
|
||||
var st = text.IndexOf("content=\"" + latestVersion);
|
||||
st = st > 0 ? text.IndexOf("\n", st) : -1;
|
||||
var end = st > 0 ? text.IndexOf("\" />", st) : -1;
|
||||
if (st > 0 && end > st)
|
||||
{
|
||||
changeLog = text.Substring(st + 1, end - st - 1).Trim();
|
||||
changeLog = changeLog.Replace("\r", "");
|
||||
changeLog = changeLog.Replace("\n", "\n- ");
|
||||
changeLog = "\nCHANGE LOG: \n- " + changeLog + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static class LOGO_BASE64
|
||||
{
|
||||
internal const string VALUE = "iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAMAAADUivDaAAAAq1BMVEUAAABKmtcvjtYzl" +
|
||||
"9szmNszl9syl9k0mNs0mNwzmNs0mNszl9szl9s0mNs0mNwzmNw0mNwyltk0mNw0mNwzl9s0mNsymNs0mNszmNwzmNwzm" +
|
||||
"NszmNs0mNwzl9w0mNwzmNw0mNs0mNs0mNwzl9wzmNs0mNwzmNs0mNwzl90zmNszmNszl9szmNsxmNszmNszmNw0mNwzm" +
|
||||
"Nw0mNs2neM4pe41mt43ouo2oOY5qfM+UHlaAAAAMnRSTlMAAwXN3sgI+/069MSCK6M/MA74h9qfFHB8STWMJ9OSdmNcI" +
|
||||
"8qya1IeF+/U0EIa57mqmFTYJe4AAAN3SURBVFjD7ZbpkppAFEa/bgVBREF2kEVGFNeZsM77P1kadURnJkr8k1Qlx1Khu" +
|
||||
"/pw7+2lwH/+YcgfMBBLG7VocwDamzH+wJBB8Qhjve2f0TdrGwjei6o4Ub/nM/APw5Z7vvSB/qrCrqbD6fBEVtigeMxks" +
|
||||
"fX9zWbj+z1jhqgSBplQ50eGo4614WXlRAzgrRhmtSfvxAn7pB0N5ObaKKZZuU5/d37IBcBgUQwqDuf7Z2gUmVAl4NGNr" +
|
||||
"/UeHxV5n39ulbaKLI86h6HilmM5M1aN126lpNhtl59yeTsp8nUMvpNC1J3bh5FtfVRk+bJrJunn5d4U4piJ/Vw9eXgsj" +
|
||||
"4ZpZaCjg9waZkIpnBWLJ44OwoNu60F2UnSaEkKv4XnAlCpm6B4F/aKMDiyGi2L8SEEAVdxNLuzmgV7nFwObEe2xQVuX+" +
|
||||
"RV1lWetga3w+cN1sXgvm4cJH8OEgZC1DPKhfF/BIymmQrMjq/x65FUeEkDup8GxoexZmznHCvANtXU/CAq13yimhQGtm" +
|
||||
"H4VCPnBBL1fTKo3CqEcvq7Lb/OwHxWTYlyw+JmjKoVvDLVOQB4pVsM8K8smgvLCxZDlIijwyOEc+nr/msMwK0+GQWGBd" +
|
||||
"tmhjv8icTds1s2ammaFh04QLLe69NK7guP6mTDMaw3o6nAX/Z7EXUskPSvWEWg4srVlp5NTDXv9Lce9HGN5eeG4nj5Yz" +
|
||||
"ACteU2wQLo4MBtJfd1nw5nG1/s9zwUQ6pykL1TQjqdeuvQW0naz2XKLYL4Cwzr4vj+OQdD96CSp7Lrynp4aeFF0xdm5q" +
|
||||
"6OFtFfPv7URxpWJNjd/N+3+I9+1klMav12Qtgbt9R2JaIopjkzaPtOFq4KxUpqfUMSFnQrySWjLoQzRZS4HMH84ME1ej" +
|
||||
"S1YJpQZ3B+sR1uCQJSBdGdCk1eAEgORR88KK05W8dh2MA+A/SKCYu3mCJ0Ek7HBx4HHeuwYy5G3x8hSMTJcOMFbinCsn" +
|
||||
"hO1V1aszGULvA0g4UFsb4VA0hAFcyo6cgLsAoT7uUtGAH5wQKQle0wuLyxLTaNyJEYwxw4wSljLK1TP8CAaOyhBMMEsj" +
|
||||
"OBoXgo7VGElFkSWL+vef1RF2YNXeRWYzQBTpkhC8KaZHhuIogArkQLKClBZjU26B2IZgGz+cpZkHl8g3fYUaW/YP2kb2" +
|
||||
"M/V97JY/vZN859n+QmO7XtC9Bf2jAAAAABJRU5ErkJggg==";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 902614e06186a482f9e816e1d1984547
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8ef2143da4eb4506bd2956385af09162
|
||||
timeCreated: 1732110071
|
||||
12
Assets/Scripts/NBC/LICENSE
Normal file
12
Assets/Scripts/NBC/LICENSE
Normal file
@@ -0,0 +1,12 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 qq362946
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
However, the following entity is explicitly prohibited from using, copying, modifying, or distributing the Software or any of its portions:
|
||||
|
||||
泰课在线(https://www.taikr.com/)
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -1,6 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f4a88279c0696a488a2e08f8bccf903
|
||||
AssemblyDefinitionImporter:
|
||||
guid: e68ec9986245d4ecfa0445bda8a7868d
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80eed01ec1744d9782dd4c3735da6957
|
||||
timeCreated: 1715247848
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 35f7b912a3794f2290a6d67d5b129707
|
||||
timeCreated: 1715247864
|
||||
@@ -1,13 +1,12 @@
|
||||
{
|
||||
"name": "NBC.Lan",
|
||||
"name": "NBC",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:8c8f9d96103e94a7da84b012fd7e9f13",
|
||||
"GUID:6055be8ebefd69e48b49212b09b47b2f"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"allowUnsafeCode": true,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6263c1234f5252446a12e61977ccbaa7
|
||||
guid: 0b7224b83ba514121aa026f3857f820a
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
45
Assets/Scripts/NBC/README.md
Normal file
45
Assets/Scripts/NBC/README.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Fantasy
|
||||
#### Fantasy是基于.NET的高性能网络开发框架,支持主流协议,前后端分离。
|
||||
#### 支持Unity/Godot/WinFrom/WPF/Console等C#客户端接入。
|
||||
#### 框架支持TCP\KCP\WebSocket\http(支持Unity发布成H5)三种网络协议。
|
||||
#### 适合需要快速上手、可扩展、分布式全平台商业级解决方案的框架。
|
||||
## 导航
|
||||
* [Fantasy介绍网站](https://www.code-fantasy.com/)
|
||||
* [Fantasy的API文档](https://www.code-fantasy.com/doc/api/Fantasy.html)
|
||||
* [入门视频观看地址](https://space.bilibili.com/382126312)
|
||||
## 快速上手
|
||||
* 01.快速入门
|
||||
* [1.1.获得Fantasy](https://www.code-fantasy.com/top/download-fantasy/)
|
||||
* [1.2.配置文件](https://www.code-fantasy.com/top/config-file/)
|
||||
* [1.3.Fantasy的网络](https://www.code-fantasy.com/top/use-network/)
|
||||
* [1.4.Fantasy的配置文件](https://www.code-fantasy.com/top/config-file/)
|
||||
* [1.5.Fantasy的命令行参数](https://www.code-fantasy.com/top/command-line-parameter/)
|
||||
* [1.6.如何升级到最新版](https://www.code-fantasy.com/top/upgrade/)
|
||||
* 02.网络通信
|
||||
* [2.1.配置网络协议](https://www.code-fantasy.com/network/network-protocols/)
|
||||
* [2.2.客户端服务器之间发送消息](https://www.code-fantasy.com/network/session/)
|
||||
* [2.3.服务器之间发送消息](https://www.code-fantasy.com/network/networkmessagingomponent/)
|
||||
* [2.4.Route通信协议](https://www.code-fantasy.com/network/network-route/)
|
||||
* [2.5.Addressable通信协议](https://www.code-fantasy.com/network/network-addressable/)
|
||||
* 03.系统组件
|
||||
* [3.1.ECS系统](https://www.code-fantasy.com/core/ecs/)
|
||||
* [3.2.事件系统](https://www.code-fantasy.com/core/event/)
|
||||
* [3.3.任务系统](https://www.code-fantasy.com/core/task/)
|
||||
* [3.4.异步协程锁](https://www.code-fantasy.com/core/lock/)
|
||||
* [3.5.数据库](https://www.code-fantasy.com/core/db/)
|
||||
* [更新日志](https://www.code-fantasy.com/changelog/)
|
||||
* [API文档](https://www.code-fantasy.com/doc/api/Fantasy.html)
|
||||
* [常见问题](https://www.code-fantasy.com/question/)
|
||||
|
||||
## 优质开源项目推荐
|
||||
#### <a href="https://github.com/egametang/ET"><strong>ET</strong></a> - ET框架是一整套完善的游戏开发框架。
|
||||
#### <a href="https://github.com/ALEXTANGXIAO/TEngine"><strong>TEngine</strong></a> - TEngine是一个简单(新手友好开箱即用)且强大的Unity框架全平台解决方案。
|
||||
#### <a href="https://github.com/FlameskyDexive/Legends-Of-Heroes"><strong>Legends-Of-Heroes</strong></a> - 一个LOL风格的球球大作战游戏,基于ET,使用状态同步。
|
||||
## 交流与讨论:
|
||||
__讨论QQ群 : Fantasy服务器开发交流群 569888673 __
|
||||
## 特别鸣谢
|
||||
|
||||
感谢JetBrains公司提供的使用许可证!
|
||||
|
||||
<p><a href="https://www.jetbrains.com/?from=fantasy">
|
||||
<img src="https://user-images.githubusercontent.com/8274346/223466125-611c027a-61f3-4ea0-a96d-4052283da746.png" alt="JetBrains的Logo" width="20%" height="20%"></a></p>
|
||||
@@ -1,6 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8beb767f9f7a66f4e87dd9db57cdd64e
|
||||
AssemblyDefinitionImporter:
|
||||
guid: cf5443fd5b0e44724945a38cbd0fde13
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
8
Assets/Scripts/NBC/Runtime.meta
Normal file
8
Assets/Scripts/NBC/Runtime.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d4180ba95bb674e6488cd44665e784d6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 841fa3f7e4afc064c82bb2e5d8ae49c4
|
||||
guid: 7148f149eca74238a06cee662839e8bf
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user