add kcp
This commit is contained in:
parent
ebf9c1f526
commit
2c4710bc5d
|
@ -15,39 +15,17 @@
|
|||
<Compile Remove="Packages\Tests\**" />
|
||||
<Compile Remove="Packages\Runtime~\Unity\**" />
|
||||
<Compile Remove="Packages\Runtime~\UnityPluginsSupport\**" />
|
||||
<Compile Remove="Src\Unity\**" />
|
||||
<Compile Remove="Src\UnityPluginsSupport\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Remove="Packages\Common~\**" />
|
||||
<EmbeddedResource Remove="Packages\Editor\**" />
|
||||
<EmbeddedResource Remove="Packages\Runtime\**" />
|
||||
<EmbeddedResource Remove="Packages\Core\Cache\**" />
|
||||
<EmbeddedResource Remove="Packages\Tests\**" />
|
||||
<EmbeddedResource Remove="Packages\Runtime~\Unity\**" />
|
||||
<EmbeddedResource Remove="Packages\Runtime~\UnityPluginsSupport\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Packages\Common~\**" />
|
||||
<None Remove="Packages\Editor\**" />
|
||||
<None Remove="Packages\Runtime\**" />
|
||||
<None Remove="Packages\Core\Assets\**" />
|
||||
<None Remove="Packages\Core\Cache\**" />
|
||||
<None Remove="Packages\Tests\**" />
|
||||
<None Remove="Packages\Runtime~\Unity\**" />
|
||||
<None Remove="Packages\Runtime~\UnityPluginsSupport\**" />
|
||||
<None Remove="Packages\Runtime~\BITKit.asmdef" />
|
||||
<None Remove="Packages\Runtime~\BITKit.asmdef.meta" />
|
||||
<None Remove="Packages\Runtime~\Core.meta" />
|
||||
<None Remove="Packages\Runtime~\NetSupport.meta" />
|
||||
<None Remove="Packages\Runtime~\Unity.meta" />
|
||||
<None Remove="Packages\Runtime~\UnityPluginsSupport.meta" />
|
||||
<None Remove="Packages\Editor.meta" />
|
||||
<None Remove="Packages\kcp2k.meta" />
|
||||
<None Remove="Packages\package.json" />
|
||||
<None Remove="Packages\package.json.meta" />
|
||||
<None Remove="Packages\Plugins.meta" />
|
||||
<None Remove="Packages\Tests.meta" />
|
||||
<!-- 排除Unity文件 -->
|
||||
<None Remove="**\*.meta"/>
|
||||
<None Remove="**\*.asmdef"/>
|
||||
<None Remove="Src\Unity\**" />
|
||||
<None Remove="Src\UnityPluginsSupport\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -57,16 +35,33 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Kcp" Version="2.6.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.9" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0-preview.4.23259.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
|
||||
<PackageReference Include="MySql.EntityFrameworkCore" Version="6.0.13" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.3-beta1" />
|
||||
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
|
||||
<PackageReference Include="UniTask" Version="2.3.3" />
|
||||
|
||||
|
||||
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Remove="Src\Unity\**" />
|
||||
<EmbeddedResource Remove="Src\UnityPluginsSupport\**" />
|
||||
|
||||
|
||||
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"allowUnsafeCode": true,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
|
|
|
@ -7,6 +7,7 @@ using Cysharp.Threading.Tasks;
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
// ReSharper disable StringLiteralTypo
|
||||
#if NET5_0_OR_GREATER
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
#endif
|
||||
|
@ -19,6 +20,10 @@ namespace BITKit
|
|||
}
|
||||
public class BITApp
|
||||
{
|
||||
public static async UniTask SwitchToMainThread()
|
||||
{
|
||||
await UniTask.SwitchToSynchronizationContext(SynchronizationContext);
|
||||
}
|
||||
public static class Time
|
||||
{
|
||||
public static float DeltaTime { get; internal set; }
|
||||
|
@ -59,7 +64,89 @@ namespace BITKit
|
|||
"TextCopy",
|
||||
"Blazored",
|
||||
"TextCopy",
|
||||
"mattatz"
|
||||
"mattatz",
|
||||
"TrailsFX",
|
||||
"Knife",
|
||||
"Needle",
|
||||
"NiceIO",
|
||||
"AndroidPlayerBuildProgram",
|
||||
"DocCodeExamples",
|
||||
"System",
|
||||
"UnityEngine",
|
||||
"Unity",
|
||||
"Microsoft",
|
||||
"UnityEditor",
|
||||
"Google",
|
||||
"Mono",
|
||||
"ZXing",
|
||||
"ImmersiveVRTools",
|
||||
"MonKey",
|
||||
"FLib",
|
||||
"Kcp",
|
||||
"Udx",
|
||||
"Sirenix",
|
||||
"TMPro",
|
||||
"RotaryHeart",
|
||||
"Cinemachine",
|
||||
"ParadoxNotion",
|
||||
"Net",
|
||||
"VSCodeEditor",
|
||||
"AOT",
|
||||
"UnityEditorInternal",
|
||||
"UnityEngineInternal",
|
||||
"JetBrains",
|
||||
"Bee",
|
||||
"NotInvited",
|
||||
"HighlightPlus",
|
||||
"DG",
|
||||
"Hierarchy2",
|
||||
"Cysharp",
|
||||
"JetBrains",
|
||||
"Packages",
|
||||
"Newtonsoft_X",
|
||||
"Binding",
|
||||
"NodeCanvas",
|
||||
"SaveDuringPlay",
|
||||
"LimWorks",
|
||||
"MagicaCloth2",
|
||||
"FastScriptReload",
|
||||
"ParrelSync",
|
||||
"KinematicCharacterController",
|
||||
"LimWorksEditor",
|
||||
"BuildComponent",
|
||||
"dnlib",
|
||||
"BigIntegerLibrary",
|
||||
"Ionic",
|
||||
"log4net",
|
||||
"ImmersiveVrToolsCommon",
|
||||
"NUnit",
|
||||
"HarmonyLib",
|
||||
"MonoMod",
|
||||
"WebDav",
|
||||
"PlasticGui",
|
||||
"Codice",
|
||||
"GluonGui",
|
||||
"PlasticPipe",
|
||||
"XDiffGui",
|
||||
"MacFsWatcher",
|
||||
"MacUI",
|
||||
"PlayerBuildProgramLibrary",
|
||||
"ExCSS",
|
||||
"ScriptCompilationBuildProgram",
|
||||
"BeeBuildProgramCommon",
|
||||
"Accessibility",
|
||||
"CodiceApp",
|
||||
"Newtonsoft",
|
||||
"MergetoolGui",
|
||||
"TreeEditor",
|
||||
"MackySoft",
|
||||
"FullscreenEditor",
|
||||
"mattatz",
|
||||
"AYellowpaper",
|
||||
"kcp2k",
|
||||
"MeshCombineStudio",
|
||||
"AmazingAssets",
|
||||
"Utilities"
|
||||
};
|
||||
}
|
||||
#if NET5_0_OR_GREATER
|
||||
|
@ -144,7 +231,8 @@ namespace BITKit
|
|||
public static InitializationState State;
|
||||
public static Assembly[] Assemblies;
|
||||
public static AppSettings Settings { get; protected set; }
|
||||
public static async void Start(string appName = nameof(BITApp),AppSettings settings=default)
|
||||
private static DateTime InitialTime { get; set; }=DateTime.Now;
|
||||
public static async UniTask Start(string appName = nameof(BITApp),AppSettings settings=default)
|
||||
{
|
||||
Time.TimeAsDouble = 0;
|
||||
Time.DeltaTime = 1 / 60f;
|
||||
|
@ -153,7 +241,7 @@ namespace BITKit
|
|||
CancellationTokenSource = new CancellationTokenSource();
|
||||
AppName = appName;
|
||||
ThreadHelper.LogCurrentThread();
|
||||
|
||||
InitialTime = DateTime.Now;
|
||||
await Init();
|
||||
}
|
||||
private static async Task Init()
|
||||
|
@ -182,10 +270,16 @@ namespace BITKit
|
|||
reflectionHelperWatch.Start();
|
||||
await ReflectionHelper.Init();
|
||||
reflectionHelperWatch.Stop();
|
||||
|
||||
Stopwatch commandWatch = new();
|
||||
await BITCommands.InitializeAsync();
|
||||
commandWatch.Stop();
|
||||
|
||||
|
||||
stopwatch.Stop();
|
||||
State = InitializationState.Initialized;
|
||||
BIT4Log.Log<BITApp>($"已完成初始化,耗时:{stopwatch.ElapsedMilliseconds}ms");
|
||||
BIT4Log.Log<BITApp>($"反射初始化耗时:{reflectionHelperWatch.ElapsedMilliseconds}ms");
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
|
@ -196,11 +290,18 @@ namespace BITKit
|
|||
}
|
||||
public static void Stop()
|
||||
{
|
||||
var runTime = DateTime.Now - InitialTime;
|
||||
|
||||
BIT4Log.Log<BITApp>($"正在停止{nameof(BITApp)}");
|
||||
CancellationTokenSource.Cancel();
|
||||
State = InitializationState.None;
|
||||
|
||||
BITCommands.Dispose();
|
||||
|
||||
BIT4Log.Log<BITApp>($"已停止{nameof(BITApp)}");
|
||||
BIT4Log.Log<BITApp>($"运行时间:{runTime}");
|
||||
BIT4Log.Log<BITApp>("Exit Code:0");
|
||||
|
||||
}
|
||||
public static void Run(string path, string WorkingDirectory = "")
|
||||
{
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#if NETCOREAPP
|
||||
using System;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
namespace BITKit;
|
||||
|
||||
public class BITAppForNet
|
||||
|
@ -18,7 +18,7 @@ public class BITAppForNet
|
|||
BIT4Log.OnSetConsoleColor += color => Console.ForegroundColor = color;
|
||||
BIT4Log.OnNextLine += Console.WriteLine;
|
||||
|
||||
BITApp.Start(name);
|
||||
await BITApp.Start(name);
|
||||
await BITBinary.Start();
|
||||
}
|
||||
public static UniTask DisposeAsync()
|
||||
|
|
|
@ -9,4 +9,14 @@ namespace BITKit
|
|||
{
|
||||
|
||||
}
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true, Inherited = true)]
|
||||
public class CustomTypeAttribute : System.Attribute
|
||||
{
|
||||
public readonly Type Type;
|
||||
public CustomTypeAttribute(Type type)
|
||||
{
|
||||
|
||||
Type = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 647f1c92db6d9b5438a81bdb9bfc11bd
|
||||
guid: ef5795e833a88cd4b8c1485d4b50ebfd
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b869357f0380e864eb445105d35c68b7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,87 @@
|
|||
using System;
|
||||
using Cysharp.Threading.Tasks;
|
||||
|
||||
namespace BITKit.Auth
|
||||
{
|
||||
/// <summary>
|
||||
/// 授权服务
|
||||
/// </summary>
|
||||
public interface IAuthService
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否已授权
|
||||
/// </summary>
|
||||
bool IsAuthorized { get; }
|
||||
/// <summary>
|
||||
/// 是否正在授权
|
||||
/// </summary>
|
||||
bool IsAuthorizing { get; }
|
||||
/// <summary>
|
||||
/// 异步开始授权
|
||||
/// </summary>
|
||||
/// <param name="token">令牌</param>
|
||||
UniTask AuthorizeAsync(string token);
|
||||
/// <summary>
|
||||
/// 异步取消授权
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
UniTask CancelAuthorizationAsync();
|
||||
/// <summary>
|
||||
/// 开始授权的回调
|
||||
/// </summary>
|
||||
event Action<string> OnAuthorize;
|
||||
/// <summary>
|
||||
/// 已授权的回调
|
||||
/// </summary>
|
||||
event Action<string> OnAuthorized;
|
||||
/// <summary>
|
||||
/// 取消授权的回调
|
||||
/// </summary>
|
||||
event Action<string> UnAuthorize;
|
||||
/// <summary>
|
||||
/// 授权失败的回调
|
||||
/// </summary>
|
||||
event Action<string> OnAuthorizeFailure;
|
||||
}
|
||||
public abstract class AuthServiceImplement:IAuthService
|
||||
{
|
||||
protected abstract IAuthService service { get; }
|
||||
bool IAuthService.IsAuthorized => service.IsAuthorized;
|
||||
|
||||
bool IAuthService.IsAuthorizing => service.IsAuthorizing;
|
||||
|
||||
UniTask IAuthService.AuthorizeAsync(string token)
|
||||
{
|
||||
return service.AuthorizeAsync(token);
|
||||
}
|
||||
|
||||
UniTask IAuthService.CancelAuthorizationAsync()
|
||||
{
|
||||
return service.CancelAuthorizationAsync();
|
||||
}
|
||||
|
||||
event Action<string> IAuthService.OnAuthorize
|
||||
{
|
||||
add => service.OnAuthorize += value;
|
||||
remove => service.OnAuthorize -= value;
|
||||
}
|
||||
|
||||
event Action<string> IAuthService.OnAuthorized
|
||||
{
|
||||
add => service.OnAuthorized += value;
|
||||
remove => service.OnAuthorized -= value;
|
||||
}
|
||||
|
||||
event Action<string> IAuthService.UnAuthorize
|
||||
{
|
||||
add => service.UnAuthorize += value;
|
||||
remove => service.UnAuthorize -= value;
|
||||
}
|
||||
|
||||
event Action<string> IAuthService.OnAuthorizeFailure
|
||||
{
|
||||
add => service.OnAuthorizeFailure += value;
|
||||
remove => service.OnAuthorizeFailure -= value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: dd4b17361e28d304bbc1dd6d568e9a3c
|
||||
guid: df16dad99b7205a40b655489e7f19076
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
|
@ -1,4 +1,5 @@
|
|||
#if UNITY
|
||||
#if NET5_0_OR_GREATER
|
||||
#else
|
||||
using UnityEngine;
|
||||
#endif
|
||||
using System;
|
||||
|
@ -6,7 +7,9 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using Cysharp.Threading.Tasks;
|
||||
#if NET5_0_OR_GREATER
|
||||
using Microsoft.SqlServer.Server;
|
||||
#endif
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BITKit
|
||||
|
@ -14,27 +17,37 @@ namespace BITKit
|
|||
public class BITBinary
|
||||
{
|
||||
private static readonly Dictionary<string, INetMessageReader> netReaders = new();
|
||||
private static readonly List<Type> serializableTypes = new();
|
||||
#if NET5_0_OR_GREATER
|
||||
public static readonly List<Type> serializableTypes = new();
|
||||
#endif
|
||||
|
||||
public static async UniTask Start()
|
||||
{
|
||||
netReaders.Clear();
|
||||
#if NET5_0_OR_GREATER
|
||||
serializableTypes.Clear();
|
||||
#endif
|
||||
foreach (var x in await ReflectionHelper.GetInstances<INetMessageReader>())
|
||||
{
|
||||
var typeName = x.GetMessageType().FullName;
|
||||
if (typeName == null) continue;
|
||||
netReaders.Add(typeName, x);
|
||||
BIT4Log.Log<BITBinary>($"已注册类型:{typeName}");
|
||||
}
|
||||
#if NET5_0_OR_GREATER
|
||||
var serializes = await ReflectionHelper.GetInstances<IBinarySerialize>();
|
||||
#if UNITY
|
||||
serializes = serializes.Where(x => x is not UnityEngine.Object);
|
||||
#else
|
||||
|
||||
#endif
|
||||
foreach (var x in serializes)
|
||||
{
|
||||
serializableTypes.Add(x.GetType());
|
||||
BIT4Log.Log<BITBinary>($"已注册类型:{x.GetType().FullName}");
|
||||
}
|
||||
// #if NET5_0_OR_GREATER
|
||||
// #else
|
||||
// serializes = serializes.Where(x => x is not UnityEngine.Object);
|
||||
// #endif
|
||||
// foreach (var x in serializes)
|
||||
// {
|
||||
// serializableTypes.Add(x.GetType());
|
||||
// BIT4Log.Log<BITBinary>($"已注册类型:{x.GetType().FullName}");
|
||||
// }
|
||||
}
|
||||
|
||||
public static object Read<T>(byte[] buffer) => (T)ReadAsValue(buffer);
|
||||
|
@ -60,26 +73,22 @@ namespace BITKit
|
|||
|
||||
var typeName = reader.ReadString();
|
||||
if (netReaders.TryGetValue(typeName, out var netReader))
|
||||
{
|
||||
return netReader.ReadBinaryAsObject(reader);
|
||||
}
|
||||
var json = reader.ReadString();
|
||||
json = reader.ReadString();
|
||||
if (string.IsNullOrEmpty(json))
|
||||
{
|
||||
throw new Exception($"从二进制中读取的json值为空");
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
if (BITSharp.TryGetTypeFromFullName(typeName, out var type))
|
||||
{
|
||||
return JsonConvert.DeserializeObject(json, type);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception e)
|
||||
{
|
||||
BIT4Log.Warning<BITBinary>($"反序列化失败,类型:{typeName},值:\n{json}");
|
||||
throw;
|
||||
BIT4Log.LogException(e);
|
||||
}
|
||||
|
||||
|
||||
throw new Exception("未找到读取该二进制的BinaryReader");
|
||||
}
|
||||
|
||||
|
@ -119,14 +128,8 @@ namespace BITKit
|
|||
{
|
||||
netReader.WriteBinaryAsObject(writer,value);
|
||||
}
|
||||
else if( value is IBinarySerialize serialize)
|
||||
{
|
||||
serialize.Write(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
//throw new Exception($"没有找到{value.GetType().Name}的Binary写入方法");
|
||||
writer.Write(value!.GetType().FullName!);
|
||||
writer.Write(JsonConvert.SerializeObject(value));
|
||||
}
|
||||
}
|
||||
|
@ -139,10 +142,12 @@ namespace BITKit
|
|||
{
|
||||
return true;
|
||||
}
|
||||
else if (serializableTypes.Any(x => x.FullName == typeName))
|
||||
#if NET5_0_OR_GREATER
|
||||
else if (serializableTypes.Any(x => x.FullName == typeName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,19 @@ namespace BITKit
|
|||
}
|
||||
public static async void Excute(string cmd)
|
||||
{
|
||||
var cmdSplit = cmd.Split("|");
|
||||
if (cmdSplit.Length is 1 or 0)
|
||||
{
|
||||
cmdSplit = cmd.Split("\n");
|
||||
}
|
||||
if (cmdSplit.Length > 1)
|
||||
{
|
||||
foreach (var x in cmdSplit)
|
||||
{
|
||||
Excute(x);
|
||||
}
|
||||
return;
|
||||
}
|
||||
await UniTask.SwitchToThreadPool();
|
||||
await TaskHelper.WaitUntil(() => state is InitializationState.Initialized);
|
||||
var split = cmd.Split(" ").ToList();
|
||||
|
@ -87,27 +100,24 @@ namespace BITKit
|
|||
}
|
||||
static Dictionary<string, MethodInfo> methodInfos = new();
|
||||
static InitializationState state;
|
||||
[ExcuteOnStart]
|
||||
public static void Start()
|
||||
public static async UniTask InitializeAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
Init();
|
||||
await Init();
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
|
||||
BIT4Log.LogException(e);
|
||||
}
|
||||
|
||||
}
|
||||
[ExcuteOnStop]
|
||||
public static void Stop()
|
||||
public static void Dispose()
|
||||
{
|
||||
state = 0;
|
||||
methodInfos.Clear();
|
||||
}
|
||||
static async void Init()
|
||||
private static async UniTask Init()
|
||||
{
|
||||
state = InitializationState.Initializing;
|
||||
await UniTask.SwitchToThreadPool();
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 47446028359168843813e0d48fa10de5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6c3b8ff8ac3fe6f45bb8f4690a0a15e1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Security.Cryptography;
|
||||
namespace BITKit.Crypto
|
||||
{
|
||||
public class BITCrypto:ICryptography
|
||||
{
|
||||
public string Salt { get; set; } = "2196F3";
|
||||
public string Hash(string password)
|
||||
{
|
||||
var data = System.Text.Encoding.UTF8.GetBytes(password + Salt);
|
||||
return Convert.ToBase64String(data);
|
||||
}
|
||||
|
||||
public bool Verify(string password, string hash)
|
||||
{
|
||||
return Hash(password) == hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 259562ab3c5f28243819c92d2db08104
|
||||
guid: d015706f3749b334ab81c82b23a1575a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
|
@ -0,0 +1,26 @@
|
|||
namespace BITKit.Crypto
|
||||
{
|
||||
/// <summary>
|
||||
/// 加密接口
|
||||
/// </summary>
|
||||
public interface ICryptography
|
||||
{
|
||||
/// <summary>
|
||||
/// 盐
|
||||
/// </summary>
|
||||
public string Salt { get; set; }
|
||||
/// <summary>
|
||||
/// 获取Hash
|
||||
/// </summary>
|
||||
/// <param name="password"></param>
|
||||
/// <returns></returns>
|
||||
public string Hash(string password);
|
||||
/// <summary>
|
||||
/// 验证密码是否有效
|
||||
/// </summary>
|
||||
/// <param name="password">明文密码</param>
|
||||
/// <param name="hash"></param>
|
||||
/// <returns></returns>
|
||||
public bool Verify(string password, string hash);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3db000849b712bf4ea543570c2ea0f43
|
||||
guid: e6da82a831307d145bac6bdf73a852c9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
Binary file not shown.
|
@ -1,33 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 681d142aa31302548a110f6824493c32
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -2,8 +2,5 @@ using System;
|
|||
|
||||
namespace BITKit
|
||||
{
|
||||
public interface IServiceRegister
|
||||
{
|
||||
Type BaseType { get; }
|
||||
}
|
||||
|
||||
}
|
|
@ -3,7 +3,10 @@ using System.Collections.Generic;
|
|||
|
||||
namespace BITKit
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 双缓冲区
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public interface IDoubleBuffer<T>
|
||||
{
|
||||
T Current { get; }
|
||||
|
@ -11,7 +14,10 @@ namespace BITKit
|
|||
event Action<T> OnRelease;
|
||||
bool TryGetRelease(out T result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="IDoubleBuffer{T}"/>
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class DoubleBuffer<T> : IDoubleBuffer<T>
|
||||
{
|
||||
public T Current
|
||||
|
@ -25,14 +31,18 @@ namespace BITKit
|
|||
{
|
||||
Current = newValue;
|
||||
OnRelease?.Invoke(newValue);
|
||||
_release.SetValueThenAllow(newValue);
|
||||
}
|
||||
|
||||
public event Action<T> OnRelease;
|
||||
private readonly Queue<T> _releases = new();
|
||||
private readonly Optional<T> _release=new();
|
||||
|
||||
public bool TryGetRelease(out T result)
|
||||
{
|
||||
return _releases.TryDequeue(out result);
|
||||
result = _release.Value;
|
||||
if (!_release.Allow) return _release.Allow;
|
||||
_release.Clear();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,9 @@
|
|||
using System.Threading;
|
||||
using System;
|
||||
using System.ComponentModel.Design;
|
||||
#if NET5_0_OR_GREATER
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
#endif
|
||||
namespace BITKit.Core.Entites
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -8,14 +12,11 @@ namespace BITKit.Core.Entites
|
|||
public interface IEntity
|
||||
{
|
||||
ulong Id { get; }
|
||||
#if NET5_0_OR_GREATER
|
||||
bool TryGetComponent<T>(out T component) where T : IEntityComponent;
|
||||
CancellationToken CancellationToken { get; }
|
||||
bool TryGetComponent<T>(out T component);
|
||||
IEntityComponent[] Components { get; }
|
||||
bool RegisterComponent<T>(T component) where T : IEntityComponent;
|
||||
#else
|
||||
|
||||
#endif
|
||||
|
||||
bool RegisterComponent<T>(T component);
|
||||
IServiceProvider ServiceProvider { get; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 基本实体组件
|
||||
|
@ -24,6 +25,9 @@ namespace BITKit.Core.Entites
|
|||
{
|
||||
Type BaseType { get; }
|
||||
IEntity Entity { get; set; }
|
||||
#if NET5_0_OR_GREATER
|
||||
void BuildService(IServiceCollection serviceCollection);
|
||||
#endif
|
||||
}
|
||||
/// <summary>
|
||||
/// 基本实体服务
|
||||
|
@ -61,24 +65,28 @@ namespace BITKit.Core.Entites
|
|||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
IEntity Get(ulong id);
|
||||
|
||||
/// <summary>
|
||||
/// 查询Entity,例如
|
||||
/// </summary>
|
||||
/// <para>var rotationEntities=EntitiesService.Query<RotationComponent></para>
|
||||
IEntity[] Query<T>() where T : IEntityComponent;
|
||||
IEntity[] Query<T>();
|
||||
|
||||
/// <summary>
|
||||
/// 查询1个组件
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
T[] QueryComponents<T>() where T : IEntityComponent;
|
||||
T[] QueryComponents<T>();
|
||||
|
||||
/// <summary>
|
||||
/// 查询2个组件
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="T1"></typeparam>
|
||||
/// <returns></returns>
|
||||
ValueTuple<T,T1>[] QueryComponents<T,T1>()where T : IEntityComponent where T1 : IEntityComponent;
|
||||
ValueTuple<T, T1>[] QueryComponents<T, T1>();
|
||||
|
||||
/// <summary>
|
||||
/// 查询3个组件
|
||||
/// </summary>
|
||||
|
@ -86,7 +94,7 @@ namespace BITKit.Core.Entites
|
|||
/// <typeparam name="T1"></typeparam>
|
||||
/// <typeparam name="T2"></typeparam>
|
||||
/// <returns></returns>
|
||||
ValueTuple<T,T1,T2>[] QueryComponents<T,T1,T2>() where T : IEntityComponent where T1 : IEntityComponent where T2 : IEntityComponent;
|
||||
|
||||
ValueTuple<T, T1, T2>[] QueryComponents<T, T1, T2>();
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace BITKit
|
||||
{
|
||||
public static class FuncExtensions
|
||||
{
|
||||
public static IEnumerable<Func<T0,T1>> CastAsFunc<T0,T1>(this Func<T0,T1> self)
|
||||
{
|
||||
return self.GetInvocationList().Cast<Func<T0, T1>>();
|
||||
}
|
||||
public static IEnumerable<Func<T0,T1,T2>> CastAsFunc<T0,T1,T2>(this Func<T0,T1,T2> self)
|
||||
{
|
||||
return self.GetInvocationList().Cast<Func<T0, T1,T2>>();
|
||||
}
|
||||
public static IEnumerable<Func<T0,T1,T2,T3>> CastAsFunc<T0,T1,T2,T3>(this Func<T0,T1,T2,T3> self)
|
||||
{
|
||||
return self.GetInvocationList().Cast<Func<T0, T1,T2,T3>>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ebbaf967274f9c942bcbfccbea097f28
|
||||
guid: 8372b15121bd7e4408788d269d22fc20
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
|
@ -0,0 +1,19 @@
|
|||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BITKit
|
||||
{
|
||||
public static class HttpClientExtensions
|
||||
{
|
||||
public static async UniTask<string> PostJsonAsync(this HttpClient self, string requestUrl, object value , CancellationToken cancellationToken=default)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(value);
|
||||
var content = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
var response =await self.PostAsync(requestUrl, content, cancellationToken);
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c1610171280cf1d488accdfd46ae59d4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -33,6 +33,8 @@ namespace BITKit.Apps
|
|||
/// </summary>
|
||||
event Action<string> OnDownloadComplete;
|
||||
|
||||
event Action OnDetectedLatestVersion;
|
||||
|
||||
/// <summary>
|
||||
/// 下载最新版本
|
||||
/// </summary>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Timers;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using kcp2k;
|
||||
|
@ -21,6 +22,9 @@ namespace BITKit.Net
|
|||
public int Ping => -1;
|
||||
public int Id { get; private set; } = -1;
|
||||
private readonly KcpClient client;
|
||||
|
||||
private readonly Queue<byte[]> commandQueue = new();
|
||||
|
||||
private readonly Timer _timer = new(100)
|
||||
{
|
||||
AutoReset = true
|
||||
|
@ -44,8 +48,13 @@ namespace BITKit.Net
|
|||
});
|
||||
}
|
||||
|
||||
private void Tick(object sender, ElapsedEventArgs e)
|
||||
private async void Tick(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
await UniTask.SwitchToThreadPool();
|
||||
while (commandQueue.TryDequeue(out var bytes))
|
||||
{
|
||||
client.Send(bytes, KcpChannel.Reliable);
|
||||
}
|
||||
client.Tick();
|
||||
}
|
||||
|
||||
|
@ -108,8 +117,7 @@ namespace BITKit.Net
|
|||
case NetCommandType.Command:
|
||||
var command = BITBinary.Read(reader);
|
||||
if (command is object[] { Length: 1 } objs) command = objs[0];
|
||||
// BIT4Log.Log<KcpClient>(
|
||||
// $"已收到指令:{command},值:\n{JsonConvert.SerializeObject(command, Formatting.Indented)}");
|
||||
//BIT4Log.Log<KcpClient>($"已收到指令:{command},值:\n{JsonConvert.SerializeObject(command, Formatting.Indented)}");
|
||||
try
|
||||
{
|
||||
if (BITApp.SynchronizationContext is not null)
|
||||
|
@ -128,7 +136,7 @@ namespace BITKit.Net
|
|||
|
||||
break;
|
||||
case NetCommandType.Heartbeat:
|
||||
client.Send(new[] { (byte)NetCommandType.Heartbeat }, KcpChannel.Reliable);
|
||||
//client.Send(new[] { (byte)NetCommandType.Heartbeat }, KcpChannel.Reliable);
|
||||
break;
|
||||
default:
|
||||
BIT4Log.Log<KcpClient>($"未知消息类型:{type},字节:{(byte)type}");
|
||||
|
@ -249,7 +257,8 @@ namespace BITKit.Net
|
|||
.Write((byte)commandType)
|
||||
.WriteObject(values)
|
||||
.Build();
|
||||
client.Send(bytes, KcpChannel.Reliable);
|
||||
commandQueue.Enqueue(bytes);
|
||||
//client.Send(bytes, KcpChannel.Reliable);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace BITKit.Net
|
|||
{
|
||||
public class KCPNetServer:INetServer,INetProvider
|
||||
{
|
||||
public event Action<int> OnClientConnect;
|
||||
public event Action<int> OnClientConnected;
|
||||
public event Action<int> OnClientDisconnected;
|
||||
public event Action OnStartServer;
|
||||
public event Action OnStopServer;
|
||||
|
@ -74,6 +74,9 @@ namespace BITKit.Net
|
|||
new Dictionary<int, EndPoint>(
|
||||
server.connections.Select(x => new KeyValuePair<int, EndPoint>(x.Key, x.Value.remoteEndPoint)
|
||||
));
|
||||
|
||||
|
||||
|
||||
public void Tick() => server.Tick();
|
||||
public void HandShake()
|
||||
{
|
||||
|
@ -85,7 +88,7 @@ namespace BITKit.Net
|
|||
|
||||
private void OnConnected(int Id)
|
||||
{
|
||||
OnClientConnect?.Invoke(Id);
|
||||
OnClientConnected?.Invoke(Id);
|
||||
ClientCommand(Id,new NetClientAllocateIdCommand
|
||||
{
|
||||
Id = Id,
|
||||
|
@ -105,6 +108,7 @@ namespace BITKit.Net
|
|||
using var ms = new MemoryStream(bytes.ToArray());
|
||||
using var reader = new BinaryReader(ms);
|
||||
|
||||
BIT4Log.Log<INetServer>(Id);
|
||||
|
||||
var type = (NetCommandType)ms.ReadByte();
|
||||
switch (type)
|
||||
|
@ -114,9 +118,12 @@ namespace BITKit.Net
|
|||
break;
|
||||
case NetCommandType.Command:
|
||||
var command = BITBinary.Read(reader);
|
||||
if (command is object[] objs && objs.Length is 1) command = objs[0];
|
||||
//BIT4Log.Log<KCPNetServer>($"已收到指令:{command},值:\n{JsonConvert.SerializeObject(command, Formatting.Indented)}");
|
||||
if (command is object[] { Length: 1 } objs) command = objs[0];
|
||||
BIT4Log.Log<KCPNetServer>($"已收到指令:{command},值:\n{JsonConvert.SerializeObject(command, Formatting.Indented)}");
|
||||
_events.Invoke(command.GetType().FullName, command);
|
||||
|
||||
(int Id,object Command) tuple = (Id,command);
|
||||
_events.InvokeDirect(command.GetType().FullName,tuple);
|
||||
break;
|
||||
case NetCommandType.Heartbeat:
|
||||
server.Send(Id,new byte[]{(byte)NetCommandType.Heartbeat}, KcpChannel.Reliable);
|
||||
|
@ -179,6 +186,17 @@ namespace BITKit.Net
|
|||
{
|
||||
_events.AddListener<T>(handle);
|
||||
}
|
||||
|
||||
public void AddCommandListenerWithId<T>(Action<int, T> handle)
|
||||
{
|
||||
_events.AddListenerDirect(typeof(T).FullName, x =>
|
||||
{
|
||||
if (x is ValueTuple<int, T> tuple)
|
||||
{
|
||||
handle.Invoke(tuple.Item1,tuple.Item2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void RemoveCommandListener<T>(Action<T> handle)
|
||||
{
|
||||
|
|
|
@ -44,6 +44,19 @@ namespace BITKit
|
|||
return list;
|
||||
}
|
||||
|
||||
public static bool TryGetIndexOf<T>(this IEnumerable<T> self, Func<T, bool> factory, out int index)
|
||||
{
|
||||
index = -1;
|
||||
var enumerable = self as T[] ?? self.ToArray();
|
||||
for (var i = 0; i < enumerable.Length; i++)
|
||||
{
|
||||
var item = enumerable.ElementAt(i);
|
||||
if (!factory.Invoke(item)) continue;
|
||||
index = i;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static bool Contains<T>(IEnumerable<T> a, IEnumerable<T> b)
|
||||
{
|
||||
foreach (var x in b)
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
// ReSharper disable CheckNamespace
|
||||
namespace BITKit
|
||||
// ReSharper restore CheckNamespace
|
||||
{
|
||||
public record ContextModel
|
||||
{
|
||||
public static ContextModel Get(object data)
|
||||
{
|
||||
return new ContextModel()
|
||||
{
|
||||
StatusCode = 200,
|
||||
Message = "success",
|
||||
Data = data
|
||||
};
|
||||
}
|
||||
public static ContextModel Error(string message)
|
||||
{
|
||||
return new ContextModel()
|
||||
{
|
||||
StatusCode = 500,
|
||||
Message = message,
|
||||
Data = false
|
||||
};
|
||||
}
|
||||
public static ContextModel GetFromJson(string json)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = new ContextModel();
|
||||
var jObject = JObject.Parse(json);
|
||||
if(jObject.TryGetValue("status_code",out var statusCode))
|
||||
result.StatusCode = statusCode.Value<int>();
|
||||
if(jObject.TryGetValue("message",out var message))
|
||||
result.Message = message.Value<string>();
|
||||
if (jObject.TryGetValue("data", out var data))
|
||||
result.Data = data;
|
||||
return JsonConvert.DeserializeObject<ContextModel>(json);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BIT4Log.Warning(json);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
public static implicit operator string(ContextModel self)
|
||||
{
|
||||
return self.ToString();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return JsonConvert.SerializeObject(this);
|
||||
}
|
||||
|
||||
[JsonProperty("status_code")]
|
||||
public int StatusCode;
|
||||
[JsonProperty("message")]
|
||||
public string Message=string.Empty;
|
||||
[JsonProperty("data")]
|
||||
public object Data=string.Empty;
|
||||
[JsonIgnore]
|
||||
public bool IsSuccess => StatusCode is 200 or 0;
|
||||
public bool TryAs<T>(out T value)
|
||||
{
|
||||
switch (Data)
|
||||
{
|
||||
case T t:
|
||||
value = t;
|
||||
return true;
|
||||
case JToken jToken:
|
||||
value = jToken.ToObject<T>();
|
||||
return true;
|
||||
default:
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
using Newtonsoft.Json;
|
||||
// ReSharper disable CheckNamespace
|
||||
namespace BITKit
|
||||
// ReSharper restore CheckNamespace
|
||||
{
|
||||
public record ContextModel
|
||||
{
|
||||
public static ContextModel Get(object data)
|
||||
{
|
||||
return new ContextModel()
|
||||
{
|
||||
code = 200,
|
||||
message = "success",
|
||||
data = data
|
||||
};
|
||||
}
|
||||
public static ContextModel Error(object data)
|
||||
{
|
||||
return new ContextModel()
|
||||
{
|
||||
code = 500,
|
||||
message = "failed",
|
||||
data = data
|
||||
};
|
||||
}
|
||||
public static implicit operator string(ContextModel self)
|
||||
{
|
||||
return JsonConvert.SerializeObject(self);
|
||||
}
|
||||
public int code;
|
||||
public string message=string.Empty;
|
||||
public object data=string.Empty;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
#if UNITY
|
||||
#else
|
||||
#if NET5_0_OR_GREATER
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
#else
|
||||
#endif
|
||||
using System;
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 080bac71709b69c4ca047982932f76f0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: baf3f1a7c92c3a54ca4fc5c27d09e5aa
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace BITKit.Net.Http
|
||||
{
|
||||
public interface IHttpListenerService
|
||||
{
|
||||
bool IsListening { get; }
|
||||
int Port { get; set; }
|
||||
public event Func<HttpListenerRequest,HttpContent> OnRequest;
|
||||
void Start();
|
||||
void Stop();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8480f17d72498ee4a978ca8a4d85440a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,105 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
|
||||
namespace BITKit.Net.Http
|
||||
{
|
||||
public class HttpListenerService:IHttpListenerService
|
||||
{
|
||||
public bool IsListening=>_httpListener.IsListening;
|
||||
public int Port { get; set; }
|
||||
private readonly HttpListener _httpListener = new();
|
||||
public event Func<HttpListenerRequest,HttpContent> OnRequest;
|
||||
private readonly CancellationTokenSource _cancellationTokenSource = new();
|
||||
private CancellationToken _cancellationToken=>_cancellationTokenSource.Token;
|
||||
|
||||
public HttpListenerService()
|
||||
{
|
||||
Port = 7001;
|
||||
}
|
||||
public HttpListenerService(int port)
|
||||
{
|
||||
Port = port;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
if (HttpListener.IsSupported is false)
|
||||
{
|
||||
throw new NotImplementedException("HttpListener is not supported this platform");
|
||||
}
|
||||
_httpListener.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
|
||||
//_httpListener.Prefixes.Add($"http://localhost:{Port}/");
|
||||
#if NET5_0_OR_GREATER
|
||||
_httpListener.Prefixes.Add($"http://localhost:{Port}/");
|
||||
#else
|
||||
_httpListener.Prefixes.Add($"http://*:{Port}/");
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
Thread thread = new(Process);
|
||||
thread.Start();
|
||||
}
|
||||
public void Stop()
|
||||
{
|
||||
_cancellationTokenSource.Cancel();
|
||||
_httpListener.Stop();
|
||||
BIT4Log.Log<IHttpListenerService>("Is Trying To Stop");
|
||||
}
|
||||
private void Process()
|
||||
{
|
||||
_httpListener.Start();
|
||||
BIT4Log.Log<IHttpListenerService>($"{Port}\tIs Listening");
|
||||
while (_cancellationToken.IsCancellationRequested is false)
|
||||
{
|
||||
var result = _httpListener.BeginGetContext(ListenerCallback, _httpListener);
|
||||
result.AsyncWaitHandle.WaitOne();
|
||||
}
|
||||
BIT4Log.Log<IHttpListenerService>($"{Port}\tStopped");
|
||||
}
|
||||
|
||||
private void ListenerCallback(IAsyncResult result)
|
||||
{
|
||||
if (_cancellationToken.IsCancellationRequested) return;
|
||||
|
||||
var context = _httpListener.EndGetContext(result);
|
||||
var request = context.Request;
|
||||
|
||||
var response = context.Response;
|
||||
|
||||
|
||||
var output = response.OutputStream;
|
||||
|
||||
if (request.RawUrl is "/favicon.ico")
|
||||
{
|
||||
output.Close();
|
||||
response.Close();
|
||||
return;
|
||||
}
|
||||
|
||||
// 启用CORS
|
||||
response.Headers.Add("Access-Control-Allow-Origin", "*"); // 允许任何来源访问,生产环境应更具体设置
|
||||
response.Headers.Add("Access-Control-Allow-Methods", "*"); // 允许的HTTP方法
|
||||
response.Headers.Add("Access-Control-Allow-Headers", "*"); // 允许的标头
|
||||
|
||||
|
||||
var content = OnRequest?.Invoke(request);
|
||||
|
||||
var buffer = StringHelper.GetBytes(ContextModel.Error("没有注册请求事件"));
|
||||
if (content is not null)
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
buffer = content!.ReadAsByteArrayAsync(_cancellationToken).Result;
|
||||
#else
|
||||
buffer = content!.ReadAsByteArrayAsync().Result;
|
||||
#endif
|
||||
}
|
||||
response.ContentLength64 = buffer.Length;
|
||||
output.Write(buffer);
|
||||
output.Close();
|
||||
response.Close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 55947637fce62c643ba67ab42d72cce8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7f4804b35f0832940a028f2905294829
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9cf6dcf675e5fb74fa0675d39177e1c5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ef6bc358998385e409414022bd10c876
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
|
||||
namespace BITKit.Net.LAN
|
||||
{
|
||||
public interface ILANBroadcaster
|
||||
{
|
||||
int Port { get; set; }
|
||||
byte[] Buffer { get; set; }
|
||||
event Action<EndPoint, string> OnReceive;
|
||||
void StartBroadcast();
|
||||
void StopBroadcast();
|
||||
void StartListen();
|
||||
void StopListen();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5874f625a9ef3e24092f070bdce13c9f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,108 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace BITKit.Net.LAN
|
||||
{
|
||||
/// <summary>
|
||||
/// 基于UDP的LAN广播
|
||||
/// </summary>
|
||||
public class UdpBasedLanBroadcaster : ILANBroadcaster
|
||||
{
|
||||
public int Port { get; set; }
|
||||
public byte[] Buffer { get; set; } = StringHelper.GetBytes("Hello World");
|
||||
private bool _isBroadcasting;
|
||||
private bool _isListening;
|
||||
|
||||
public UdpBasedLanBroadcaster()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public event Action<EndPoint, string> OnReceive;
|
||||
|
||||
public void StartBroadcast()
|
||||
{
|
||||
_isBroadcasting = true;
|
||||
Thread thread = new(Process)
|
||||
{
|
||||
IsBackground = true
|
||||
};
|
||||
thread.Start();
|
||||
BIT4Log.Log<ILANBroadcaster>($"开始广播端口{Port}");
|
||||
}
|
||||
|
||||
public void StopBroadcast()
|
||||
{
|
||||
_isBroadcasting = false;
|
||||
BIT4Log.Log<ILANBroadcaster>($"停止广播端口 {Port}");
|
||||
}
|
||||
|
||||
public void StartListen()
|
||||
{
|
||||
_isListening = true;
|
||||
var thread = new Thread(ReceiveThread)
|
||||
{
|
||||
IsBackground = true
|
||||
};
|
||||
thread.Start();
|
||||
BIT4Log.Log<ILANBroadcaster>($"开始监听端口:{Port}");
|
||||
}
|
||||
|
||||
public void StopListen()
|
||||
{
|
||||
_isListening = false;
|
||||
BIT4Log.Log<ILANBroadcaster>($"停止监听端口{Port}");
|
||||
}
|
||||
|
||||
|
||||
private void Process()
|
||||
{
|
||||
var udpClient = new UdpClient(new IPEndPoint(IPAddress.Any, 0));
|
||||
|
||||
var endpoint = new IPEndPoint(IPAddress.Broadcast, Port);
|
||||
//其实 IPAddress.Broadcast 就是 255.255.255.255
|
||||
//下面代码与上面有相同的作用
|
||||
//IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("255.255.255.255"), 8080);
|
||||
try
|
||||
{
|
||||
while (_isBroadcasting)
|
||||
{
|
||||
udpClient.Send(Buffer, Buffer.Length, endpoint);
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BIT4Log.LogException(e);
|
||||
}
|
||||
udpClient.Dispose();
|
||||
}
|
||||
|
||||
private void ReceiveThread()
|
||||
{
|
||||
try
|
||||
{
|
||||
var udpClient = new UdpClient(new IPEndPoint(IPAddress.Any, Port));
|
||||
var endpoint = new IPEndPoint(IPAddress.Any, 0);
|
||||
while (_isListening)
|
||||
{
|
||||
var buf = udpClient.Receive(ref endpoint);
|
||||
var msg = Encoding.Default.GetString(buf);
|
||||
if (OnReceive is not null)
|
||||
OnReceive(endpoint, msg);
|
||||
else
|
||||
BIT4Log.Log<ILANBroadcaster>($"Receive From {endpoint}:\t{msg}");
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BIT4Log.LogException(e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4822fff0e51bc0a43a98342ea5c1d9d0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -141,7 +141,7 @@ namespace BITKit
|
|||
/// <summary>
|
||||
/// 回调:当客户端连接时
|
||||
/// </summary>
|
||||
public event Action<int> OnClientConnect;
|
||||
public event Action<int> OnClientConnected;
|
||||
|
||||
/// <summary>
|
||||
/// 回调:当客户端断开连接时
|
||||
|
@ -188,6 +188,13 @@ namespace BITKit
|
|||
/// 所有已连接的客户端
|
||||
/// </summary>
|
||||
public IDictionary<int,EndPoint> Connections { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 添加远程命令监听,包括客户端Id
|
||||
/// </summary>
|
||||
/// <param name="handle"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
void AddCommandListenerWithId<T>(Action<int,T> handle);
|
||||
}
|
||||
/// <summary>
|
||||
/// 基本网络客户端的接口定义,包括了基本客户端的功能
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
}
|
||||
public interface IOptional<T>
|
||||
{
|
||||
bool Allow { get; }
|
||||
T Value { get; }
|
||||
bool Allow { get; set; }
|
||||
T Value { get; set; }
|
||||
}
|
||||
[System.Serializable]
|
||||
public record Optional<T> : IOptional<T>
|
||||
public class Optional<T> : IOptional<T>
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
bool allow;
|
||||
|
@ -23,8 +23,18 @@
|
|||
T value;
|
||||
#endif
|
||||
public bool Allow { get => allow; set => allow = value;}
|
||||
public T Value { get => value; set => this.value = value; }
|
||||
public void SetValueThenAllow(T newValue) => value = newValue;
|
||||
public T Value
|
||||
{
|
||||
get => value;
|
||||
set=>this.value=value;
|
||||
}
|
||||
|
||||
public void SetValueThenAllow(T newValue)
|
||||
{
|
||||
value = newValue;
|
||||
allow = true;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
Allow = false;
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
namespace BITKit
|
||||
using System;
|
||||
|
||||
namespace BITKit
|
||||
{
|
||||
/// <summary>
|
||||
/// 订阅者,发布者下发任务给支持并优先级最高的订阅者
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
[Obsolete]
|
||||
public interface TaskSubscriber<in T>
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -22,6 +25,7 @@
|
|||
/// 发布接口,向发布者下发任务
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
[Obsolete("Use Func Instanced",true)]
|
||||
public interface TaskPublisher<in T>
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
// ReSharper disable UnassignedGetOnlyAutoProperty
|
||||
|
||||
namespace BITKit.UX
|
||||
{
|
||||
|
@ -44,7 +45,7 @@ namespace BITKit.UX
|
|||
}
|
||||
public abstract class UXPanelImplement:IUXPanel
|
||||
{
|
||||
private IUXPanel _iuxPanelImplementation1;
|
||||
protected virtual IUXPanel _iuxPanelImplementation1 { get; }
|
||||
protected abstract IUXPanel _iuxPanelImplementation { get; }
|
||||
public bool IsAnimate => _iuxPanelImplementation.IsAnimate;
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace BITKit
|
|||
public const string Status = "Status";
|
||||
public const string State = "State";
|
||||
public const string Settings = "Settings";
|
||||
public const string Services = "Services";
|
||||
public const string AudioClip = "AudioClip";
|
||||
public const string AudioSource = "AudioSource";
|
||||
public const string Paths = "Paths";
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
|
||||
namespace BITKit
|
||||
{
|
||||
/// <summary>泛型事件,简单的事件接口</summary>
|
||||
|
@ -39,6 +40,12 @@ namespace BITKit
|
|||
var list = events.Get(key);
|
||||
list.Add(action);
|
||||
}
|
||||
|
||||
public void AddListenerDirect(string key, Action<object> action)
|
||||
{
|
||||
events.Get(key).Add(action);
|
||||
}
|
||||
|
||||
public void Invoke<T>(string key, T value)
|
||||
{
|
||||
key = key.GetType<T>();
|
||||
|
@ -52,6 +59,17 @@ namespace BITKit
|
|||
}
|
||||
});
|
||||
}
|
||||
public void InvokeDirect(string key,object value)
|
||||
{
|
||||
var list = events.Get(key);
|
||||
list.ToArray().ForEach(x =>
|
||||
{
|
||||
if (x is Action<object> action)
|
||||
{
|
||||
action.Invoke(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
public void Invoke(string typeName, object value)
|
||||
{
|
||||
var key = $"{typeName}.{defaultEventName}";
|
||||
|
@ -80,6 +98,7 @@ namespace BITKit
|
|||
public void Set<T>(T value) => dictionary.Set(Constant.System.Internal.GetType<T>(), value);
|
||||
public void Set<T>(string key, T value) => dictionary.Set(key.GetType<T>(), value);
|
||||
public void Set(Type type, object value) => dictionary.Set($"{type.FullName}.{Constant.System.Internal}", value);
|
||||
public void SetDirect(string key, object value) => dictionary.Set(key, value);
|
||||
public void RemoveListener<T>(string key, Action<T> action)
|
||||
{
|
||||
key = key.GetType<T>();
|
||||
|
@ -115,5 +134,10 @@ namespace BITKit
|
|||
}
|
||||
|
||||
public void Invoke<T>() where T : new() => Invoke(new T());
|
||||
|
||||
public bool TryGetObjectDirect(string key, out object value)
|
||||
{
|
||||
return dictionary.TryGetValue(key, out value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
{
|
||||
string Get();
|
||||
string Value => Get();
|
||||
string Replace(string value) => Get().Replace("{x}",value);
|
||||
}
|
||||
|
||||
public interface IReference<T>
|
||||
|
@ -37,9 +38,12 @@
|
|||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[UnityEngine.TextArea]
|
||||
#endif
|
||||
public string value;
|
||||
public override string Get() => value;
|
||||
public override string ToString() => value;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
|
|
|
@ -5,17 +5,12 @@ namespace BITKit
|
|||
{
|
||||
public class ValidHandle
|
||||
{
|
||||
public ValidHandle() { Init(); }
|
||||
public ValidHandle() {}
|
||||
public ValidHandle(Action<bool> boolDelegate)
|
||||
{
|
||||
AddListener(boolDelegate);
|
||||
Init();
|
||||
EventOnEnableChanged?.Invoke(enableHandle);
|
||||
}
|
||||
void Init()
|
||||
{
|
||||
AddListener(OnInoke);
|
||||
}
|
||||
public static implicit operator bool(ValidHandle validHandle)
|
||||
{
|
||||
return validHandle.enableHandle;
|
||||
|
@ -24,8 +19,6 @@ namespace BITKit
|
|||
public bool Allow => this;
|
||||
|
||||
private bool enableHandle;
|
||||
private int enableElementCount;
|
||||
private int disableElementCount;
|
||||
private readonly List<object> objs = new List<object>();
|
||||
private readonly List<object> disableObjs = new List<object>();
|
||||
private bool tempEnable;
|
||||
|
@ -43,7 +36,7 @@ namespace BITKit
|
|||
}
|
||||
CheckEnable();
|
||||
}
|
||||
protected virtual void CheckEnable()
|
||||
protected void CheckEnable()
|
||||
{
|
||||
tempEnable = objs.Count > 0 && disableObjs.Count == 0;
|
||||
if (tempEnable != enableHandle)
|
||||
|
@ -51,13 +44,8 @@ namespace BITKit
|
|||
enableHandle = tempEnable;
|
||||
if (EventOnEnableChanged is not null)
|
||||
EventOnEnableChanged.Invoke(enableHandle);
|
||||
OnEnable(enableHandle);
|
||||
|
||||
}
|
||||
enableElementCount = objs.Count;
|
||||
disableElementCount = disableObjs.Count;
|
||||
}
|
||||
protected virtual void OnEnable(bool enable) { }
|
||||
public virtual void RemoveElement(object obj)
|
||||
{
|
||||
if (objs.Contains(obj))
|
||||
|
@ -93,7 +81,7 @@ namespace BITKit
|
|||
}
|
||||
CheckEnable();
|
||||
}
|
||||
public virtual void RemoveDisableElements(object obj)
|
||||
public void RemoveDisableElements(object obj)
|
||||
{
|
||||
if (disableObjs.Contains(obj))
|
||||
{
|
||||
|
@ -104,7 +92,7 @@ namespace BITKit
|
|||
}
|
||||
CheckEnable();
|
||||
}
|
||||
public virtual void SetElements(object obj, bool add = true)
|
||||
public void SetElements(object obj, bool add = true)
|
||||
{
|
||||
if (add)
|
||||
{
|
||||
|
@ -126,29 +114,33 @@ namespace BITKit
|
|||
RemoveDisableElements(obj);
|
||||
}
|
||||
}
|
||||
public virtual void Invoke()
|
||||
public void Invoke()
|
||||
{
|
||||
bool enable = disableObjs.Count == 0 && objs.Count > 0;
|
||||
EventOnEnableChanged.Invoke(enable);
|
||||
var enable = disableObjs.Count == 0 && objs.Count > 0;
|
||||
EventOnEnableChanged?.Invoke(enable);
|
||||
}
|
||||
public virtual void Invoke(bool value)
|
||||
public void Invoke(bool value)
|
||||
{
|
||||
EventOnEnableChanged.Invoke(value);
|
||||
EventOnEnableChanged?.Invoke(value);
|
||||
}
|
||||
public virtual void OnInoke(bool value)
|
||||
{
|
||||
|
||||
}
|
||||
public virtual void AddListener(Action<bool> action)
|
||||
public void AddListener(Action<bool> action)
|
||||
{
|
||||
EventOnEnableChanged+= action;
|
||||
}
|
||||
public virtual void RemoveListener(Action<bool> action)
|
||||
public void RemoveListener(Action<bool> action)
|
||||
{
|
||||
if(EventOnEnableChanged is not null && action is not null)
|
||||
{
|
||||
EventOnEnableChanged -= action;
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
objs.Clear();
|
||||
disableObjs.Clear();
|
||||
Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ namespace BITKit
|
|||
[BITCommand]
|
||||
public static void Set(string key, string value)
|
||||
{
|
||||
Data.Set(key, value);
|
||||
if (Guid.TryParse(value, out var guidResult))
|
||||
{
|
||||
Data.Set(key, guidResult);
|
||||
|
@ -35,6 +34,10 @@ namespace BITKit
|
|||
{
|
||||
Data.Set(key, intResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
Data.Set(key, value);
|
||||
}
|
||||
}
|
||||
[BITCommand]
|
||||
public static void SetContainer(string key, string typeName, string json)
|
||||
|
|
|
@ -32,6 +32,12 @@ namespace BITKit
|
|||
|
||||
return GetPath(paths);
|
||||
}
|
||||
public static void EnsureDirectoryCreated(string path)
|
||||
{
|
||||
path = Path.GetDirectoryName(path);
|
||||
if (Directory.Exists(path) is true) return;
|
||||
if (path != null) Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
public static string GetFilePath(params string[] paths)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b6a022bce79573f4e92be71426b89938
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "BITKit.EntityFramework",
|
||||
"rootNamespace": "",
|
||||
"references": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [
|
||||
"NET5_0_OR_GREATER"
|
||||
],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 715ab799293af1942afd9ce5ef57c99b
|
||||
guid: a3f593891073dfc4c860f7df41ef8e2c
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
|
@ -0,0 +1,54 @@
|
|||
#if NET5_0_OR_GREATER
|
||||
using System;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace BITKit;
|
||||
|
||||
public interface IDatabaseContext<T> where T : class
|
||||
{
|
||||
void Add(T entity);
|
||||
UniTask AddAsync(T entity);
|
||||
void Remove(T entity);
|
||||
T[] GetArray();
|
||||
bool TrySearch(Func<T, bool> searchFactory, out T result);
|
||||
bool TrySearchArray(Func<T, bool> searchFactory, out T[] result);
|
||||
}
|
||||
|
||||
public abstract class EntityFrameworkContext<T>:DbContext ,IDatabaseContext<T> where T : class
|
||||
{
|
||||
protected DbSet<T> context { get; private set; }
|
||||
|
||||
public void Add(T entity)
|
||||
{
|
||||
context.Add(entity);
|
||||
SaveChanges();
|
||||
}
|
||||
|
||||
public async UniTask AddAsync(T entity)
|
||||
{
|
||||
await context.AddAsync(entity);
|
||||
await SaveChangesAsync();
|
||||
}
|
||||
|
||||
public void Remove(T entity)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public T[] GetArray()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TrySearch(Func<T, bool> searchFactory, out T result)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TrySearchArray(Func<T, bool> searchFactory, out T[] result)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 355b442bac74fd443b42f7f601c5a824
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,19 @@
|
|||
#if NET5_0_OR_GREATER
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace BITKit;
|
||||
|
||||
public class MySQLContext<T>:DbContext where T:class
|
||||
{
|
||||
protected readonly string _connectSql;
|
||||
protected DbSet<T> context { get; private set; }
|
||||
public MySQLContext(string connectSql) : base()
|
||||
{
|
||||
_connectSql = connectSql;
|
||||
}
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
optionsBuilder.UseMySQL("_connectSql");
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 88296b712b21d1549acf51a95b74e126
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,82 @@
|
|||
#if NET5_0_OR_GREATER
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace BITKit;
|
||||
|
||||
|
||||
|
||||
public class SqlLiteContext<T> : DbContext,IDatabaseContext<T> where T : class
|
||||
{
|
||||
public DbSet<T> context { get; private set; }
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
var sql = SQLiteContextHelper.GetConnectionString<T>();
|
||||
optionsBuilder.UseSqlite(sql);
|
||||
}
|
||||
public virtual void Add(T entity)
|
||||
{
|
||||
context.Add(entity);
|
||||
SaveChanges();
|
||||
}
|
||||
|
||||
public UniTask AddAsync(T entity)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public virtual void Remove(T entity)
|
||||
{
|
||||
context.Remove(entity);
|
||||
SaveChanges();
|
||||
}
|
||||
public virtual T[] GetArray()
|
||||
{
|
||||
return context.ToArray();
|
||||
}
|
||||
public virtual bool TrySearch(Func<T,bool> searchFactory,out T result)
|
||||
{
|
||||
result = context.FirstOrDefault(searchFactory);
|
||||
return result != null;
|
||||
}
|
||||
/// <summary>
|
||||
/// 搜索数组
|
||||
/// </summary>
|
||||
/// <param name="searchFactory"></param>
|
||||
/// <param name="result"></param>
|
||||
/// <returns></returns>
|
||||
public virtual bool TrySearchArray(Func<T, bool> searchFactory, out T[] result)
|
||||
{
|
||||
result = context.Where(searchFactory).ToArray();
|
||||
return result.Length > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static class SQLiteContextHelper
|
||||
{
|
||||
private const string _database = "Database";
|
||||
|
||||
public static string GetConnectionString(string key)
|
||||
{
|
||||
GetConnectionSqlAndPath(key,out var connectionSql,out var path);
|
||||
BIT4Log.Log($"已创建数据库链接:{path}");
|
||||
return connectionSql;
|
||||
}
|
||||
|
||||
public static string GetConnectionString<T>()
|
||||
{
|
||||
GetConnectionSqlAndPath(typeof(T).Name,out var connectionSql,out var path);
|
||||
BIT4Log.Log<T>($"已创建数据库链接:{path}");
|
||||
return connectionSql;
|
||||
}
|
||||
|
||||
public static void GetConnectionSqlAndPath(string name,out string connectionSql,out string path)
|
||||
{
|
||||
PathHelper.GetFolderPath(_database);
|
||||
path = PathHelper.GetPath(_database, $"{name}.db");
|
||||
connectionSql = $"Data Source={path}";
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 051098367a2e84d4c9ade3bc7ef6eb1e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 17d6f75da2f6aef4491958ba74c65d1e
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -26,6 +26,7 @@ RenderTexture:
|
|||
m_UseDynamicScale: 0
|
||||
m_BindMS: 0
|
||||
m_EnableCompatibleFormat: 1
|
||||
m_EnableRandomWrite: 0
|
||||
m_TextureSettings:
|
||||
serializedVersion: 2
|
||||
m_FilterMode: 1
|
||||
|
|
|
@ -76,7 +76,7 @@ Transform:
|
|||
m_GameObject: {fileID: 4263150313831602955}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: 0.99025595, z: -0.1392595, w: 0}
|
||||
m_LocalPosition: {x: 2.14, y: 1.942205, z: -0.5443456}
|
||||
m_LocalPosition: {x: 2.1400003, y: 1.942205, z: -0.5443456}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
|
@ -255,7 +255,7 @@ MonoBehaviour:
|
|||
m_RotationOrder: 4
|
||||
cameraDistanceLimit: {x: 1, y: 64}
|
||||
allowInput:
|
||||
rid: 6077775057159979015
|
||||
rid: 8000561620556709889
|
||||
touchesCount: 0
|
||||
isParallelVector: 0
|
||||
lookInput: {x: 0, y: 0, z: 0}
|
||||
|
@ -263,8 +263,8 @@ MonoBehaviour:
|
|||
references:
|
||||
version: 2
|
||||
RefIds:
|
||||
- rid: 6077775057159979015
|
||||
type: {class: AllowTouchWhenPointerNotOverUI, ns: BITKit.UX, asm: BITKit.UX.OnScreen}
|
||||
- rid: 8000561620556709889
|
||||
type: {class: AllowCondition, ns: BITKit, asm: BITKit.Node}
|
||||
data:
|
||||
--- !u!1 &4263150314961711450
|
||||
GameObject:
|
||||
|
|
|
@ -50,6 +50,8 @@ namespace BITKit
|
|||
remove => ApplicationService.OnDownloadComplete -= value;
|
||||
}
|
||||
|
||||
public event Action OnDetectedLatestVersion;
|
||||
|
||||
public UniTask<string> DownloadLatestVersionAsync()
|
||||
{
|
||||
return _applicationServiceImplementation.DownloadLatestVersionAsync();
|
||||
|
@ -104,6 +106,12 @@ namespace BITKit
|
|||
remove => OnDownloadComplete -= value;
|
||||
}
|
||||
|
||||
public event Action OnDetectedLatestVersion
|
||||
{
|
||||
add => Singleton.OnDetectedLatestVersion += value;
|
||||
remove => Singleton.OnDetectedLatestVersion -= value;
|
||||
}
|
||||
|
||||
private UnityWebRequest downloadRequest;
|
||||
|
||||
private CancellationTokenSource _cancellationTokenSource;
|
||||
|
|
|
@ -2,7 +2,6 @@ using System;
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.Remoting.Contexts;
|
||||
using UnityEngine;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -79,10 +78,8 @@ namespace BITKit
|
|||
BIT4Log.OnLog += Debug.Log;
|
||||
BIT4Log.OnWarning += Debug.LogWarning;
|
||||
BIT4Log.OnException += Debug.LogException;
|
||||
|
||||
var settings = Addressables.LoadAssetAsync<ScriptableObject>("Assets/BITKit/Unity/Configs/AppSettings.asset").WaitForCompletion() as BITSettingsSO;
|
||||
//启动BITApp
|
||||
BITApp.Start(Application.productName, settings!.appSettings);
|
||||
BITApp.Start(Application.productName, new BITApp.AppSettings()).Forget();
|
||||
|
||||
AllowCursor = new();
|
||||
AllowTouchSupport = new();
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using UnityEngine;
|
||||
namespace BITKit
|
||||
{
|
||||
public class BITSettingsSO : ScriptableObject
|
||||
{
|
||||
public BITApp.AppSettings appSettings;
|
||||
|
||||
[ContextMenu(nameof(Print))]
|
||||
public void Print()
|
||||
{
|
||||
GUIUtility.systemCopyBuffer = JsonConvert.SerializeObject(appSettings.blackList, Formatting.Indented);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -196,8 +196,8 @@ namespace BITKit
|
|||
private void Update()
|
||||
{
|
||||
//var debuger = DI.Get<IDebuger>();
|
||||
var playerConfig = PlayerConfig.singleton;
|
||||
var sensitivity = playerConfig.touchSensitivity;
|
||||
var playerConfig = PlayerConfig.Singleton;
|
||||
var sensitivity = playerConfig.TouchSensitivity;
|
||||
|
||||
//debuger.Log(nameof(Touch.activeTouches), Touch.activeTouches.Count.ToString());
|
||||
touchesCount = Touch.activeTouches.Count;
|
||||
|
@ -229,8 +229,8 @@ namespace BITKit
|
|||
private void OnView(InputAction.CallbackContext context)
|
||||
{
|
||||
if (allowInput.OnCheck() is false) return;
|
||||
var playerConfig = PlayerConfig.singleton;
|
||||
var sensitivity = playerConfig.sensitivity * playerConfig.m_yaw;
|
||||
var playerConfig = PlayerConfig.Singleton;
|
||||
var sensitivity = playerConfig.Sensitivity * playerConfig.M_Yaw;
|
||||
var delta = context.ReadValue<Vector2>();
|
||||
switch (context.control.device)
|
||||
{
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BITKit
|
||||
{
|
||||
public class ExcuteCommand : MonoBehaviour
|
||||
{
|
||||
public string command;
|
||||
public void Excute()
|
||||
{
|
||||
Data.Set("Cmd", command);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BITKit
|
||||
{
|
||||
public class ExecuteCommand : MonoBehaviour
|
||||
{
|
||||
public string command;
|
||||
[SerializeReference, SubclassSelector] private IReference format;
|
||||
public void Execute()
|
||||
{
|
||||
Data.Set("Cmd", command);
|
||||
}
|
||||
public void Execute(string cmd)
|
||||
{
|
||||
if(format!=null)
|
||||
cmd = format.Value.Replace("{x}",cmd);
|
||||
BITCommands.Excute(cmd);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,11 +5,10 @@ namespace BITKit
|
|||
{
|
||||
public record PlayerConfig
|
||||
{
|
||||
[SaveData]
|
||||
public static PlayerConfig singleton = new();
|
||||
public float sensitivity = 1.81f;
|
||||
public float touchSensitivity = 0.22f;
|
||||
public float m_yaw = 0.022f;
|
||||
public float fov = 75;
|
||||
public static readonly PlayerConfig Singleton = new();
|
||||
public float Sensitivity = 1.81f;
|
||||
public float TouchSensitivity = 0.22f;
|
||||
public float M_Yaw = 0.022f;
|
||||
public float Fov = 75;
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@ using UnityEngine.SceneManagement;
|
|||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using UnityEngine.Pool;
|
||||
using BITModel;
|
||||
namespace BITKit
|
||||
{
|
||||
public class UnityDiagnostics : MonoBehaviour, IDiagnostics
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
"GUID:28c2d6a6727d47442a24a353f0d37846",
|
||||
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
|
||||
"GUID:d525ad6bd40672747bde77962f1c401e",
|
||||
"GUID:be17a8778dbfe454890ed8279279e153"
|
||||
"GUID:be17a8778dbfe454890ed8279279e153",
|
||||
"GUID:96f476e982d6fb945bfc9140ba094b7f",
|
||||
"GUID:4307f53044263cf4b835bd812fc161a4"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BITKit.Entities.Movement
|
||||
{
|
||||
public sealed class GravityDamage:IDamageType
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cdf96f81bc60af44e8233982c2183015
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -5,6 +5,9 @@ using BITKit;
|
|||
using BITKit.Animations;
|
||||
using BITKit.StateMachine;
|
||||
using System.Linq;
|
||||
using BITFALL.Player.Equip;
|
||||
using Cinemachine;
|
||||
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
public interface IEquipBase : IEntryElement, IAwake, IStart, IUpdate
|
||||
|
@ -31,10 +34,17 @@ namespace BITKit.Entities
|
|||
public virtual void EquipEvent(string eventName){}
|
||||
public virtual void AnimationEvent(string eventName){}
|
||||
}
|
||||
public class EntityEquipment : EntityComponent
|
||||
[CustomType(typeof(IEquipService))]
|
||||
public class EntityEquipment : EntityComponent,IEquipService
|
||||
{
|
||||
public EntryGroup<IEquipBase> equips = new();
|
||||
public IOptional<float> Zoom { get; } = new Optional<float>(){Value = 1};
|
||||
|
||||
public float InitialFov;
|
||||
|
||||
[SerializeField] private CinemachineVirtualCamera virtualCamera;
|
||||
protected IEquipBase entryComplete;
|
||||
private PlayerConfig playerConfig;
|
||||
public override void OnStart()
|
||||
{
|
||||
base.OnStart();
|
||||
|
@ -56,6 +66,13 @@ namespace BITKit.Entities
|
|||
{
|
||||
entryComplete.OnUpdate(deltaTime);
|
||||
}
|
||||
|
||||
var current = virtualCamera.m_Lens.FieldOfView;
|
||||
current= Mathf.Lerp(current,Zoom.Allow ? InitialFov / Zoom.Value : PlayerConfig.Singleton.Fov , deltaTime * 5);
|
||||
current = Mathf.Clamp(current, 10, PlayerConfig.Singleton.Fov);
|
||||
virtualCamera.m_Lens.FieldOfView = current;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -37,8 +37,18 @@ namespace BITKit.Entities
|
|||
|
||||
public interface IHealth
|
||||
{
|
||||
/// <summary>
|
||||
/// 当设置HP时的回调
|
||||
/// </summary>
|
||||
public event Action<int> OnSetHealthPoint;
|
||||
/// <summary>
|
||||
/// 当设置生存状态时的回调
|
||||
/// </summary>
|
||||
public event Action<bool> OnSetAlive;
|
||||
/// <summary>
|
||||
/// 当受到伤害时的回调
|
||||
/// </summary>
|
||||
public event Func<DamageMessage,int,int> OnDamage;
|
||||
int HealthPoint { get; set; }
|
||||
int MaxHealthPoint { get; set; }
|
||||
bool IsAlive { get; }
|
||||
|
@ -50,14 +60,13 @@ namespace BITKit.Entities
|
|||
[SerializeField] private int healthPoint = 100;
|
||||
[SerializeField] private int maxHealthPoint = 100;
|
||||
|
||||
[Header(Constant.Header.Events)]
|
||||
[SerializeField] private UnityEvent<bool> onSetAlive = new();
|
||||
|
||||
[Header(Constant.Header.Providers)] [SerializeField, SerializeReference, SubclassSelector]
|
||||
[Obsolete]
|
||||
private IHealthCallback[] additiveCallback;
|
||||
|
||||
public event Action<int> OnSetHealthPoint;
|
||||
public event Action<bool> OnSetAlive;
|
||||
public event Func<DamageMessage,int, int> OnDamage;
|
||||
|
||||
public int HealthPoint
|
||||
{
|
||||
|
@ -72,7 +81,7 @@ namespace BITKit.Entities
|
|||
public bool IsAlive { get; private set; }
|
||||
public override void OnAwake()
|
||||
{
|
||||
entity.AddListener<DamageMessage>(OnDamage);
|
||||
entity.AddListener<DamageMessage>(OnGetDamage);
|
||||
}
|
||||
|
||||
public override void OnStart()
|
||||
|
@ -95,11 +104,6 @@ namespace BITKit.Entities
|
|||
x.OnSetHP(newHP);
|
||||
}
|
||||
|
||||
foreach (var x in additiveCallback)
|
||||
{
|
||||
x.OnSetHP(newHP);
|
||||
}
|
||||
|
||||
OnSetHealthPoint?.Invoke(newHP);
|
||||
}
|
||||
|
||||
|
@ -110,12 +114,11 @@ namespace BITKit.Entities
|
|||
{
|
||||
x.OnSetAlive(alive);
|
||||
}
|
||||
foreach (var x in additiveCallback)
|
||||
{
|
||||
x.OnSetAlive(alive);
|
||||
}
|
||||
// foreach (var x in additiveCallback)
|
||||
// {
|
||||
// x.OnSetAlive(alive);
|
||||
// }
|
||||
OnSetAlive?.Invoke(alive);
|
||||
onSetAlive.Invoke(alive);
|
||||
}
|
||||
|
||||
private void AddHP(int hp)
|
||||
|
@ -123,10 +126,15 @@ namespace BITKit.Entities
|
|||
OnHealthPointChangedInternal(healthPoint, healthPoint += hp);
|
||||
}
|
||||
|
||||
private void OnDamage(DamageMessage damageMessage)
|
||||
private void OnGetDamage(DamageMessage damageMessage)
|
||||
{
|
||||
if (damageMessage.target == entity)
|
||||
AddHP(-damageMessage.damage);
|
||||
if (damageMessage.target != entity) return;
|
||||
var damage = damageMessage.damage;
|
||||
foreach (var x in OnDamage.CastAsFunc())
|
||||
{
|
||||
damage = x.Invoke(damageMessage,damage);
|
||||
}
|
||||
AddHP(-damage);
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
[BIT]
|
||||
|
|
|
@ -6,7 +6,10 @@
|
|||
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0",
|
||||
"GUID:f822dbf6fdfd4a5469cccaa2e4eed3b6",
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
||||
"GUID:75469ad4d38634e559750d17036d5f7c"
|
||||
"GUID:75469ad4d38634e559750d17036d5f7c",
|
||||
"GUID:d525ad6bd40672747bde77962f1c401e",
|
||||
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
|
||||
"GUID:508392158bd966c4d9c21e19661a441d"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using BITKit.Sensors;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.InputSystem.Interactions;
|
||||
|
@ -6,24 +7,16 @@ namespace BITKit.Entities.Player
|
|||
public class EntityInteractive : EntityPlayerComponent
|
||||
{
|
||||
[Header(Constant.Header.Settings)]
|
||||
public float distance;
|
||||
public LayerMask layerMask;
|
||||
|
||||
[Header(Constant.Header.Input)]
|
||||
public InputActionReference interactiveAction;
|
||||
private readonly InputActionGroup inputActionGroup = new();
|
||||
|
||||
[Header(Constant.Header.Gameobjects)]
|
||||
[SerializeField] private Transform cameraTransform;
|
||||
[SerializeReference, SubclassSelector] private ISensor sensor;
|
||||
|
||||
[Header(Constant.Header.InternalVariables)]
|
||||
private ISelectable selected;
|
||||
private IntervalUpdate cd = new(0.08f);
|
||||
public override void OnUpdate(float deltaTime)
|
||||
{
|
||||
if (Physics.Raycast(cameraTransform.position,cameraTransform.forward, out var raycastHit, distance, layerMask,QueryTriggerInteraction.Collide))
|
||||
if (sensor.Get().TryGetAny(x=>x.TryGetComponentAny<ISelectable>(out _),out var detected))
|
||||
{
|
||||
if (raycastHit.transform.TryGetComponentAny<ISelectable>(out var _detected))
|
||||
if (detected.TryGetComponentAny<ISelectable>(out var _detected))
|
||||
{
|
||||
if (_detected == selected)
|
||||
{
|
||||
|
@ -68,7 +61,7 @@ namespace BITKit.Entities.Player
|
|||
}
|
||||
public void Interactive(InputAction.CallbackContext context)
|
||||
{
|
||||
if (context.interaction is not PressInteraction || !context.performed) return;
|
||||
if (context.interaction is not PressInteraction || !context.performed || cd.AllowUpdate is false) return;
|
||||
var _selected = selected;
|
||||
if (_selected is not MonoBehaviour monoBehaviour) return;
|
||||
if (monoBehaviour.TryGetComponentAny<IAction>(out var action))
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e832535d9d9241a4a8f5ce3ca4bdfe10
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0de6b422fe6534e4c9d6d6cec7812dc1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "BITKit.Entities.Value",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
|
||||
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5a8522cbb18cbd74a847d0fd43c747cb
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,14 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BITKit.Entities.Value
|
||||
{
|
||||
/// <summary>
|
||||
/// 实体属性接口,通常用于角色的可被数值化的属性
|
||||
/// </summary>
|
||||
public interface IEntityValue
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cd3c71baeb6c69642b7e53b45eca93e8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using UnityEngine;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using BITKit.Core.Entites;
|
||||
using Cysharp.Threading.Tasks;
|
||||
|
@ -17,30 +18,62 @@ namespace BITKit.Entities
|
|||
private readonly Processor processor = new();
|
||||
public IEntityComponent[] entityComponents { get; set; }
|
||||
public ulong Id { get; private set; }
|
||||
public CancellationToken CancellationToken => _cancellationToken;
|
||||
|
||||
Core.Entites.IEntityComponent[] Core.Entites.IEntity.Components => _components;
|
||||
|
||||
bool Core.Entites.IEntity.RegisterComponent<T>(T component)
|
||||
{
|
||||
throw new InvalidOperationException("Unity Entity can't register component");
|
||||
}
|
||||
|
||||
IServiceProvider Core.Entites.IEntity.ServiceProvider=> throw new InvalidOperationException("Unity Entity can't register component");
|
||||
|
||||
private CancellationToken _cancellationToken;
|
||||
private bool isInitialized;
|
||||
private Core.Entites.IEntityComponent[] _components => entityComponents;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Id = (ulong)Guid.NewGuid().GetHashCode();
|
||||
_cancellationToken = gameObject.GetCancellationTokenOnDestroy();
|
||||
Set(_cancellationToken);
|
||||
foreach (var serviceRegister in GetComponentsInChildren<IServiceRegister>(true))
|
||||
{
|
||||
genericEvent.Set(serviceRegister.BaseType, serviceRegister);
|
||||
}
|
||||
entityComponents = GetComponentsInChildren<IEntityComponent>(true).Distinct().ToArray();
|
||||
foreach (var x in entityComponents)
|
||||
{
|
||||
foreach (var att in x.GetType().GetCustomAttributes<CustomTypeAttribute>())
|
||||
{
|
||||
genericEvent.Set(att.Type, x);
|
||||
}
|
||||
}
|
||||
entityComponents.ForEach(x => x.Initialize(this));
|
||||
|
||||
UnityEntitiesService.Register(this);
|
||||
}
|
||||
private void Start()
|
||||
{
|
||||
foreach (var x in entityComponents)
|
||||
{
|
||||
foreach (var att in x.GetType().GetCustomAttributes<CustomTypeAttribute>())
|
||||
{
|
||||
genericEvent.Set(att.Type,x);
|
||||
genericEvent.Set(att.Type.FullName, x);
|
||||
genericEvent.SetDirect(att.Type.FullName,x);
|
||||
}
|
||||
}
|
||||
foreach (var x in GetComponentsInChildren<MonoBehaviour>(true))
|
||||
{
|
||||
foreach (var fieldInfo in x
|
||||
.GetType()
|
||||
.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
|
||||
.Where(fieldInfo=>fieldInfo.GetCustomAttribute<InjectAttribute>() is not null))
|
||||
{
|
||||
var type = fieldInfo.FieldType;
|
||||
if(genericEvent.TryGetObjectDirect(type.FullName,out var value))
|
||||
{
|
||||
fieldInfo.SetValue(x,value);
|
||||
}
|
||||
else
|
||||
{
|
||||
BIT4Log.Warning<Entity>($"{name}未找到{type.FullName}");
|
||||
BIT4Log.Warning<Entity>(genericEvent.GetDiagnostics());
|
||||
}
|
||||
}
|
||||
}
|
||||
entityComponents.ForEach(x => x.Initialize(this));
|
||||
|
||||
entityComponents.ForEach(x => x.OnAwake());
|
||||
entityComponents.ForEach(x => x.OnStart());
|
||||
isInitialized = true;
|
||||
|
|
|
@ -41,22 +41,22 @@ public class UnityEntitiesServiceSingleton:IEntitiesService
|
|||
|
||||
public IEntity Get(ulong id) => UnityEntitiesService.Get(id);
|
||||
|
||||
public IEntity[] Query<T>() where T : IEntityComponent
|
||||
public IEntity[] Query<T>()
|
||||
{
|
||||
return UnityEntitiesService.Query<T>();
|
||||
}
|
||||
|
||||
public T[] QueryComponents<T>() where T : IEntityComponent
|
||||
public T[] QueryComponents<T>()
|
||||
{
|
||||
return UnityEntitiesService.QueryComponents<T>();
|
||||
}
|
||||
|
||||
public (T, T1)[] QueryComponents<T, T1>() where T : IEntityComponent where T1 : IEntityComponent
|
||||
public (T, T1)[] QueryComponents<T, T1>()
|
||||
{
|
||||
return UnityEntitiesService.QueryComponents<T, T1>();
|
||||
}
|
||||
|
||||
public (T, T1, T2)[] QueryComponents<T, T1, T2>() where T : IEntityComponent where T1 : IEntityComponent where T2 : IEntityComponent
|
||||
public (T, T1, T2)[] QueryComponents<T, T1, T2>()
|
||||
{
|
||||
return UnityEntitiesService.QueryComponents<T, T1, T2>();
|
||||
}
|
||||
|
@ -64,13 +64,12 @@ public class UnityEntitiesServiceSingleton:IEntitiesService
|
|||
|
||||
public class UnityEntitiesService : MonoBehaviour,IEntitiesService
|
||||
{
|
||||
[RuntimeInitializeOnLoadMethod]
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
||||
private static void Initialize()
|
||||
{
|
||||
Dictionary.Clear();
|
||||
RegisterQueue.Clear();
|
||||
UnRegisterQueue.Clear();
|
||||
|
||||
}
|
||||
public static bool Register(IEntity entity)
|
||||
{
|
||||
|
@ -127,12 +126,12 @@ public class UnityEntitiesService : MonoBehaviour,IEntitiesService
|
|||
public static IEntity Get(ulong id)=>Dictionary[id];
|
||||
IEntity IEntitiesService.Get(ulong id)=>Get(id);
|
||||
IEntity[] IEntitiesService.Query<T>()=>Query<T>();
|
||||
public static IEntity[] Query<T>() where T : IEntityComponent
|
||||
public static IEntity[] Query<T>()
|
||||
{
|
||||
return Entities.Where(x => ((Entity)x).TryGetComponentAny<T>(out _)).ToArray();
|
||||
}
|
||||
T[] IEntitiesService.QueryComponents<T>()=>QueryComponents<T>();
|
||||
public static T[] QueryComponents<T>() where T : IEntityComponent
|
||||
public static T[] QueryComponents<T>()
|
||||
{
|
||||
var list = ListPool<T>.Get();
|
||||
foreach (var iEntity in Entities)
|
||||
|
@ -150,7 +149,7 @@ public class UnityEntitiesService : MonoBehaviour,IEntitiesService
|
|||
return value;
|
||||
}
|
||||
(T, T1)[] IEntitiesService.QueryComponents<T,T1>()=>QueryComponents<T,T1>();
|
||||
public static (T, T1)[] QueryComponents<T, T1>() where T : IEntityComponent where T1 : IEntityComponent
|
||||
public static (T, T1)[] QueryComponents<T, T1>()
|
||||
{
|
||||
var list = ListPool<(T t, T1 t1)>.Get();
|
||||
foreach (var iEntity in Entities)
|
||||
|
@ -168,7 +167,7 @@ public class UnityEntitiesService : MonoBehaviour,IEntitiesService
|
|||
return value;
|
||||
}
|
||||
(T, T1, T2)[] IEntitiesService.QueryComponents<T,T1,T2>()=>QueryComponents<T,T1,T2>();
|
||||
public static (T, T1, T2)[] QueryComponents<T, T1, T2>() where T : IEntityComponent where T1 : IEntityComponent where T2 : IEntityComponent
|
||||
public static (T, T1, T2)[] QueryComponents<T, T1, T2>()
|
||||
{
|
||||
var list = ListPool<(T t, T1 t1, T2 t2)>.Get();
|
||||
foreach (var iEntity in Entities)
|
||||
|
|
|
@ -25,7 +25,6 @@ namespace BITKit.Entities.Editor
|
|||
rootVisualElement.styleSheets.Add(BITEditorUtils.InspectorStyleSheet);
|
||||
rootVisualElement.styleSheets.Add(BITEditorUtils.Style);
|
||||
rootVisualElement.AddToClassList("pa-8");
|
||||
|
||||
}
|
||||
|
||||
private void Update()
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
{
|
||||
"name": "BITFALL.Entities.EquipSelector.Runtime",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
|
||||
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0",
|
||||
"GUID:b355af20142c0c541ba9588ab1d0f64e",
|
||||
"GUID:75469ad4d38634e559750d17036d5f7c",
|
||||
"GUID:30cdc242b1ac6a944a460f4ab0b77b88",
|
||||
"GUID:677cd05ca06c46b4395470200b1acdad",
|
||||
"GUID:7efac18f239530141802fb139776f333",
|
||||
"GUID:84d565da37ad40546a118cfb3c3509f3",
|
||||
"GUID:42a9827d94e00374aa52e51f0a1b035c",
|
||||
"GUID:d525ad6bd40672747bde77962f1c401e",
|
||||
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
|
||||
"GUID:9354affc93e0f3e4a904785e7d4c0f59"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
|
@ -1,164 +0,0 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using BITKit;
|
||||
using BITKit.Entities;
|
||||
using UnityEngine.InputSystem;
|
||||
using static UnityEditor.Progress;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using BITKit.Entities.Player;
|
||||
using UnityEngine.InputSystem.Interactions;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
namespace BITFALL
|
||||
{
|
||||
[CustomType(typeof(IPlayerEquipSelector))]
|
||||
public class PlayerEquipSelector : EntityComponent,TaskSubscriber<IBasicItem>,IEntityInventoryCallback,IPlayerEquipSelector
|
||||
{
|
||||
[Header(Constant.Header.Components)]
|
||||
public EntityEquipment equipment;
|
||||
|
||||
[Header(Constant.Header.InternalVariables)]
|
||||
private readonly Dictionary<int, IBasicItem> equips=new();
|
||||
private IBasicItemContainer inventory;
|
||||
|
||||
public event Action<IBasicItem> OnEquip;
|
||||
public event Action<IBasicItem> OnDeEquip;
|
||||
public event Action<IDictionary<int, IBasicItem>> OnUpdateEquip;
|
||||
|
||||
private IBasicItem currentEquip;
|
||||
public override void OnAwake()
|
||||
{
|
||||
var health = entity.Get<IHealth>();
|
||||
health.OnSetAlive += OnSetAlive;
|
||||
OnDeEquip += DeEquip;
|
||||
OnEquip += Equip;
|
||||
}
|
||||
public override void OnStart()
|
||||
{
|
||||
base.OnStart();
|
||||
|
||||
entity.RegisterCallback<TaskSubscriber<IBasicItem>>(this);
|
||||
|
||||
inventory = entity.Get<IBasicItemContainer>();
|
||||
}
|
||||
public void OnPrimary(InputAction.CallbackContext context)
|
||||
{
|
||||
if (context is not {interaction:PressInteraction ,performed:true}) return;
|
||||
Equip(1);
|
||||
}
|
||||
public void OnSecondary(InputAction.CallbackContext context)
|
||||
{
|
||||
if (context is not {interaction:PressInteraction ,performed:true}) return;
|
||||
Equip(2);
|
||||
}
|
||||
public void OnTertiary(InputAction.CallbackContext context)
|
||||
{
|
||||
if (context is not {interaction:PressInteraction ,performed:true}) return;
|
||||
if (Equip(3) is false)
|
||||
{
|
||||
Equip(-1);
|
||||
}
|
||||
}
|
||||
public void OnQuaternary(InputAction.CallbackContext context)
|
||||
{
|
||||
if (context is not {interaction:PressInteraction ,performed:true}) return;
|
||||
Equip(4);
|
||||
}
|
||||
public void OnHolster(InputAction.CallbackContext context)
|
||||
{
|
||||
if (context is not {interaction:PressInteraction ,performed:true}) return;
|
||||
Equip(-1);
|
||||
}
|
||||
private void OnSetAlive(bool alive)
|
||||
{
|
||||
if (alive) return;
|
||||
foreach (var x in equips.ToArray())
|
||||
{
|
||||
inventory.Add(x.Value);
|
||||
}
|
||||
equips.Clear();
|
||||
UpdateEquip();
|
||||
Equip(-1);
|
||||
}
|
||||
int TaskSubscriber<IBasicItem>.Priority => 0;
|
||||
|
||||
bool TaskSubscriber<IBasicItem>.TryExecute(IBasicItem value)
|
||||
{
|
||||
var asset = value.GetAssetable();
|
||||
if (IsSupportItem(value) is false) return false;
|
||||
switch (asset)
|
||||
{
|
||||
case var _ when asset.TryGetProperty<EquipmentAsWeapon>(out _):
|
||||
if (equips.TryAdd(1, value) || equips.TryAdd(2,value))
|
||||
{
|
||||
OnEquip?.Invoke(value);
|
||||
UpdateEquip();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public void OnAdd(IBasicItem item)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnRemove(IBasicItem item)
|
||||
{
|
||||
if (IsSupportItem(item) is false)
|
||||
{
|
||||
UpdateEquip();
|
||||
}
|
||||
}
|
||||
private bool IsSupportItem(IBasicItem item)
|
||||
{
|
||||
return equipment.equips.list.Any(x => x.AddressablePath == item.AddressablePath);
|
||||
}
|
||||
private void UpdateEquip()
|
||||
{
|
||||
OnUpdateEquip?.Invoke(new Dictionary<int, IBasicItem>(equips));
|
||||
}
|
||||
|
||||
public bool TryDeEquip(IBasicItem item)
|
||||
{
|
||||
if (item is null) return false;
|
||||
if (equips.Any(x => x.Value.AddressablePath == item.AddressablePath) is false) return false;
|
||||
var index = equips.Single(x=>x.Value.AddressablePath==item.AddressablePath).Key;
|
||||
if (equips.TryRemove(index) is false) return false;
|
||||
if (!inventory.Add(item)) return false;
|
||||
OnDeEquip?.Invoke(item);
|
||||
UpdateEquip();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void Equip(IBasicItem item)
|
||||
{
|
||||
if (item is null)
|
||||
{
|
||||
equipment.equips.Entry(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
equipment.equips.Entry(x=>x.AddressablePath == item.AddressablePath);
|
||||
}
|
||||
}
|
||||
|
||||
private bool Equip(int index)
|
||||
{
|
||||
if (!equips.TryGetValue(index, out var x) && index is not -1) return false;
|
||||
if (index is -1)
|
||||
{
|
||||
OnEquip?.Invoke(x);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private void DeEquip(IBasicItem item)
|
||||
{
|
||||
equipment.equips.Entry(-1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4718485b2b78cbb4b8e3cd04c04ba6f8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,163 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Newtonsoft.Json;
|
||||
using UnityEditor.UIElements;
|
||||
#if UNITY_EDITOR
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEditor;
|
||||
#endif
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace BITKit.Events
|
||||
{
|
||||
[Serializable]
|
||||
public class UnityEventData
|
||||
{
|
||||
public Object Target;
|
||||
public string MethodName;
|
||||
}
|
||||
[Serializable]
|
||||
public class UnityEvent
|
||||
{
|
||||
public List<UnityEventData> Targets = new List<UnityEventData>();
|
||||
|
||||
public void Invoke(params object[] objects)
|
||||
{
|
||||
foreach (var x in Targets)
|
||||
{
|
||||
var method =x.Target.GetType().GetMethod(x.MethodName);
|
||||
try
|
||||
{
|
||||
method?.Invoke(x.Target, objects);
|
||||
}
|
||||
catch (TargetParameterCountException e)
|
||||
{
|
||||
Debug.LogWarning(string.Join(",",method?.GetParameters().Select(x=>x.Name)));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
[CustomPropertyDrawer(typeof(UnityEvent))]
|
||||
public class UnityEventDataPropertyDrawer:PropertyDrawer
|
||||
{
|
||||
private VisualElement root;
|
||||
|
||||
private UnityEvent agent;
|
||||
|
||||
private SerializedProperty _property;
|
||||
|
||||
private static readonly List<string> _unityMethodNames = typeof(MonoBehaviour).GetMethods().Select(x => x.Name).ToList();
|
||||
public override VisualElement CreatePropertyGUI(SerializedProperty property)
|
||||
{
|
||||
_property = property;
|
||||
agent = property.Get<UnityEvent>();
|
||||
|
||||
root = new VisualElement
|
||||
{
|
||||
style =
|
||||
{
|
||||
paddingLeft = 10,
|
||||
paddingTop = 10,
|
||||
paddingRight = 10,
|
||||
paddingBottom = 10,
|
||||
}
|
||||
};
|
||||
|
||||
root.styleSheets.Add(BITEditorUtils.InspectorStyleSheet);
|
||||
|
||||
Update();
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
root.Clear();
|
||||
|
||||
var targets = _property.FindPropertyRelative(nameof(UnityEvent.Targets));
|
||||
|
||||
_property.serializedObject.Update();
|
||||
|
||||
var label = root.Create<Label>();
|
||||
|
||||
label.text = _property.displayName;
|
||||
|
||||
var flex = root.Create<VisualElement>();
|
||||
|
||||
flex.style.flexDirection = FlexDirection.Row;
|
||||
|
||||
var containers = new[] { flex.Create<VisualElement>(), flex.Create<VisualElement>(),flex.Create<VisualElement>() };
|
||||
|
||||
containers[1].style.flexGrow = 1;
|
||||
|
||||
for (var i = 0; i < targets.arraySize; i++)
|
||||
{
|
||||
var x = agent.Targets[i];
|
||||
|
||||
var objectField = containers[0].Create<ObjectField>();
|
||||
var field = containers[1].Create<DropdownField>();
|
||||
var removeButton = containers[2].Create<Button>();
|
||||
|
||||
|
||||
var data = targets.GetArrayElementAtIndex(i);
|
||||
var target = data.FindPropertyRelative(nameof(UnityEventData.Target));
|
||||
|
||||
objectField.BindProperty(target);
|
||||
|
||||
if (x.Target is not null)
|
||||
{
|
||||
field.choices = x.Target
|
||||
.GetType()
|
||||
.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
|
||||
.Where(x=>x.IsSpecialName is false)
|
||||
.Where(x=>x.GetCustomAttribute<ObsoleteAttribute>() is null)
|
||||
.Select(x => x.Name)
|
||||
//.Where(x=>_unityMethodNames.Contains(x) is false)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
|
||||
field.RegisterValueChangedCallback(changeEvent =>
|
||||
{
|
||||
x.MethodName = changeEvent.newValue;
|
||||
EditorUtility.SetDirty(_property.serializedObject.targetObject);
|
||||
});
|
||||
|
||||
field.value = x.MethodName;
|
||||
|
||||
field.style.flexGrow = 1;
|
||||
|
||||
removeButton.text = "X";
|
||||
removeButton.clicked+=()=>{
|
||||
agent.Targets.Remove(x);
|
||||
Update();
|
||||
};
|
||||
}
|
||||
|
||||
var addButton = root.Create<Button>();
|
||||
|
||||
addButton.text = "Add";
|
||||
|
||||
addButton.clicked += () =>
|
||||
{
|
||||
agent.Targets.Add(new());
|
||||
Update();
|
||||
};
|
||||
|
||||
var invokeButton = root.Create<Button>();
|
||||
invokeButton.text = "Invoke";
|
||||
invokeButton.clicked +=()=> agent.Invoke();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 037e8fe9dc2ba9f438112d7a8c3160cb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue