add kcp
This commit is contained in:
parent
ebf9c1f526
commit
2c4710bc5d
|
@ -15,39 +15,17 @@
|
||||||
<Compile Remove="Packages\Tests\**" />
|
<Compile Remove="Packages\Tests\**" />
|
||||||
<Compile Remove="Packages\Runtime~\Unity\**" />
|
<Compile Remove="Packages\Runtime~\Unity\**" />
|
||||||
<Compile Remove="Packages\Runtime~\UnityPluginsSupport\**" />
|
<Compile Remove="Packages\Runtime~\UnityPluginsSupport\**" />
|
||||||
|
<Compile Remove="Src\Unity\**" />
|
||||||
|
<Compile Remove="Src\UnityPluginsSupport\**" />
|
||||||
</ItemGroup>
|
</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>
|
<ItemGroup>
|
||||||
<None Remove="Packages\Common~\**" />
|
<!-- 排除Unity文件 -->
|
||||||
<None Remove="Packages\Editor\**" />
|
<None Remove="**\*.meta"/>
|
||||||
<None Remove="Packages\Runtime\**" />
|
<None Remove="**\*.asmdef"/>
|
||||||
<None Remove="Packages\Core\Assets\**" />
|
<None Remove="Src\Unity\**" />
|
||||||
<None Remove="Packages\Core\Cache\**" />
|
<None Remove="Src\UnityPluginsSupport\**" />
|
||||||
<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" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -57,16 +35,33 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<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.Configuration" Version="7.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0-preview.4.23259.5" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
|
||||||
<PackageReference Include="MySql.EntityFrameworkCore" Version="6.0.13" />
|
<PackageReference Include="MySql.EntityFrameworkCore" Version="6.0.13" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.3-beta1" />
|
<PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.3-beta1" />
|
||||||
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
|
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
|
||||||
<PackageReference Include="UniTask" Version="2.3.3" />
|
<PackageReference Include="UniTask" Version="2.3.3" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Remove="Src\Unity\**" />
|
||||||
|
<EmbeddedResource Remove="Src\UnityPluginsSupport\**" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
],
|
],
|
||||||
"includePlatforms": [],
|
"includePlatforms": [],
|
||||||
"excludePlatforms": [],
|
"excludePlatforms": [],
|
||||||
"allowUnsafeCode": false,
|
"allowUnsafeCode": true,
|
||||||
"overrideReferences": false,
|
"overrideReferences": false,
|
||||||
"precompiledReferences": [],
|
"precompiledReferences": [],
|
||||||
"autoReferenced": true,
|
"autoReferenced": true,
|
||||||
|
|
|
@ -7,6 +7,7 @@ using Cysharp.Threading.Tasks;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
// ReSharper disable StringLiteralTypo
|
||||||
#if NET5_0_OR_GREATER
|
#if NET5_0_OR_GREATER
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
#endif
|
#endif
|
||||||
|
@ -19,6 +20,10 @@ namespace BITKit
|
||||||
}
|
}
|
||||||
public class BITApp
|
public class BITApp
|
||||||
{
|
{
|
||||||
|
public static async UniTask SwitchToMainThread()
|
||||||
|
{
|
||||||
|
await UniTask.SwitchToSynchronizationContext(SynchronizationContext);
|
||||||
|
}
|
||||||
public static class Time
|
public static class Time
|
||||||
{
|
{
|
||||||
public static float DeltaTime { get; internal set; }
|
public static float DeltaTime { get; internal set; }
|
||||||
|
@ -59,7 +64,89 @@ namespace BITKit
|
||||||
"TextCopy",
|
"TextCopy",
|
||||||
"Blazored",
|
"Blazored",
|
||||||
"TextCopy",
|
"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
|
#if NET5_0_OR_GREATER
|
||||||
|
@ -144,7 +231,8 @@ namespace BITKit
|
||||||
public static InitializationState State;
|
public static InitializationState State;
|
||||||
public static Assembly[] Assemblies;
|
public static Assembly[] Assemblies;
|
||||||
public static AppSettings Settings { get; protected set; }
|
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.TimeAsDouble = 0;
|
||||||
Time.DeltaTime = 1 / 60f;
|
Time.DeltaTime = 1 / 60f;
|
||||||
|
@ -153,7 +241,7 @@ namespace BITKit
|
||||||
CancellationTokenSource = new CancellationTokenSource();
|
CancellationTokenSource = new CancellationTokenSource();
|
||||||
AppName = appName;
|
AppName = appName;
|
||||||
ThreadHelper.LogCurrentThread();
|
ThreadHelper.LogCurrentThread();
|
||||||
|
InitialTime = DateTime.Now;
|
||||||
await Init();
|
await Init();
|
||||||
}
|
}
|
||||||
private static async Task Init()
|
private static async Task Init()
|
||||||
|
@ -182,10 +270,16 @@ namespace BITKit
|
||||||
reflectionHelperWatch.Start();
|
reflectionHelperWatch.Start();
|
||||||
await ReflectionHelper.Init();
|
await ReflectionHelper.Init();
|
||||||
reflectionHelperWatch.Stop();
|
reflectionHelperWatch.Stop();
|
||||||
|
|
||||||
|
Stopwatch commandWatch = new();
|
||||||
|
await BITCommands.InitializeAsync();
|
||||||
|
commandWatch.Stop();
|
||||||
|
|
||||||
|
|
||||||
stopwatch.Stop();
|
stopwatch.Stop();
|
||||||
State = InitializationState.Initialized;
|
State = InitializationState.Initialized;
|
||||||
BIT4Log.Log<BITApp>($"已完成初始化,耗时:{stopwatch.ElapsedMilliseconds}ms");
|
BIT4Log.Log<BITApp>($"已完成初始化,耗时:{stopwatch.ElapsedMilliseconds}ms");
|
||||||
|
BIT4Log.Log<BITApp>($"反射初始化耗时:{reflectionHelperWatch.ElapsedMilliseconds}ms");
|
||||||
}
|
}
|
||||||
catch (System.Exception e)
|
catch (System.Exception e)
|
||||||
{
|
{
|
||||||
|
@ -196,11 +290,18 @@ namespace BITKit
|
||||||
}
|
}
|
||||||
public static void Stop()
|
public static void Stop()
|
||||||
{
|
{
|
||||||
|
var runTime = DateTime.Now - InitialTime;
|
||||||
|
|
||||||
BIT4Log.Log<BITApp>($"正在停止{nameof(BITApp)}");
|
BIT4Log.Log<BITApp>($"正在停止{nameof(BITApp)}");
|
||||||
CancellationTokenSource.Cancel();
|
CancellationTokenSource.Cancel();
|
||||||
State = InitializationState.None;
|
State = InitializationState.None;
|
||||||
|
|
||||||
|
BITCommands.Dispose();
|
||||||
|
|
||||||
BIT4Log.Log<BITApp>($"已停止{nameof(BITApp)}");
|
BIT4Log.Log<BITApp>($"已停止{nameof(BITApp)}");
|
||||||
|
BIT4Log.Log<BITApp>($"运行时间:{runTime}");
|
||||||
BIT4Log.Log<BITApp>("Exit Code:0");
|
BIT4Log.Log<BITApp>("Exit Code:0");
|
||||||
|
|
||||||
}
|
}
|
||||||
public static void Run(string path, string WorkingDirectory = "")
|
public static void Run(string path, string WorkingDirectory = "")
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#if NETCOREAPP
|
#if NETCOREAPP
|
||||||
|
using System;
|
||||||
using Cysharp.Threading.Tasks;
|
using Cysharp.Threading.Tasks;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
|
||||||
namespace BITKit;
|
namespace BITKit;
|
||||||
|
|
||||||
public class BITAppForNet
|
public class BITAppForNet
|
||||||
|
@ -18,7 +18,7 @@ public class BITAppForNet
|
||||||
BIT4Log.OnSetConsoleColor += color => Console.ForegroundColor = color;
|
BIT4Log.OnSetConsoleColor += color => Console.ForegroundColor = color;
|
||||||
BIT4Log.OnNextLine += Console.WriteLine;
|
BIT4Log.OnNextLine += Console.WriteLine;
|
||||||
|
|
||||||
BITApp.Start(name);
|
await BITApp.Start(name);
|
||||||
await BITBinary.Start();
|
await BITBinary.Start();
|
||||||
}
|
}
|
||||||
public static UniTask DisposeAsync()
|
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
|
fileFormatVersion: 2
|
||||||
guid: 647f1c92db6d9b5438a81bdb9bfc11bd
|
guid: ef5795e833a88cd4b8c1485d4b50ebfd
|
||||||
folderAsset: yes
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
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
|
fileFormatVersion: 2
|
||||||
guid: dd4b17361e28d304bbc1dd6d568e9a3c
|
guid: df16dad99b7205a40b655489e7f19076
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
|
@ -1,4 +1,5 @@
|
||||||
#if UNITY
|
#if NET5_0_OR_GREATER
|
||||||
|
#else
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
#endif
|
#endif
|
||||||
using System;
|
using System;
|
||||||
|
@ -6,7 +7,9 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Cysharp.Threading.Tasks;
|
using Cysharp.Threading.Tasks;
|
||||||
|
#if NET5_0_OR_GREATER
|
||||||
using Microsoft.SqlServer.Server;
|
using Microsoft.SqlServer.Server;
|
||||||
|
#endif
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace BITKit
|
namespace BITKit
|
||||||
|
@ -14,27 +17,37 @@ namespace BITKit
|
||||||
public class BITBinary
|
public class BITBinary
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<string, INetMessageReader> netReaders = new();
|
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()
|
public static async UniTask Start()
|
||||||
{
|
{
|
||||||
netReaders.Clear();
|
netReaders.Clear();
|
||||||
|
#if NET5_0_OR_GREATER
|
||||||
serializableTypes.Clear();
|
serializableTypes.Clear();
|
||||||
|
#endif
|
||||||
foreach (var x in await ReflectionHelper.GetInstances<INetMessageReader>())
|
foreach (var x in await ReflectionHelper.GetInstances<INetMessageReader>())
|
||||||
{
|
{
|
||||||
var typeName = x.GetMessageType().FullName;
|
var typeName = x.GetMessageType().FullName;
|
||||||
|
if (typeName == null) continue;
|
||||||
netReaders.Add(typeName, x);
|
netReaders.Add(typeName, x);
|
||||||
BIT4Log.Log<BITBinary>($"已注册类型:{typeName}");
|
BIT4Log.Log<BITBinary>($"已注册类型:{typeName}");
|
||||||
}
|
}
|
||||||
|
#if NET5_0_OR_GREATER
|
||||||
var serializes = await ReflectionHelper.GetInstances<IBinarySerialize>();
|
var serializes = await ReflectionHelper.GetInstances<IBinarySerialize>();
|
||||||
#if UNITY
|
|
||||||
serializes = serializes.Where(x => x is not UnityEngine.Object);
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
foreach (var x in serializes)
|
// #if NET5_0_OR_GREATER
|
||||||
{
|
// #else
|
||||||
serializableTypes.Add(x.GetType());
|
// serializes = serializes.Where(x => x is not UnityEngine.Object);
|
||||||
BIT4Log.Log<BITBinary>($"已注册类型:{x.GetType().FullName}");
|
// #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);
|
public static object Read<T>(byte[] buffer) => (T)ReadAsValue(buffer);
|
||||||
|
@ -60,26 +73,22 @@ namespace BITKit
|
||||||
|
|
||||||
var typeName = reader.ReadString();
|
var typeName = reader.ReadString();
|
||||||
if (netReaders.TryGetValue(typeName, out var netReader))
|
if (netReaders.TryGetValue(typeName, out var netReader))
|
||||||
{
|
|
||||||
return netReader.ReadBinaryAsObject(reader);
|
return netReader.ReadBinaryAsObject(reader);
|
||||||
}
|
|
||||||
var json = reader.ReadString();
|
var json = reader.ReadString();
|
||||||
json = reader.ReadString();
|
if (string.IsNullOrEmpty(json))
|
||||||
|
{
|
||||||
|
throw new Exception($"从二进制中读取的json值为空");
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
if (BITSharp.TryGetTypeFromFullName(typeName, out var type))
|
if (BITSharp.TryGetTypeFromFullName(typeName, out var type))
|
||||||
{
|
|
||||||
return JsonConvert.DeserializeObject(json, type);
|
return JsonConvert.DeserializeObject(json, type);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
BIT4Log.Warning<BITBinary>($"反序列化失败,类型:{typeName},值:\n{json}");
|
BIT4Log.Warning<BITBinary>($"反序列化失败,类型:{typeName},值:\n{json}");
|
||||||
throw;
|
BIT4Log.LogException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
throw new Exception("未找到读取该二进制的BinaryReader");
|
throw new Exception("未找到读取该二进制的BinaryReader");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,14 +128,8 @@ namespace BITKit
|
||||||
{
|
{
|
||||||
netReader.WriteBinaryAsObject(writer,value);
|
netReader.WriteBinaryAsObject(writer,value);
|
||||||
}
|
}
|
||||||
else if( value is IBinarySerialize serialize)
|
|
||||||
{
|
|
||||||
serialize.Write(writer);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//throw new Exception($"没有找到{value.GetType().Name}的Binary写入方法");
|
|
||||||
writer.Write(value!.GetType().FullName!);
|
|
||||||
writer.Write(JsonConvert.SerializeObject(value));
|
writer.Write(JsonConvert.SerializeObject(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,10 +142,12 @@ namespace BITKit
|
||||||
{
|
{
|
||||||
return true;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,19 @@ namespace BITKit
|
||||||
}
|
}
|
||||||
public static async void Excute(string cmd)
|
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 UniTask.SwitchToThreadPool();
|
||||||
await TaskHelper.WaitUntil(() => state is InitializationState.Initialized);
|
await TaskHelper.WaitUntil(() => state is InitializationState.Initialized);
|
||||||
var split = cmd.Split(" ").ToList();
|
var split = cmd.Split(" ").ToList();
|
||||||
|
@ -87,27 +100,24 @@ namespace BITKit
|
||||||
}
|
}
|
||||||
static Dictionary<string, MethodInfo> methodInfos = new();
|
static Dictionary<string, MethodInfo> methodInfos = new();
|
||||||
static InitializationState state;
|
static InitializationState state;
|
||||||
[ExcuteOnStart]
|
public static async UniTask InitializeAsync()
|
||||||
public static void Start()
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Init();
|
await Init();
|
||||||
}
|
}
|
||||||
catch (System.Exception e)
|
catch (System.Exception e)
|
||||||
{
|
{
|
||||||
|
|
||||||
BIT4Log.LogException(e);
|
BIT4Log.LogException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
[ExcuteOnStop]
|
public static void Dispose()
|
||||||
public static void Stop()
|
|
||||||
{
|
{
|
||||||
state = 0;
|
state = 0;
|
||||||
methodInfos.Clear();
|
methodInfos.Clear();
|
||||||
}
|
}
|
||||||
static async void Init()
|
private static async UniTask Init()
|
||||||
{
|
{
|
||||||
state = InitializationState.Initializing;
|
state = InitializationState.Initializing;
|
||||||
await UniTask.SwitchToThreadPool();
|
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
|
fileFormatVersion: 2
|
||||||
guid: 259562ab3c5f28243819c92d2db08104
|
guid: d015706f3749b334ab81c82b23a1575a
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
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
|
fileFormatVersion: 2
|
||||||
guid: 3db000849b712bf4ea543570c2ea0f43
|
guid: e6da82a831307d145bac6bdf73a852c9
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
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
|
namespace BITKit
|
||||||
{
|
{
|
||||||
public interface IServiceRegister
|
|
||||||
{
|
|
||||||
Type BaseType { get; }
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -3,7 +3,10 @@ using System.Collections.Generic;
|
||||||
|
|
||||||
namespace BITKit
|
namespace BITKit
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 双缓冲区
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
public interface IDoubleBuffer<T>
|
public interface IDoubleBuffer<T>
|
||||||
{
|
{
|
||||||
T Current { get; }
|
T Current { get; }
|
||||||
|
@ -11,7 +14,10 @@ namespace BITKit
|
||||||
event Action<T> OnRelease;
|
event Action<T> OnRelease;
|
||||||
bool TryGetRelease(out T result);
|
bool TryGetRelease(out T result);
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// <see cref="IDoubleBuffer{T}"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
public class DoubleBuffer<T> : IDoubleBuffer<T>
|
public class DoubleBuffer<T> : IDoubleBuffer<T>
|
||||||
{
|
{
|
||||||
public T Current
|
public T Current
|
||||||
|
@ -25,14 +31,18 @@ namespace BITKit
|
||||||
{
|
{
|
||||||
Current = newValue;
|
Current = newValue;
|
||||||
OnRelease?.Invoke(newValue);
|
OnRelease?.Invoke(newValue);
|
||||||
|
_release.SetValueThenAllow(newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public event Action<T> OnRelease;
|
public event Action<T> OnRelease;
|
||||||
private readonly Queue<T> _releases = new();
|
private readonly Optional<T> _release=new();
|
||||||
|
|
||||||
public bool TryGetRelease(out T result)
|
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.Threading;
|
||||||
using System;
|
using System;
|
||||||
|
using System.ComponentModel.Design;
|
||||||
|
#if NET5_0_OR_GREATER
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
#endif
|
||||||
namespace BITKit.Core.Entites
|
namespace BITKit.Core.Entites
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -8,14 +12,11 @@ namespace BITKit.Core.Entites
|
||||||
public interface IEntity
|
public interface IEntity
|
||||||
{
|
{
|
||||||
ulong Id { get; }
|
ulong Id { get; }
|
||||||
#if NET5_0_OR_GREATER
|
CancellationToken CancellationToken { get; }
|
||||||
bool TryGetComponent<T>(out T component) where T : IEntityComponent;
|
bool TryGetComponent<T>(out T component);
|
||||||
IEntityComponent[] Components { get; }
|
IEntityComponent[] Components { get; }
|
||||||
bool RegisterComponent<T>(T component) where T : IEntityComponent;
|
bool RegisterComponent<T>(T component);
|
||||||
#else
|
IServiceProvider ServiceProvider { get; }
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 基本实体组件
|
/// 基本实体组件
|
||||||
|
@ -24,6 +25,9 @@ namespace BITKit.Core.Entites
|
||||||
{
|
{
|
||||||
Type BaseType { get; }
|
Type BaseType { get; }
|
||||||
IEntity Entity { get; set; }
|
IEntity Entity { get; set; }
|
||||||
|
#if NET5_0_OR_GREATER
|
||||||
|
void BuildService(IServiceCollection serviceCollection);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 基本实体服务
|
/// 基本实体服务
|
||||||
|
@ -61,24 +65,28 @@ namespace BITKit.Core.Entites
|
||||||
/// <param name="id"></param>
|
/// <param name="id"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
IEntity Get(ulong id);
|
IEntity Get(ulong id);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查询Entity,例如
|
/// 查询Entity,例如
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <para>var rotationEntities=EntitiesService.Query<RotationComponent></para>
|
/// <para>var rotationEntities=EntitiesService.Query<RotationComponent></para>
|
||||||
IEntity[] Query<T>() where T : IEntityComponent;
|
IEntity[] Query<T>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查询1个组件
|
/// 查询1个组件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
T[] QueryComponents<T>() where T : IEntityComponent;
|
T[] QueryComponents<T>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查询2个组件
|
/// 查询2个组件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <typeparam name="T1"></typeparam>
|
/// <typeparam name="T1"></typeparam>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
ValueTuple<T,T1>[] QueryComponents<T,T1>()where T : IEntityComponent where T1 : IEntityComponent;
|
ValueTuple<T, T1>[] QueryComponents<T, T1>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查询3个组件
|
/// 查询3个组件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -86,7 +94,7 @@ namespace BITKit.Core.Entites
|
||||||
/// <typeparam name="T1"></typeparam>
|
/// <typeparam name="T1"></typeparam>
|
||||||
/// <typeparam name="T2"></typeparam>
|
/// <typeparam name="T2"></typeparam>
|
||||||
/// <returns></returns>
|
/// <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
|
fileFormatVersion: 2
|
||||||
guid: ebbaf967274f9c942bcbfccbea097f28
|
guid: 8372b15121bd7e4408788d269d22fc20
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
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>
|
/// </summary>
|
||||||
event Action<string> OnDownloadComplete;
|
event Action<string> OnDownloadComplete;
|
||||||
|
|
||||||
|
event Action OnDetectedLatestVersion;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 下载最新版本
|
/// 下载最新版本
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
using Cysharp.Threading.Tasks;
|
using Cysharp.Threading.Tasks;
|
||||||
using kcp2k;
|
using kcp2k;
|
||||||
|
@ -21,6 +22,9 @@ namespace BITKit.Net
|
||||||
public int Ping => -1;
|
public int Ping => -1;
|
||||||
public int Id { get; private set; } = -1;
|
public int Id { get; private set; } = -1;
|
||||||
private readonly KcpClient client;
|
private readonly KcpClient client;
|
||||||
|
|
||||||
|
private readonly Queue<byte[]> commandQueue = new();
|
||||||
|
|
||||||
private readonly Timer _timer = new(100)
|
private readonly Timer _timer = new(100)
|
||||||
{
|
{
|
||||||
AutoReset = true
|
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();
|
client.Tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,8 +117,7 @@ namespace BITKit.Net
|
||||||
case NetCommandType.Command:
|
case NetCommandType.Command:
|
||||||
var command = BITBinary.Read(reader);
|
var command = BITBinary.Read(reader);
|
||||||
if (command is object[] { Length: 1 } objs) command = objs[0];
|
if (command is object[] { Length: 1 } objs) command = objs[0];
|
||||||
// BIT4Log.Log<KcpClient>(
|
//BIT4Log.Log<KcpClient>($"已收到指令:{command},值:\n{JsonConvert.SerializeObject(command, Formatting.Indented)}");
|
||||||
// $"已收到指令:{command},值:\n{JsonConvert.SerializeObject(command, Formatting.Indented)}");
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (BITApp.SynchronizationContext is not null)
|
if (BITApp.SynchronizationContext is not null)
|
||||||
|
@ -128,7 +136,7 @@ namespace BITKit.Net
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case NetCommandType.Heartbeat:
|
case NetCommandType.Heartbeat:
|
||||||
client.Send(new[] { (byte)NetCommandType.Heartbeat }, KcpChannel.Reliable);
|
//client.Send(new[] { (byte)NetCommandType.Heartbeat }, KcpChannel.Reliable);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BIT4Log.Log<KcpClient>($"未知消息类型:{type},字节:{(byte)type}");
|
BIT4Log.Log<KcpClient>($"未知消息类型:{type},字节:{(byte)type}");
|
||||||
|
@ -249,7 +257,8 @@ namespace BITKit.Net
|
||||||
.Write((byte)commandType)
|
.Write((byte)commandType)
|
||||||
.WriteObject(values)
|
.WriteObject(values)
|
||||||
.Build();
|
.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 class KCPNetServer:INetServer,INetProvider
|
||||||
{
|
{
|
||||||
public event Action<int> OnClientConnect;
|
public event Action<int> OnClientConnected;
|
||||||
public event Action<int> OnClientDisconnected;
|
public event Action<int> OnClientDisconnected;
|
||||||
public event Action OnStartServer;
|
public event Action OnStartServer;
|
||||||
public event Action OnStopServer;
|
public event Action OnStopServer;
|
||||||
|
@ -74,6 +74,9 @@ namespace BITKit.Net
|
||||||
new Dictionary<int, EndPoint>(
|
new Dictionary<int, EndPoint>(
|
||||||
server.connections.Select(x => new KeyValuePair<int, EndPoint>(x.Key, x.Value.remoteEndPoint)
|
server.connections.Select(x => new KeyValuePair<int, EndPoint>(x.Key, x.Value.remoteEndPoint)
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void Tick() => server.Tick();
|
public void Tick() => server.Tick();
|
||||||
public void HandShake()
|
public void HandShake()
|
||||||
{
|
{
|
||||||
|
@ -85,7 +88,7 @@ namespace BITKit.Net
|
||||||
|
|
||||||
private void OnConnected(int Id)
|
private void OnConnected(int Id)
|
||||||
{
|
{
|
||||||
OnClientConnect?.Invoke(Id);
|
OnClientConnected?.Invoke(Id);
|
||||||
ClientCommand(Id,new NetClientAllocateIdCommand
|
ClientCommand(Id,new NetClientAllocateIdCommand
|
||||||
{
|
{
|
||||||
Id = Id,
|
Id = Id,
|
||||||
|
@ -105,6 +108,7 @@ namespace BITKit.Net
|
||||||
using var ms = new MemoryStream(bytes.ToArray());
|
using var ms = new MemoryStream(bytes.ToArray());
|
||||||
using var reader = new BinaryReader(ms);
|
using var reader = new BinaryReader(ms);
|
||||||
|
|
||||||
|
BIT4Log.Log<INetServer>(Id);
|
||||||
|
|
||||||
var type = (NetCommandType)ms.ReadByte();
|
var type = (NetCommandType)ms.ReadByte();
|
||||||
switch (type)
|
switch (type)
|
||||||
|
@ -114,9 +118,12 @@ namespace BITKit.Net
|
||||||
break;
|
break;
|
||||||
case NetCommandType.Command:
|
case NetCommandType.Command:
|
||||||
var command = BITBinary.Read(reader);
|
var command = BITBinary.Read(reader);
|
||||||
if (command is object[] objs && objs.Length is 1) command = objs[0];
|
if (command is object[] { Length: 1 } objs) command = objs[0];
|
||||||
//BIT4Log.Log<KCPNetServer>($"已收到指令:{command},值:\n{JsonConvert.SerializeObject(command, Formatting.Indented)}");
|
BIT4Log.Log<KCPNetServer>($"已收到指令:{command},值:\n{JsonConvert.SerializeObject(command, Formatting.Indented)}");
|
||||||
_events.Invoke(command.GetType().FullName, command);
|
_events.Invoke(command.GetType().FullName, command);
|
||||||
|
|
||||||
|
(int Id,object Command) tuple = (Id,command);
|
||||||
|
_events.InvokeDirect(command.GetType().FullName,tuple);
|
||||||
break;
|
break;
|
||||||
case NetCommandType.Heartbeat:
|
case NetCommandType.Heartbeat:
|
||||||
server.Send(Id,new byte[]{(byte)NetCommandType.Heartbeat}, KcpChannel.Reliable);
|
server.Send(Id,new byte[]{(byte)NetCommandType.Heartbeat}, KcpChannel.Reliable);
|
||||||
|
@ -179,6 +186,17 @@ namespace BITKit.Net
|
||||||
{
|
{
|
||||||
_events.AddListener<T>(handle);
|
_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)
|
public void RemoveCommandListener<T>(Action<T> handle)
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,6 +44,19 @@ namespace BITKit
|
||||||
return list;
|
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)
|
public static bool Contains<T>(IEnumerable<T> a, IEnumerable<T> b)
|
||||||
{
|
{
|
||||||
foreach (var x in 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
|
#if NET5_0_OR_GREATER
|
||||||
#else
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
#else
|
||||||
#endif
|
#endif
|
||||||
using System;
|
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>
|
||||||
/// 回调:当客户端连接时
|
/// 回调:当客户端连接时
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action<int> OnClientConnect;
|
public event Action<int> OnClientConnected;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 回调:当客户端断开连接时
|
/// 回调:当客户端断开连接时
|
||||||
|
@ -188,6 +188,13 @@ namespace BITKit
|
||||||
/// 所有已连接的客户端
|
/// 所有已连接的客户端
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IDictionary<int,EndPoint> Connections { get; }
|
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>
|
/// <summary>
|
||||||
/// 基本网络客户端的接口定义,包括了基本客户端的功能
|
/// 基本网络客户端的接口定义,包括了基本客户端的功能
|
||||||
|
|
|
@ -7,11 +7,11 @@
|
||||||
}
|
}
|
||||||
public interface IOptional<T>
|
public interface IOptional<T>
|
||||||
{
|
{
|
||||||
bool Allow { get; }
|
bool Allow { get; set; }
|
||||||
T Value { get; }
|
T Value { get; set; }
|
||||||
}
|
}
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
public record Optional<T> : IOptional<T>
|
public class Optional<T> : IOptional<T>
|
||||||
{
|
{
|
||||||
#if NET5_0_OR_GREATER
|
#if NET5_0_OR_GREATER
|
||||||
bool allow;
|
bool allow;
|
||||||
|
@ -23,8 +23,18 @@
|
||||||
T value;
|
T value;
|
||||||
#endif
|
#endif
|
||||||
public bool Allow { get => allow; set => allow = value;}
|
public bool Allow { get => allow; set => allow = value;}
|
||||||
public T Value { get => value; set => this.value = value; }
|
public T Value
|
||||||
public void SetValueThenAllow(T newValue) => value = newValue;
|
{
|
||||||
|
get => value;
|
||||||
|
set=>this.value=value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetValueThenAllow(T newValue)
|
||||||
|
{
|
||||||
|
value = newValue;
|
||||||
|
allow = true;
|
||||||
|
}
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
Allow = false;
|
Allow = false;
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
namespace BITKit
|
using System;
|
||||||
|
|
||||||
|
namespace BITKit
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 订阅者,发布者下发任务给支持并优先级最高的订阅者
|
/// 订阅者,发布者下发任务给支持并优先级最高的订阅者
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
|
[Obsolete]
|
||||||
public interface TaskSubscriber<in T>
|
public interface TaskSubscriber<in T>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -22,6 +25,7 @@
|
||||||
/// 发布接口,向发布者下发任务
|
/// 发布接口,向发布者下发任务
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
|
[Obsolete("Use Func Instanced",true)]
|
||||||
public interface TaskPublisher<in T>
|
public interface TaskPublisher<in T>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
// ReSharper disable UnassignedGetOnlyAutoProperty
|
||||||
|
|
||||||
namespace BITKit.UX
|
namespace BITKit.UX
|
||||||
{
|
{
|
||||||
|
@ -44,7 +45,7 @@ namespace BITKit.UX
|
||||||
}
|
}
|
||||||
public abstract class UXPanelImplement:IUXPanel
|
public abstract class UXPanelImplement:IUXPanel
|
||||||
{
|
{
|
||||||
private IUXPanel _iuxPanelImplementation1;
|
protected virtual IUXPanel _iuxPanelImplementation1 { get; }
|
||||||
protected abstract IUXPanel _iuxPanelImplementation { get; }
|
protected abstract IUXPanel _iuxPanelImplementation { get; }
|
||||||
public bool IsAnimate => _iuxPanelImplementation.IsAnimate;
|
public bool IsAnimate => _iuxPanelImplementation.IsAnimate;
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace BITKit
|
||||||
public const string Status = "Status";
|
public const string Status = "Status";
|
||||||
public const string State = "State";
|
public const string State = "State";
|
||||||
public const string Settings = "Settings";
|
public const string Settings = "Settings";
|
||||||
|
public const string Services = "Services";
|
||||||
public const string AudioClip = "AudioClip";
|
public const string AudioClip = "AudioClip";
|
||||||
public const string AudioSource = "AudioSource";
|
public const string AudioSource = "AudioSource";
|
||||||
public const string Paths = "Paths";
|
public const string Paths = "Paths";
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
|
||||||
namespace BITKit
|
namespace BITKit
|
||||||
{
|
{
|
||||||
/// <summary>泛型事件,简单的事件接口</summary>
|
/// <summary>泛型事件,简单的事件接口</summary>
|
||||||
|
@ -39,6 +40,12 @@ namespace BITKit
|
||||||
var list = events.Get(key);
|
var list = events.Get(key);
|
||||||
list.Add(action);
|
list.Add(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddListenerDirect(string key, Action<object> action)
|
||||||
|
{
|
||||||
|
events.Get(key).Add(action);
|
||||||
|
}
|
||||||
|
|
||||||
public void Invoke<T>(string key, T value)
|
public void Invoke<T>(string key, T value)
|
||||||
{
|
{
|
||||||
key = key.GetType<T>();
|
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)
|
public void Invoke(string typeName, object value)
|
||||||
{
|
{
|
||||||
var key = $"{typeName}.{defaultEventName}";
|
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>(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<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 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)
|
public void RemoveListener<T>(string key, Action<T> action)
|
||||||
{
|
{
|
||||||
key = key.GetType<T>();
|
key = key.GetType<T>();
|
||||||
|
@ -115,5 +134,10 @@ namespace BITKit
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Invoke<T>() where T : new() => Invoke(new T());
|
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 Get();
|
||||||
string Value => Get();
|
string Value => Get();
|
||||||
|
string Replace(string value) => Get().Replace("{x}",value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IReference<T>
|
public interface IReference<T>
|
||||||
|
@ -37,9 +38,12 @@
|
||||||
{
|
{
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
[UnityEngine.TextArea]
|
||||||
|
#endif
|
||||||
public string value;
|
public string value;
|
||||||
public override string Get() => value;
|
public override string Get() => value;
|
||||||
|
public override string ToString() => value;
|
||||||
}
|
}
|
||||||
|
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
|
|
|
@ -5,17 +5,12 @@ namespace BITKit
|
||||||
{
|
{
|
||||||
public class ValidHandle
|
public class ValidHandle
|
||||||
{
|
{
|
||||||
public ValidHandle() { Init(); }
|
public ValidHandle() {}
|
||||||
public ValidHandle(Action<bool> boolDelegate)
|
public ValidHandle(Action<bool> boolDelegate)
|
||||||
{
|
{
|
||||||
AddListener(boolDelegate);
|
AddListener(boolDelegate);
|
||||||
Init();
|
|
||||||
EventOnEnableChanged?.Invoke(enableHandle);
|
EventOnEnableChanged?.Invoke(enableHandle);
|
||||||
}
|
}
|
||||||
void Init()
|
|
||||||
{
|
|
||||||
AddListener(OnInoke);
|
|
||||||
}
|
|
||||||
public static implicit operator bool(ValidHandle validHandle)
|
public static implicit operator bool(ValidHandle validHandle)
|
||||||
{
|
{
|
||||||
return validHandle.enableHandle;
|
return validHandle.enableHandle;
|
||||||
|
@ -24,8 +19,6 @@ namespace BITKit
|
||||||
public bool Allow => this;
|
public bool Allow => this;
|
||||||
|
|
||||||
private bool enableHandle;
|
private bool enableHandle;
|
||||||
private int enableElementCount;
|
|
||||||
private int disableElementCount;
|
|
||||||
private readonly List<object> objs = new List<object>();
|
private readonly List<object> objs = new List<object>();
|
||||||
private readonly List<object> disableObjs = new List<object>();
|
private readonly List<object> disableObjs = new List<object>();
|
||||||
private bool tempEnable;
|
private bool tempEnable;
|
||||||
|
@ -43,7 +36,7 @@ namespace BITKit
|
||||||
}
|
}
|
||||||
CheckEnable();
|
CheckEnable();
|
||||||
}
|
}
|
||||||
protected virtual void CheckEnable()
|
protected void CheckEnable()
|
||||||
{
|
{
|
||||||
tempEnable = objs.Count > 0 && disableObjs.Count == 0;
|
tempEnable = objs.Count > 0 && disableObjs.Count == 0;
|
||||||
if (tempEnable != enableHandle)
|
if (tempEnable != enableHandle)
|
||||||
|
@ -51,13 +44,8 @@ namespace BITKit
|
||||||
enableHandle = tempEnable;
|
enableHandle = tempEnable;
|
||||||
if (EventOnEnableChanged is not null)
|
if (EventOnEnableChanged is not null)
|
||||||
EventOnEnableChanged.Invoke(enableHandle);
|
EventOnEnableChanged.Invoke(enableHandle);
|
||||||
OnEnable(enableHandle);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
enableElementCount = objs.Count;
|
|
||||||
disableElementCount = disableObjs.Count;
|
|
||||||
}
|
}
|
||||||
protected virtual void OnEnable(bool enable) { }
|
|
||||||
public virtual void RemoveElement(object obj)
|
public virtual void RemoveElement(object obj)
|
||||||
{
|
{
|
||||||
if (objs.Contains(obj))
|
if (objs.Contains(obj))
|
||||||
|
@ -93,7 +81,7 @@ namespace BITKit
|
||||||
}
|
}
|
||||||
CheckEnable();
|
CheckEnable();
|
||||||
}
|
}
|
||||||
public virtual void RemoveDisableElements(object obj)
|
public void RemoveDisableElements(object obj)
|
||||||
{
|
{
|
||||||
if (disableObjs.Contains(obj))
|
if (disableObjs.Contains(obj))
|
||||||
{
|
{
|
||||||
|
@ -104,7 +92,7 @@ namespace BITKit
|
||||||
}
|
}
|
||||||
CheckEnable();
|
CheckEnable();
|
||||||
}
|
}
|
||||||
public virtual void SetElements(object obj, bool add = true)
|
public void SetElements(object obj, bool add = true)
|
||||||
{
|
{
|
||||||
if (add)
|
if (add)
|
||||||
{
|
{
|
||||||
|
@ -126,29 +114,33 @@ namespace BITKit
|
||||||
RemoveDisableElements(obj);
|
RemoveDisableElements(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public virtual void Invoke()
|
public void Invoke()
|
||||||
{
|
{
|
||||||
bool enable = disableObjs.Count == 0 && objs.Count > 0;
|
var enable = disableObjs.Count == 0 && objs.Count > 0;
|
||||||
EventOnEnableChanged.Invoke(enable);
|
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 void AddListener(Action<bool> action)
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
public virtual void AddListener(Action<bool> action)
|
|
||||||
{
|
{
|
||||||
EventOnEnableChanged+= 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)
|
if(EventOnEnableChanged is not null && action is not null)
|
||||||
{
|
{
|
||||||
EventOnEnableChanged -= action;
|
EventOnEnableChanged -= action;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
objs.Clear();
|
||||||
|
disableObjs.Clear();
|
||||||
|
Invoke();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ namespace BITKit
|
||||||
[BITCommand]
|
[BITCommand]
|
||||||
public static void Set(string key, string value)
|
public static void Set(string key, string value)
|
||||||
{
|
{
|
||||||
Data.Set(key, value);
|
|
||||||
if (Guid.TryParse(value, out var guidResult))
|
if (Guid.TryParse(value, out var guidResult))
|
||||||
{
|
{
|
||||||
Data.Set(key, guidResult);
|
Data.Set(key, guidResult);
|
||||||
|
@ -35,6 +34,10 @@ namespace BITKit
|
||||||
{
|
{
|
||||||
Data.Set(key, intResult);
|
Data.Set(key, intResult);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Data.Set(key, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
[BITCommand]
|
[BITCommand]
|
||||||
public static void SetContainer(string key, string typeName, string json)
|
public static void SetContainer(string key, string typeName, string json)
|
||||||
|
|
|
@ -32,6 +32,12 @@ namespace BITKit
|
||||||
|
|
||||||
return GetPath(paths);
|
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)
|
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
|
fileFormatVersion: 2
|
||||||
guid: 715ab799293af1942afd9ce5ef57c99b
|
guid: a3f593891073dfc4c860f7df41ef8e2c
|
||||||
AssemblyDefinitionImporter:
|
AssemblyDefinitionImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
userData:
|
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_UseDynamicScale: 0
|
||||||
m_BindMS: 0
|
m_BindMS: 0
|
||||||
m_EnableCompatibleFormat: 1
|
m_EnableCompatibleFormat: 1
|
||||||
|
m_EnableRandomWrite: 0
|
||||||
m_TextureSettings:
|
m_TextureSettings:
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_FilterMode: 1
|
m_FilterMode: 1
|
||||||
|
|
|
@ -76,7 +76,7 @@ Transform:
|
||||||
m_GameObject: {fileID: 4263150313831602955}
|
m_GameObject: {fileID: 4263150313831602955}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: -0, y: 0.99025595, z: -0.1392595, w: 0}
|
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_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children:
|
m_Children:
|
||||||
|
@ -255,7 +255,7 @@ MonoBehaviour:
|
||||||
m_RotationOrder: 4
|
m_RotationOrder: 4
|
||||||
cameraDistanceLimit: {x: 1, y: 64}
|
cameraDistanceLimit: {x: 1, y: 64}
|
||||||
allowInput:
|
allowInput:
|
||||||
rid: 6077775057159979015
|
rid: 8000561620556709889
|
||||||
touchesCount: 0
|
touchesCount: 0
|
||||||
isParallelVector: 0
|
isParallelVector: 0
|
||||||
lookInput: {x: 0, y: 0, z: 0}
|
lookInput: {x: 0, y: 0, z: 0}
|
||||||
|
@ -263,8 +263,8 @@ MonoBehaviour:
|
||||||
references:
|
references:
|
||||||
version: 2
|
version: 2
|
||||||
RefIds:
|
RefIds:
|
||||||
- rid: 6077775057159979015
|
- rid: 8000561620556709889
|
||||||
type: {class: AllowTouchWhenPointerNotOverUI, ns: BITKit.UX, asm: BITKit.UX.OnScreen}
|
type: {class: AllowCondition, ns: BITKit, asm: BITKit.Node}
|
||||||
data:
|
data:
|
||||||
--- !u!1 &4263150314961711450
|
--- !u!1 &4263150314961711450
|
||||||
GameObject:
|
GameObject:
|
||||||
|
|
|
@ -50,6 +50,8 @@ namespace BITKit
|
||||||
remove => ApplicationService.OnDownloadComplete -= value;
|
remove => ApplicationService.OnDownloadComplete -= value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public event Action OnDetectedLatestVersion;
|
||||||
|
|
||||||
public UniTask<string> DownloadLatestVersionAsync()
|
public UniTask<string> DownloadLatestVersionAsync()
|
||||||
{
|
{
|
||||||
return _applicationServiceImplementation.DownloadLatestVersionAsync();
|
return _applicationServiceImplementation.DownloadLatestVersionAsync();
|
||||||
|
@ -104,6 +106,12 @@ namespace BITKit
|
||||||
remove => OnDownloadComplete -= value;
|
remove => OnDownloadComplete -= value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public event Action OnDetectedLatestVersion
|
||||||
|
{
|
||||||
|
add => Singleton.OnDetectedLatestVersion += value;
|
||||||
|
remove => Singleton.OnDetectedLatestVersion -= value;
|
||||||
|
}
|
||||||
|
|
||||||
private UnityWebRequest downloadRequest;
|
private UnityWebRequest downloadRequest;
|
||||||
|
|
||||||
private CancellationTokenSource _cancellationTokenSource;
|
private CancellationTokenSource _cancellationTokenSource;
|
||||||
|
|
|
@ -2,7 +2,6 @@ using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.Remoting.Contexts;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Cysharp.Threading.Tasks;
|
using Cysharp.Threading.Tasks;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -79,10 +78,8 @@ namespace BITKit
|
||||||
BIT4Log.OnLog += Debug.Log;
|
BIT4Log.OnLog += Debug.Log;
|
||||||
BIT4Log.OnWarning += Debug.LogWarning;
|
BIT4Log.OnWarning += Debug.LogWarning;
|
||||||
BIT4Log.OnException += Debug.LogException;
|
BIT4Log.OnException += Debug.LogException;
|
||||||
|
|
||||||
var settings = Addressables.LoadAssetAsync<ScriptableObject>("Assets/BITKit/Unity/Configs/AppSettings.asset").WaitForCompletion() as BITSettingsSO;
|
|
||||||
//启动BITApp
|
//启动BITApp
|
||||||
BITApp.Start(Application.productName, settings!.appSettings);
|
BITApp.Start(Application.productName, new BITApp.AppSettings()).Forget();
|
||||||
|
|
||||||
AllowCursor = new();
|
AllowCursor = new();
|
||||||
AllowTouchSupport = new();
|
AllowTouchSupport = new();
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
namespace BITKit
|
namespace BITKit
|
||||||
{
|
{
|
||||||
public class BITSettingsSO : ScriptableObject
|
public class BITSettingsSO : ScriptableObject
|
||||||
{
|
{
|
||||||
public BITApp.AppSettings appSettings;
|
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()
|
private void Update()
|
||||||
{
|
{
|
||||||
//var debuger = DI.Get<IDebuger>();
|
//var debuger = DI.Get<IDebuger>();
|
||||||
var playerConfig = PlayerConfig.singleton;
|
var playerConfig = PlayerConfig.Singleton;
|
||||||
var sensitivity = playerConfig.touchSensitivity;
|
var sensitivity = playerConfig.TouchSensitivity;
|
||||||
|
|
||||||
//debuger.Log(nameof(Touch.activeTouches), Touch.activeTouches.Count.ToString());
|
//debuger.Log(nameof(Touch.activeTouches), Touch.activeTouches.Count.ToString());
|
||||||
touchesCount = Touch.activeTouches.Count;
|
touchesCount = Touch.activeTouches.Count;
|
||||||
|
@ -229,8 +229,8 @@ namespace BITKit
|
||||||
private void OnView(InputAction.CallbackContext context)
|
private void OnView(InputAction.CallbackContext context)
|
||||||
{
|
{
|
||||||
if (allowInput.OnCheck() is false) return;
|
if (allowInput.OnCheck() is false) return;
|
||||||
var playerConfig = PlayerConfig.singleton;
|
var playerConfig = PlayerConfig.Singleton;
|
||||||
var sensitivity = playerConfig.sensitivity * playerConfig.m_yaw;
|
var sensitivity = playerConfig.Sensitivity * playerConfig.M_Yaw;
|
||||||
var delta = context.ReadValue<Vector2>();
|
var delta = context.ReadValue<Vector2>();
|
||||||
switch (context.control.device)
|
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
|
public record PlayerConfig
|
||||||
{
|
{
|
||||||
[SaveData]
|
public static readonly PlayerConfig Singleton = new();
|
||||||
public static PlayerConfig singleton = new();
|
public float Sensitivity = 1.81f;
|
||||||
public float sensitivity = 1.81f;
|
public float TouchSensitivity = 0.22f;
|
||||||
public float touchSensitivity = 0.22f;
|
public float M_Yaw = 0.022f;
|
||||||
public float m_yaw = 0.022f;
|
public float Fov = 75;
|
||||||
public float fov = 75;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,6 @@ using UnityEngine.SceneManagement;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using UnityEngine.Pool;
|
using UnityEngine.Pool;
|
||||||
using BITModel;
|
|
||||||
namespace BITKit
|
namespace BITKit
|
||||||
{
|
{
|
||||||
public class UnityDiagnostics : MonoBehaviour, IDiagnostics
|
public class UnityDiagnostics : MonoBehaviour, IDiagnostics
|
||||||
|
|
|
@ -14,7 +14,9 @@
|
||||||
"GUID:28c2d6a6727d47442a24a353f0d37846",
|
"GUID:28c2d6a6727d47442a24a353f0d37846",
|
||||||
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
|
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
|
||||||
"GUID:d525ad6bd40672747bde77962f1c401e",
|
"GUID:d525ad6bd40672747bde77962f1c401e",
|
||||||
"GUID:be17a8778dbfe454890ed8279279e153"
|
"GUID:be17a8778dbfe454890ed8279279e153",
|
||||||
|
"GUID:96f476e982d6fb945bfc9140ba094b7f",
|
||||||
|
"GUID:4307f53044263cf4b835bd812fc161a4"
|
||||||
],
|
],
|
||||||
"includePlatforms": [],
|
"includePlatforms": [],
|
||||||
"excludePlatforms": [],
|
"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.Animations;
|
||||||
using BITKit.StateMachine;
|
using BITKit.StateMachine;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using BITFALL.Player.Equip;
|
||||||
|
using Cinemachine;
|
||||||
|
|
||||||
namespace BITKit.Entities
|
namespace BITKit.Entities
|
||||||
{
|
{
|
||||||
public interface IEquipBase : IEntryElement, IAwake, IStart, IUpdate
|
public interface IEquipBase : IEntryElement, IAwake, IStart, IUpdate
|
||||||
|
@ -31,10 +34,17 @@ namespace BITKit.Entities
|
||||||
public virtual void EquipEvent(string eventName){}
|
public virtual void EquipEvent(string eventName){}
|
||||||
public virtual void AnimationEvent(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 EntryGroup<IEquipBase> equips = new();
|
||||||
|
public IOptional<float> Zoom { get; } = new Optional<float>(){Value = 1};
|
||||||
|
|
||||||
|
public float InitialFov;
|
||||||
|
|
||||||
|
[SerializeField] private CinemachineVirtualCamera virtualCamera;
|
||||||
protected IEquipBase entryComplete;
|
protected IEquipBase entryComplete;
|
||||||
|
private PlayerConfig playerConfig;
|
||||||
public override void OnStart()
|
public override void OnStart()
|
||||||
{
|
{
|
||||||
base.OnStart();
|
base.OnStart();
|
||||||
|
@ -56,6 +66,13 @@ namespace BITKit.Entities
|
||||||
{
|
{
|
||||||
entryComplete.OnUpdate(deltaTime);
|
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
|
public interface IHealth
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 当设置HP时的回调
|
||||||
|
/// </summary>
|
||||||
public event Action<int> OnSetHealthPoint;
|
public event Action<int> OnSetHealthPoint;
|
||||||
|
/// <summary>
|
||||||
|
/// 当设置生存状态时的回调
|
||||||
|
/// </summary>
|
||||||
public event Action<bool> OnSetAlive;
|
public event Action<bool> OnSetAlive;
|
||||||
|
/// <summary>
|
||||||
|
/// 当受到伤害时的回调
|
||||||
|
/// </summary>
|
||||||
|
public event Func<DamageMessage,int,int> OnDamage;
|
||||||
int HealthPoint { get; set; }
|
int HealthPoint { get; set; }
|
||||||
int MaxHealthPoint { get; set; }
|
int MaxHealthPoint { get; set; }
|
||||||
bool IsAlive { get; }
|
bool IsAlive { get; }
|
||||||
|
@ -50,14 +60,13 @@ namespace BITKit.Entities
|
||||||
[SerializeField] private int healthPoint = 100;
|
[SerializeField] private int healthPoint = 100;
|
||||||
[SerializeField] private int maxHealthPoint = 100;
|
[SerializeField] private int maxHealthPoint = 100;
|
||||||
|
|
||||||
[Header(Constant.Header.Events)]
|
|
||||||
[SerializeField] private UnityEvent<bool> onSetAlive = new();
|
|
||||||
|
|
||||||
[Header(Constant.Header.Providers)] [SerializeField, SerializeReference, SubclassSelector]
|
[Header(Constant.Header.Providers)] [SerializeField, SerializeReference, SubclassSelector]
|
||||||
|
[Obsolete]
|
||||||
private IHealthCallback[] additiveCallback;
|
private IHealthCallback[] additiveCallback;
|
||||||
|
|
||||||
public event Action<int> OnSetHealthPoint;
|
public event Action<int> OnSetHealthPoint;
|
||||||
public event Action<bool> OnSetAlive;
|
public event Action<bool> OnSetAlive;
|
||||||
|
public event Func<DamageMessage,int, int> OnDamage;
|
||||||
|
|
||||||
public int HealthPoint
|
public int HealthPoint
|
||||||
{
|
{
|
||||||
|
@ -72,7 +81,7 @@ namespace BITKit.Entities
|
||||||
public bool IsAlive { get; private set; }
|
public bool IsAlive { get; private set; }
|
||||||
public override void OnAwake()
|
public override void OnAwake()
|
||||||
{
|
{
|
||||||
entity.AddListener<DamageMessage>(OnDamage);
|
entity.AddListener<DamageMessage>(OnGetDamage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnStart()
|
public override void OnStart()
|
||||||
|
@ -95,11 +104,6 @@ namespace BITKit.Entities
|
||||||
x.OnSetHP(newHP);
|
x.OnSetHP(newHP);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var x in additiveCallback)
|
|
||||||
{
|
|
||||||
x.OnSetHP(newHP);
|
|
||||||
}
|
|
||||||
|
|
||||||
OnSetHealthPoint?.Invoke(newHP);
|
OnSetHealthPoint?.Invoke(newHP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,12 +114,11 @@ namespace BITKit.Entities
|
||||||
{
|
{
|
||||||
x.OnSetAlive(alive);
|
x.OnSetAlive(alive);
|
||||||
}
|
}
|
||||||
foreach (var x in additiveCallback)
|
// foreach (var x in additiveCallback)
|
||||||
{
|
// {
|
||||||
x.OnSetAlive(alive);
|
// x.OnSetAlive(alive);
|
||||||
}
|
// }
|
||||||
OnSetAlive?.Invoke(alive);
|
OnSetAlive?.Invoke(alive);
|
||||||
onSetAlive.Invoke(alive);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddHP(int hp)
|
private void AddHP(int hp)
|
||||||
|
@ -123,10 +126,15 @@ namespace BITKit.Entities
|
||||||
OnHealthPointChangedInternal(healthPoint, healthPoint += hp);
|
OnHealthPointChangedInternal(healthPoint, healthPoint += hp);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDamage(DamageMessage damageMessage)
|
private void OnGetDamage(DamageMessage damageMessage)
|
||||||
{
|
{
|
||||||
if (damageMessage.target == entity)
|
if (damageMessage.target != entity) return;
|
||||||
AddHP(-damageMessage.damage);
|
var damage = damageMessage.damage;
|
||||||
|
foreach (var x in OnDamage.CastAsFunc())
|
||||||
|
{
|
||||||
|
damage = x.Invoke(damageMessage,damage);
|
||||||
|
}
|
||||||
|
AddHP(-damage);
|
||||||
}
|
}
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
[BIT]
|
[BIT]
|
||||||
|
|
|
@ -6,7 +6,10 @@
|
||||||
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0",
|
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0",
|
||||||
"GUID:f822dbf6fdfd4a5469cccaa2e4eed3b6",
|
"GUID:f822dbf6fdfd4a5469cccaa2e4eed3b6",
|
||||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
||||||
"GUID:75469ad4d38634e559750d17036d5f7c"
|
"GUID:75469ad4d38634e559750d17036d5f7c",
|
||||||
|
"GUID:d525ad6bd40672747bde77962f1c401e",
|
||||||
|
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
|
||||||
|
"GUID:508392158bd966c4d9c21e19661a441d"
|
||||||
],
|
],
|
||||||
"includePlatforms": [],
|
"includePlatforms": [],
|
||||||
"excludePlatforms": [],
|
"excludePlatforms": [],
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using BITKit.Sensors;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.InputSystem;
|
using UnityEngine.InputSystem;
|
||||||
using UnityEngine.InputSystem.Interactions;
|
using UnityEngine.InputSystem.Interactions;
|
||||||
|
@ -6,24 +7,16 @@ namespace BITKit.Entities.Player
|
||||||
public class EntityInteractive : EntityPlayerComponent
|
public class EntityInteractive : EntityPlayerComponent
|
||||||
{
|
{
|
||||||
[Header(Constant.Header.Settings)]
|
[Header(Constant.Header.Settings)]
|
||||||
public float distance;
|
[SerializeReference, SubclassSelector] private ISensor sensor;
|
||||||
public LayerMask layerMask;
|
|
||||||
|
|
||||||
[Header(Constant.Header.Input)]
|
|
||||||
public InputActionReference interactiveAction;
|
|
||||||
private readonly InputActionGroup inputActionGroup = new();
|
|
||||||
|
|
||||||
[Header(Constant.Header.Gameobjects)]
|
|
||||||
[SerializeField] private Transform cameraTransform;
|
|
||||||
|
|
||||||
[Header(Constant.Header.InternalVariables)]
|
[Header(Constant.Header.InternalVariables)]
|
||||||
private ISelectable selected;
|
private ISelectable selected;
|
||||||
private IntervalUpdate cd = new(0.08f);
|
private IntervalUpdate cd = new(0.08f);
|
||||||
public override void OnUpdate(float deltaTime)
|
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)
|
if (_detected == selected)
|
||||||
{
|
{
|
||||||
|
@ -68,7 +61,7 @@ namespace BITKit.Entities.Player
|
||||||
}
|
}
|
||||||
public void Interactive(InputAction.CallbackContext context)
|
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;
|
var _selected = selected;
|
||||||
if (_selected is not MonoBehaviour monoBehaviour) return;
|
if (_selected is not MonoBehaviour monoBehaviour) return;
|
||||||
if (monoBehaviour.TryGetComponentAny<IAction>(out var action))
|
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 UnityEngine;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using BITKit.Core.Entites;
|
using BITKit.Core.Entites;
|
||||||
using Cysharp.Threading.Tasks;
|
using Cysharp.Threading.Tasks;
|
||||||
|
@ -17,30 +18,62 @@ namespace BITKit.Entities
|
||||||
private readonly Processor processor = new();
|
private readonly Processor processor = new();
|
||||||
public IEntityComponent[] entityComponents { get; set; }
|
public IEntityComponent[] entityComponents { get; set; }
|
||||||
public ulong Id { get; private 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 CancellationToken _cancellationToken;
|
||||||
private bool isInitialized;
|
private bool isInitialized;
|
||||||
|
private Core.Entites.IEntityComponent[] _components => entityComponents;
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
Id = (ulong)Guid.NewGuid().GetHashCode();
|
Id = (ulong)Guid.NewGuid().GetHashCode();
|
||||||
_cancellationToken = gameObject.GetCancellationTokenOnDestroy();
|
_cancellationToken = gameObject.GetCancellationTokenOnDestroy();
|
||||||
Set(_cancellationToken);
|
Set(_cancellationToken);
|
||||||
foreach (var serviceRegister in GetComponentsInChildren<IServiceRegister>(true))
|
|
||||||
{
|
|
||||||
genericEvent.Set(serviceRegister.BaseType, serviceRegister);
|
|
||||||
}
|
|
||||||
entityComponents = GetComponentsInChildren<IEntityComponent>(true).Distinct().ToArray();
|
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);
|
UnityEntitiesService.Register(this);
|
||||||
}
|
}
|
||||||
private void Start()
|
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.OnAwake());
|
||||||
entityComponents.ForEach(x => x.OnStart());
|
entityComponents.ForEach(x => x.OnStart());
|
||||||
isInitialized = true;
|
isInitialized = true;
|
||||||
|
|
|
@ -41,22 +41,22 @@ public class UnityEntitiesServiceSingleton:IEntitiesService
|
||||||
|
|
||||||
public IEntity Get(ulong id) => UnityEntitiesService.Get(id);
|
public IEntity Get(ulong id) => UnityEntitiesService.Get(id);
|
||||||
|
|
||||||
public IEntity[] Query<T>() where T : IEntityComponent
|
public IEntity[] Query<T>()
|
||||||
{
|
{
|
||||||
return UnityEntitiesService.Query<T>();
|
return UnityEntitiesService.Query<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public T[] QueryComponents<T>() where T : IEntityComponent
|
public T[] QueryComponents<T>()
|
||||||
{
|
{
|
||||||
return UnityEntitiesService.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>();
|
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>();
|
return UnityEntitiesService.QueryComponents<T, T1, T2>();
|
||||||
}
|
}
|
||||||
|
@ -64,13 +64,12 @@ public class UnityEntitiesServiceSingleton:IEntitiesService
|
||||||
|
|
||||||
public class UnityEntitiesService : MonoBehaviour,IEntitiesService
|
public class UnityEntitiesService : MonoBehaviour,IEntitiesService
|
||||||
{
|
{
|
||||||
[RuntimeInitializeOnLoadMethod]
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
||||||
private static void Initialize()
|
private static void Initialize()
|
||||||
{
|
{
|
||||||
Dictionary.Clear();
|
Dictionary.Clear();
|
||||||
RegisterQueue.Clear();
|
RegisterQueue.Clear();
|
||||||
UnRegisterQueue.Clear();
|
UnRegisterQueue.Clear();
|
||||||
|
|
||||||
}
|
}
|
||||||
public static bool Register(IEntity entity)
|
public static bool Register(IEntity entity)
|
||||||
{
|
{
|
||||||
|
@ -127,12 +126,12 @@ public class UnityEntitiesService : MonoBehaviour,IEntitiesService
|
||||||
public static IEntity Get(ulong id)=>Dictionary[id];
|
public static IEntity Get(ulong id)=>Dictionary[id];
|
||||||
IEntity IEntitiesService.Get(ulong id)=>Get(id);
|
IEntity IEntitiesService.Get(ulong id)=>Get(id);
|
||||||
IEntity[] IEntitiesService.Query<T>()=>Query<T>();
|
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();
|
return Entities.Where(x => ((Entity)x).TryGetComponentAny<T>(out _)).ToArray();
|
||||||
}
|
}
|
||||||
T[] IEntitiesService.QueryComponents<T>()=>QueryComponents<T>();
|
T[] IEntitiesService.QueryComponents<T>()=>QueryComponents<T>();
|
||||||
public static T[] QueryComponents<T>() where T : IEntityComponent
|
public static T[] QueryComponents<T>()
|
||||||
{
|
{
|
||||||
var list = ListPool<T>.Get();
|
var list = ListPool<T>.Get();
|
||||||
foreach (var iEntity in Entities)
|
foreach (var iEntity in Entities)
|
||||||
|
@ -150,7 +149,7 @@ public class UnityEntitiesService : MonoBehaviour,IEntitiesService
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
(T, T1)[] IEntitiesService.QueryComponents<T,T1>()=>QueryComponents<T,T1>();
|
(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();
|
var list = ListPool<(T t, T1 t1)>.Get();
|
||||||
foreach (var iEntity in Entities)
|
foreach (var iEntity in Entities)
|
||||||
|
@ -168,7 +167,7 @@ public class UnityEntitiesService : MonoBehaviour,IEntitiesService
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
(T, T1, T2)[] IEntitiesService.QueryComponents<T,T1,T2>()=>QueryComponents<T,T1,T2>();
|
(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();
|
var list = ListPool<(T t, T1 t1, T2 t2)>.Get();
|
||||||
foreach (var iEntity in Entities)
|
foreach (var iEntity in Entities)
|
||||||
|
|
|
@ -25,7 +25,6 @@ namespace BITKit.Entities.Editor
|
||||||
rootVisualElement.styleSheets.Add(BITEditorUtils.InspectorStyleSheet);
|
rootVisualElement.styleSheets.Add(BITEditorUtils.InspectorStyleSheet);
|
||||||
rootVisualElement.styleSheets.Add(BITEditorUtils.Style);
|
rootVisualElement.styleSheets.Add(BITEditorUtils.Style);
|
||||||
rootVisualElement.AddToClassList("pa-8");
|
rootVisualElement.AddToClassList("pa-8");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update()
|
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