提交修改
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using ProtoBuf;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
@@ -11,7 +11,7 @@ using NBC.Serialize;
|
||||
namespace NBF
|
||||
{
|
||||
[ProtoContract]
|
||||
public sealed partial class BaitConfig : ASerialize, IProto, IConfigTable
|
||||
public sealed partial class BaitConfig : ASerialize, IConfigTable
|
||||
{
|
||||
|
||||
[ProtoMember(1)]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using ProtoBuf;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
@@ -11,7 +11,7 @@ using NBC.Serialize;
|
||||
namespace NBF
|
||||
{
|
||||
[ProtoContract]
|
||||
public sealed partial class BasicConfig : ASerialize, IProto, IConfigTable
|
||||
public sealed partial class BasicConfig : ASerialize, IConfigTable
|
||||
{
|
||||
|
||||
[ProtoMember(1)]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using ProtoBuf;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
@@ -11,7 +11,7 @@ using NBC.Serialize;
|
||||
namespace NBF
|
||||
{
|
||||
[ProtoContract]
|
||||
public sealed partial class BobberConfig : ASerialize, IProto, IConfigTable
|
||||
public sealed partial class BobberConfig : ASerialize, IConfigTable
|
||||
{
|
||||
|
||||
[ProtoMember(1)]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using ProtoBuf;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
@@ -11,7 +11,7 @@ using NBC.Serialize;
|
||||
namespace NBF
|
||||
{
|
||||
[ProtoContract]
|
||||
public sealed partial class FeederConfig : ASerialize, IProto, IConfigTable
|
||||
public sealed partial class FeederConfig : ASerialize, IConfigTable
|
||||
{
|
||||
|
||||
[ProtoMember(1)]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using ProtoBuf;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
@@ -11,7 +11,7 @@ using NBC.Serialize;
|
||||
namespace NBF
|
||||
{
|
||||
[ProtoContract]
|
||||
public sealed partial class FishConfig : ASerialize, IProto, IConfigTable
|
||||
public sealed partial class FishConfig : ASerialize, IConfigTable
|
||||
{
|
||||
|
||||
[ProtoMember(1)]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using ProtoBuf;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
@@ -11,7 +11,7 @@ using NBC.Serialize;
|
||||
namespace NBF
|
||||
{
|
||||
[ProtoContract]
|
||||
public sealed partial class HookConfig : ASerialize, IProto, IConfigTable
|
||||
public sealed partial class HookConfig : ASerialize, IConfigTable
|
||||
{
|
||||
|
||||
[ProtoMember(1)]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using ProtoBuf;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
@@ -11,7 +11,7 @@ using NBC.Serialize;
|
||||
namespace NBF
|
||||
{
|
||||
[ProtoContract]
|
||||
public sealed partial class InitConfig : ASerialize, IProto, IConfigTable
|
||||
public sealed partial class InitConfig : ASerialize, IConfigTable
|
||||
{
|
||||
|
||||
[ProtoMember(1)]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using ProtoBuf;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
@@ -11,7 +11,7 @@ using NBC.Serialize;
|
||||
namespace NBF
|
||||
{
|
||||
[ProtoContract]
|
||||
public sealed partial class ItemConfig : ASerialize, IProto, IConfigTable
|
||||
public sealed partial class ItemConfig : ASerialize, IConfigTable
|
||||
{
|
||||
|
||||
[ProtoMember(1)]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using ProtoBuf;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
@@ -11,7 +11,7 @@ using NBC.Serialize;
|
||||
namespace NBF
|
||||
{
|
||||
[ProtoContract]
|
||||
public sealed partial class LineConfig : ASerialize, IProto, IConfigTable
|
||||
public sealed partial class LineConfig : ASerialize, IConfigTable
|
||||
{
|
||||
|
||||
[ProtoMember(1)]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using ProtoBuf;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
@@ -11,7 +11,7 @@ using NBC.Serialize;
|
||||
namespace NBF
|
||||
{
|
||||
[ProtoContract]
|
||||
public sealed partial class LureConfig : ASerialize, IProto, IConfigTable
|
||||
public sealed partial class LureConfig : ASerialize, IConfigTable
|
||||
{
|
||||
|
||||
[ProtoMember(1)]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using ProtoBuf;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
@@ -11,7 +11,7 @@ using NBC.Serialize;
|
||||
namespace NBF
|
||||
{
|
||||
[ProtoContract]
|
||||
public sealed partial class ReelConfig : ASerialize, IProto, IConfigTable
|
||||
public sealed partial class ReelConfig : ASerialize, IConfigTable
|
||||
{
|
||||
|
||||
[ProtoMember(1)]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using ProtoBuf;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using ProtoBuf;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
@@ -11,7 +11,7 @@ using NBC.Serialize;
|
||||
namespace NBF
|
||||
{
|
||||
[ProtoContract]
|
||||
public sealed partial class RodConfig : ASerialize, IProto, IConfigTable
|
||||
public sealed partial class RodConfig : ASerialize, IConfigTable
|
||||
{
|
||||
|
||||
[ProtoMember(1)]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using ProtoBuf;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
@@ -11,7 +11,7 @@ using NBC.Serialize;
|
||||
namespace NBF
|
||||
{
|
||||
[ProtoContract]
|
||||
public sealed partial class RodRingConfig : ASerialize, IProto, IConfigTable
|
||||
public sealed partial class RodRingConfig : ASerialize, IConfigTable
|
||||
{
|
||||
|
||||
[ProtoMember(1)]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using ProtoBuf;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using ProtoBuf;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using ProtoBuf;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using ProtoBuf;
|
||||
using System;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using NBC.Network.Interface;
|
||||
using NBC.Serialize;
|
||||
@@ -13,7 +13,7 @@ namespace NBC
|
||||
/// 角色基础信息
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class RoleBaseInfo : AMessage, IProto
|
||||
public partial class RoleBaseInfo : AMessage
|
||||
{
|
||||
public static RoleBaseInfo Create(Scene scene)
|
||||
{
|
||||
@@ -45,7 +45,7 @@ namespace NBC
|
||||
public VipInfo VipInfo { get; set; }
|
||||
}
|
||||
[ProtoContract]
|
||||
public partial class KeyValueInt64 : AMessage, IProto
|
||||
public partial class KeyValueInt64 : AMessage
|
||||
{
|
||||
public static KeyValueInt64 Create(Scene scene)
|
||||
{
|
||||
@@ -68,7 +68,7 @@ namespace NBC
|
||||
/// 角色信息
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class RoleInfo : AMessage, IProto
|
||||
public partial class RoleInfo : AMessage
|
||||
{
|
||||
public static RoleInfo Create(Scene scene)
|
||||
{
|
||||
@@ -115,7 +115,7 @@ namespace NBC
|
||||
/// 角色信息
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class RoleSimpleInfo : AMessage, IProto
|
||||
public partial class RoleSimpleInfo : AMessage
|
||||
{
|
||||
public static RoleSimpleInfo Create(Scene scene)
|
||||
{
|
||||
@@ -153,7 +153,7 @@ namespace NBC
|
||||
/// VIP信息
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class VipInfo : AMessage, IProto
|
||||
public partial class VipInfo : AMessage
|
||||
{
|
||||
public static VipInfo Create(Scene scene)
|
||||
{
|
||||
@@ -179,7 +179,7 @@ namespace NBC
|
||||
/// 奖励信息
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class AwardInfo : AMessage, IProto
|
||||
public partial class AwardInfo : AMessage
|
||||
{
|
||||
public static AwardInfo Create(Scene scene)
|
||||
{
|
||||
@@ -202,7 +202,7 @@ namespace NBC
|
||||
/// 玩家当前使用钓组信息
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class ItemBindInfo : AMessage, IProto
|
||||
public partial class ItemBindInfo : AMessage
|
||||
{
|
||||
public static ItemBindInfo Create(Scene scene)
|
||||
{
|
||||
@@ -225,7 +225,7 @@ namespace NBC
|
||||
/// 物品信息
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class ItemInfo : AMessage, IProto
|
||||
public partial class ItemInfo : AMessage
|
||||
{
|
||||
public static ItemInfo Create(Scene scene)
|
||||
{
|
||||
@@ -260,7 +260,7 @@ namespace NBC
|
||||
/// fish信息
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class FishInfo : AMessage, IProto
|
||||
public partial class FishInfo : AMessage
|
||||
{
|
||||
public static FishInfo Create(Scene scene)
|
||||
{
|
||||
@@ -289,7 +289,7 @@ namespace NBC
|
||||
public long ExpirationTime { get; set; }
|
||||
}
|
||||
[ProtoContract]
|
||||
public partial class ActivityInfo : AMessage, IProto
|
||||
public partial class ActivityInfo : AMessage
|
||||
{
|
||||
public static ActivityInfo Create(Scene scene)
|
||||
{
|
||||
@@ -318,7 +318,7 @@ namespace NBC
|
||||
/// 技能情况
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class SkillInfo : AMessage, IProto
|
||||
public partial class SkillInfo : AMessage
|
||||
{
|
||||
public static SkillInfo Create(Scene scene)
|
||||
{
|
||||
@@ -341,3 +341,4 @@ namespace NBC
|
||||
public int Exp { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using ProtoBuf;
|
||||
using System;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using NBC.Network.Interface;
|
||||
using NBC.Serialize;
|
||||
@@ -16,7 +16,7 @@ namespace NBC
|
||||
/// 请求背包列表
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2Game_GetItemsRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2Game_GetItemsRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2Game_GetItemsRequest Create(Scene scene)
|
||||
{
|
||||
@@ -38,7 +38,7 @@ namespace NBC
|
||||
/// 请求背包列表响应
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class Game2C_GetItemsResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class Game2C_GetItemsResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static Game2C_GetItemsResponse Create(Scene scene)
|
||||
{
|
||||
@@ -65,7 +65,7 @@ namespace NBC
|
||||
/// 请求使用物品
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2Game_UseItemRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2Game_UseItemRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2Game_UseItemRequest Create(Scene scene)
|
||||
{
|
||||
@@ -87,7 +87,7 @@ namespace NBC
|
||||
/// 请求使用物品响应
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class Game2C_UseItemResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class Game2C_UseItemResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static Game2C_UseItemResponse Create(Scene scene)
|
||||
{
|
||||
@@ -108,7 +108,7 @@ namespace NBC
|
||||
/// 物品变化
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class Game2C_ItemChange : AMessage, ICustomRouteMessage, IProto
|
||||
public partial class Game2C_ItemChange : AMessage, ICustomRouteMessage
|
||||
{
|
||||
public static Game2C_ItemChange Create(Scene scene)
|
||||
{
|
||||
@@ -140,7 +140,7 @@ namespace NBC
|
||||
/// 请求安装或取下配件
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2Game_RigChangeRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2Game_RigChangeRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2Game_RigChangeRequest Create(Scene scene)
|
||||
{
|
||||
@@ -171,7 +171,7 @@ namespace NBC
|
||||
/// 请求安装配件响应
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class Game2C_RigChangeResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class Game2C_RigChangeResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static Game2C_RigChangeResponse Create(Scene scene)
|
||||
{
|
||||
@@ -198,7 +198,7 @@ namespace NBC
|
||||
/// 请求鱼护列表
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2Game_GetFishsRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2Game_GetFishsRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2Game_GetFishsRequest Create(Scene scene)
|
||||
{
|
||||
@@ -220,7 +220,7 @@ namespace NBC
|
||||
/// 请求鱼护列表响应
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class Game2C_GetFishsResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class Game2C_GetFishsResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static Game2C_GetFishsResponse Create(Scene scene)
|
||||
{
|
||||
@@ -244,7 +244,7 @@ namespace NBC
|
||||
/// 鱼护变化
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class Game2C_FishChange : AMessage, ICustomRouteMessage, IProto
|
||||
public partial class Game2C_FishChange : AMessage, ICustomRouteMessage
|
||||
{
|
||||
public static Game2C_FishChange Create(Scene scene)
|
||||
{
|
||||
@@ -273,7 +273,7 @@ namespace NBC
|
||||
/// 请求出售
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2Game_SellFishRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2Game_SellFishRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2Game_SellFishRequest Create(Scene scene)
|
||||
{
|
||||
@@ -298,7 +298,7 @@ namespace NBC
|
||||
/// 请求出售响应
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class Game2C_SellFishResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class Game2C_SellFishResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static Game2C_SellFishResponse Create(Scene scene)
|
||||
{
|
||||
@@ -325,7 +325,7 @@ namespace NBC
|
||||
/// 请求购买
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2Game_BuyRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2Game_BuyRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2Game_BuyRequest Create(Scene scene)
|
||||
{
|
||||
@@ -347,7 +347,7 @@ namespace NBC
|
||||
/// 请求购买响应
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class Game2C_BuyResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class Game2C_BuyResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static Game2C_BuyResponse Create(Scene scene)
|
||||
{
|
||||
@@ -368,3 +368,4 @@ namespace NBC
|
||||
public uint ErrorCode { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using ProtoBuf;
|
||||
using System;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using NBC.Network.Interface;
|
||||
using NBC.Serialize;
|
||||
@@ -13,7 +13,7 @@ namespace NBC
|
||||
/// 请求创建房间
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2Map_CreateRoomRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2Map_CreateRoomRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2Map_CreateRoomRequest Create(Scene scene)
|
||||
{
|
||||
@@ -38,7 +38,7 @@ namespace NBC
|
||||
/// 请求创建房间成功
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class Map2C_CreateRoomResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class Map2C_CreateRoomResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static Map2C_CreateRoomResponse Create(Scene scene)
|
||||
{
|
||||
@@ -65,7 +65,7 @@ namespace NBC
|
||||
/// 请求网关离开房间(离开房间,但是不离开地图)
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2G_ExitRoomRequest : AMessage, IRequest, IProto
|
||||
public partial class C2G_ExitRoomRequest : AMessage, IRequest
|
||||
{
|
||||
public static C2G_ExitRoomRequest Create(Scene scene)
|
||||
{
|
||||
@@ -88,7 +88,7 @@ namespace NBC
|
||||
/// 请求网关进入离开响应
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class G2C_ExitRoomResponse : AMessage, IResponse, IProto
|
||||
public partial class G2C_ExitRoomResponse : AMessage, IResponse
|
||||
{
|
||||
public static G2C_ExitRoomResponse Create(Scene scene)
|
||||
{
|
||||
@@ -112,7 +112,7 @@ namespace NBC
|
||||
/// 请求网关进入地图
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2G_EnterMapRequest : AMessage, IRequest, IProto
|
||||
public partial class C2G_EnterMapRequest : AMessage, IRequest
|
||||
{
|
||||
public static C2G_EnterMapRequest Create(Scene scene)
|
||||
{
|
||||
@@ -138,7 +138,7 @@ namespace NBC
|
||||
/// 请求网关进入房间响应
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class G2C_EnterMapResponse : AMessage, IResponse, IProto
|
||||
public partial class G2C_EnterMapResponse : AMessage, IResponse
|
||||
{
|
||||
public static G2C_EnterMapResponse Create(Scene scene)
|
||||
{
|
||||
@@ -168,7 +168,7 @@ namespace NBC
|
||||
/// 通知客户端切换地图
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class Map2C_ChangeMap : AMessage, ICustomRouteMessage, IProto
|
||||
public partial class Map2C_ChangeMap : AMessage, ICustomRouteMessage
|
||||
{
|
||||
public static Map2C_ChangeMap Create(Scene scene)
|
||||
{
|
||||
@@ -191,3 +191,4 @@ namespace NBC
|
||||
public int Node { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using ProtoBuf;
|
||||
using System;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using NBC.Network.Interface;
|
||||
using NBC.Serialize;
|
||||
@@ -10,7 +10,7 @@ using NBC.Serialize;
|
||||
namespace NBC
|
||||
{
|
||||
[ProtoContract]
|
||||
public partial class Vector3Info : AMessage, IProto
|
||||
public partial class Vector3Info : AMessage
|
||||
{
|
||||
public static Vector3Info Create(Scene scene)
|
||||
{
|
||||
@@ -33,7 +33,7 @@ namespace NBC
|
||||
public float z { get; set; }
|
||||
}
|
||||
[ProtoContract]
|
||||
public partial class Vector2Info : AMessage, IProto
|
||||
public partial class Vector2Info : AMessage
|
||||
{
|
||||
public static Vector2Info Create(Scene scene)
|
||||
{
|
||||
@@ -53,7 +53,7 @@ namespace NBC
|
||||
public float y { get; set; }
|
||||
}
|
||||
[ProtoContract]
|
||||
public partial class QuaternionInfo : AMessage, IProto
|
||||
public partial class QuaternionInfo : AMessage
|
||||
{
|
||||
public static QuaternionInfo Create(Scene scene)
|
||||
{
|
||||
@@ -82,7 +82,7 @@ namespace NBC
|
||||
/// 玩家当前使用钓组信息
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class GearInfo : AMessage, IProto
|
||||
public partial class GearInfo : AMessage
|
||||
{
|
||||
public static GearInfo Create(Scene scene)
|
||||
{
|
||||
@@ -111,7 +111,7 @@ namespace NBC
|
||||
public List<KeyValueInt64> Propertys = new List<KeyValueInt64>();
|
||||
}
|
||||
[ProtoContract]
|
||||
public partial class UnitStateInfo : AMessage, IProto
|
||||
public partial class UnitStateInfo : AMessage
|
||||
{
|
||||
public static UnitStateInfo Create(Scene scene)
|
||||
{
|
||||
@@ -131,7 +131,7 @@ namespace NBC
|
||||
public List<KeyValueInt64> Propertys = new List<KeyValueInt64>();
|
||||
}
|
||||
[ProtoContract]
|
||||
public partial class MapUnitInfo : AMessage, IProto
|
||||
public partial class MapUnitInfo : AMessage
|
||||
{
|
||||
public static MapUnitInfo Create(Scene scene)
|
||||
{
|
||||
@@ -166,3 +166,4 @@ namespace NBC
|
||||
public List<KeyValueInt64> Propertys = new List<KeyValueInt64>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
657
Assets/Scripts/Generate/NetworkProtocol/NetworkProtocolHelper.cs
Normal file
657
Assets/Scripts/Generate/NetworkProtocol/NetworkProtocolHelper.cs
Normal file
@@ -0,0 +1,657 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using NBC;
|
||||
using NBC.Async;
|
||||
using NBC.Network;
|
||||
using System.Collections.Generic;
|
||||
#pragma warning disable CS8618
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public static class NetworkProtocolHelper
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<Game2C_GetItemsResponse> C2Game_GetItemsRequest(this Session session, C2Game_GetItemsRequest request)
|
||||
{
|
||||
return (Game2C_GetItemsResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<Game2C_GetItemsResponse> C2Game_GetItemsRequest(this Session session)
|
||||
{
|
||||
using var request = Fantasy.C2Game_GetItemsRequest.Create(session.Scene);
|
||||
return (Game2C_GetItemsResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<Game2C_UseItemResponse> C2Game_UseItemRequest(this Session session, C2Game_UseItemRequest request)
|
||||
{
|
||||
return (Game2C_UseItemResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<Game2C_UseItemResponse> C2Game_UseItemRequest(this Session session)
|
||||
{
|
||||
using var request = Fantasy.C2Game_UseItemRequest.Create(session.Scene);
|
||||
return (Game2C_UseItemResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Game2C_ItemChange(this Session session, Game2C_ItemChange message)
|
||||
{
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Game2C_ItemChange(this Session session, int type, List<ItemInfo> items, List<long> removes)
|
||||
{
|
||||
using var message = Fantasy.Game2C_ItemChange.Create(session.Scene);
|
||||
message.Type = type;
|
||||
message.Items = items;
|
||||
message.Removes = removes;
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<Game2C_RigChangeResponse> C2Game_RigChangeRequest(this Session session, C2Game_RigChangeRequest request)
|
||||
{
|
||||
return (Game2C_RigChangeResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<Game2C_RigChangeResponse> C2Game_RigChangeRequest(this Session session, long rodId, long rigId, bool isAdd)
|
||||
{
|
||||
using var request = Fantasy.C2Game_RigChangeRequest.Create(session.Scene);
|
||||
request.RodId = rodId;
|
||||
request.RigId = rigId;
|
||||
request.IsAdd = isAdd;
|
||||
return (Game2C_RigChangeResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<Game2C_GetFishsResponse> C2Game_GetFishsRequest(this Session session, C2Game_GetFishsRequest request)
|
||||
{
|
||||
return (Game2C_GetFishsResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<Game2C_GetFishsResponse> C2Game_GetFishsRequest(this Session session)
|
||||
{
|
||||
using var request = Fantasy.C2Game_GetFishsRequest.Create(session.Scene);
|
||||
return (Game2C_GetFishsResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Game2C_FishChange(this Session session, Game2C_FishChange message)
|
||||
{
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Game2C_FishChange(this Session session, int type, List<FishInfo> fishs, List<long> removes)
|
||||
{
|
||||
using var message = Fantasy.Game2C_FishChange.Create(session.Scene);
|
||||
message.Type = type;
|
||||
message.Fishs = fishs;
|
||||
message.Removes = removes;
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<Game2C_SellFishResponse> C2Game_SellFishRequest(this Session session, C2Game_SellFishRequest request)
|
||||
{
|
||||
return (Game2C_SellFishResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<Game2C_SellFishResponse> C2Game_SellFishRequest(this Session session, List<long> ids)
|
||||
{
|
||||
using var request = Fantasy.C2Game_SellFishRequest.Create(session.Scene);
|
||||
request.Ids = ids;
|
||||
return (Game2C_SellFishResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<Game2C_GetFishsResponse> C2Game_BuyRequest(this Session session, C2Game_BuyRequest request)
|
||||
{
|
||||
return (Game2C_GetFishsResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<Game2C_GetFishsResponse> C2Game_BuyRequest(this Session session)
|
||||
{
|
||||
using var request = Fantasy.C2Game_BuyRequest.Create(session.Scene);
|
||||
return (Game2C_GetFishsResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<Map2C_CreateRoomResponse> C2Map_CreateRoomRequest(this Session session, C2Map_CreateRoomRequest request)
|
||||
{
|
||||
return (Map2C_CreateRoomResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<Map2C_CreateRoomResponse> C2Map_CreateRoomRequest(this Session session, int mapId)
|
||||
{
|
||||
using var request = Fantasy.C2Map_CreateRoomRequest.Create(session.Scene);
|
||||
request.MapId = mapId;
|
||||
return (Map2C_CreateRoomResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<G2C_ExitRoomResponse> C2G_ExitRoomRequest(this Session session, C2G_ExitRoomRequest request)
|
||||
{
|
||||
return (G2C_ExitRoomResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<G2C_ExitRoomResponse> C2G_ExitRoomRequest(this Session session, string roomCode)
|
||||
{
|
||||
using var request = Fantasy.C2G_ExitRoomRequest.Create(session.Scene);
|
||||
request.RoomCode = roomCode;
|
||||
return (G2C_ExitRoomResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<G2C_EnterMapResponse> C2G_EnterMapRequest(this Session session, C2G_EnterMapRequest request)
|
||||
{
|
||||
return (G2C_EnterMapResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<G2C_EnterMapResponse> C2G_EnterMapRequest(this Session session, string roomCode, int mapId)
|
||||
{
|
||||
using var request = Fantasy.C2G_EnterMapRequest.Create(session.Scene);
|
||||
request.RoomCode = roomCode;
|
||||
request.MapId = mapId;
|
||||
return (G2C_EnterMapResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Map2C_ChangeMap(this Session session, Map2C_ChangeMap message)
|
||||
{
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Map2C_ChangeMap(this Session session, int mapId, int node)
|
||||
{
|
||||
using var message = Fantasy.Map2C_ChangeMap.Create(session.Scene);
|
||||
message.MapId = mapId;
|
||||
message.Node = node;
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<A2C_LoginResponse> C2A_LoginRequest(this Session session, C2A_LoginRequest request)
|
||||
{
|
||||
return (A2C_LoginResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<A2C_LoginResponse> C2A_LoginRequest(this Session session, string username, string password, int loginType, int region)
|
||||
{
|
||||
using var request = Fantasy.C2A_LoginRequest.Create(session.Scene);
|
||||
request.Username = username;
|
||||
request.Password = password;
|
||||
request.LoginType = loginType;
|
||||
request.Region = region;
|
||||
return (A2C_LoginResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<G2C_LoginResponse> C2G_LoginRequest(this Session session, C2G_LoginRequest request)
|
||||
{
|
||||
return (G2C_LoginResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<G2C_LoginResponse> C2G_LoginRequest(this Session session, string toKen)
|
||||
{
|
||||
using var request = Fantasy.C2G_LoginRequest.Create(session.Scene);
|
||||
request.ToKen = toKen;
|
||||
return (G2C_LoginResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void G2C_RepeatLogin(this Session session, G2C_RepeatLogin message)
|
||||
{
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void G2C_RepeatLogin(this Session session)
|
||||
{
|
||||
using var message = Fantasy.G2C_RepeatLogin.Create(session.Scene);
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<Game2C_GetRoleInfoResponse> C2Game_GetRoleInfoRequest(this Session session, C2Game_GetRoleInfoRequest request)
|
||||
{
|
||||
return (Game2C_GetRoleInfoResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<Game2C_GetRoleInfoResponse> C2Game_GetRoleInfoRequest(this Session session)
|
||||
{
|
||||
using var request = Fantasy.C2Game_GetRoleInfoRequest.Create(session.Scene);
|
||||
return (Game2C_GetRoleInfoResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Map2C_RoleEnterRoomNotify(this Session session, Map2C_RoleEnterRoomNotify message)
|
||||
{
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Map2C_RoleEnterRoomNotify(this Session session, MapUnitInfo info)
|
||||
{
|
||||
using var message = Fantasy.Map2C_RoleEnterRoomNotify.Create(session.Scene);
|
||||
message.Info = info;
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Map2C_RoleExitRoomNotify(this Session session, Map2C_RoleExitRoomNotify message)
|
||||
{
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Map2C_RoleExitRoomNotify(this Session session, long id)
|
||||
{
|
||||
using var message = Fantasy.Map2C_RoleExitRoomNotify.Create(session.Scene);
|
||||
message.Id = id;
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void C2Map_RolePropertyChange(this Session session, C2Map_RolePropertyChange message)
|
||||
{
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void C2Map_RolePropertyChange(this Session session, List<KeyValueInt64> propertys)
|
||||
{
|
||||
using var message = Fantasy.C2Map_RolePropertyChange.Create(session.Scene);
|
||||
message.Propertys = propertys;
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Map2C_RoleStateNotify(this Session session, Map2C_RoleStateNotify message)
|
||||
{
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Map2C_RoleStateNotify(this Session session, long id, UnitStateInfo state)
|
||||
{
|
||||
using var message = Fantasy.Map2C_RoleStateNotify.Create(session.Scene);
|
||||
message.Id = id;
|
||||
message.State = state;
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Map2C_RoleGearChangeNotify(this Session session, Map2C_RoleGearChangeNotify message)
|
||||
{
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Map2C_RoleGearChangeNotify(this Session session, long id, List<GearInfo> gears)
|
||||
{
|
||||
using var message = Fantasy.Map2C_RoleGearChangeNotify.Create(session.Scene);
|
||||
message.Id = id;
|
||||
message.Gears = gears;
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Map2C_RolePropertyChangeNotify(this Session session, Map2C_RolePropertyChangeNotify message)
|
||||
{
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Map2C_RolePropertyChangeNotify(this Session session, long id, List<KeyValueInt64> propertys)
|
||||
{
|
||||
using var message = Fantasy.Map2C_RolePropertyChangeNotify.Create(session.Scene);
|
||||
message.Id = id;
|
||||
message.Propertys = propertys;
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void C2Map_Move(this Session session, C2Map_Move message)
|
||||
{
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void C2Map_Move(this Session session, Vector3Info position, Vector3Info rotation, Vector3Info direction, bool isStop, bool isRun, long timestamp)
|
||||
{
|
||||
using var message = Fantasy.C2Map_Move.Create(session.Scene);
|
||||
message.Position = position;
|
||||
message.Rotation = rotation;
|
||||
message.Direction = direction;
|
||||
message.IsStop = isStop;
|
||||
message.IsRun = isRun;
|
||||
message.Timestamp = timestamp;
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void C2Map_Look(this Session session, C2Map_Look message)
|
||||
{
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void C2Map_Look(this Session session, Vector3Info rotation, long timestamp)
|
||||
{
|
||||
using var message = Fantasy.C2Map_Look.Create(session.Scene);
|
||||
message.Rotation = rotation;
|
||||
message.Timestamp = timestamp;
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Map2C_MoveNotify(this Session session, Map2C_MoveNotify message)
|
||||
{
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Map2C_MoveNotify(this Session session, long id, Vector3Info position, Vector3Info rotation, Vector3Info direction, bool isStop, bool isRun, long timestamp)
|
||||
{
|
||||
using var message = Fantasy.Map2C_MoveNotify.Create(session.Scene);
|
||||
message.Id = id;
|
||||
message.Position = position;
|
||||
message.Rotation = rotation;
|
||||
message.Direction = direction;
|
||||
message.IsStop = isStop;
|
||||
message.IsRun = isRun;
|
||||
message.Timestamp = timestamp;
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Map2C_LookeNotify(this Session session, Map2C_LookeNotify message)
|
||||
{
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Map2C_LookeNotify(this Session session, long id, Vector3Info rotation, long timestamp)
|
||||
{
|
||||
using var message = Fantasy.Map2C_LookeNotify.Create(session.Scene);
|
||||
message.Id = id;
|
||||
message.Rotation = rotation;
|
||||
message.Timestamp = timestamp;
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_GetConversationsResponse> C2S_GetConversationsRequest(this Session session, C2S_GetConversationsRequest request)
|
||||
{
|
||||
return (S2C_GetConversationsResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_GetConversationsResponse> C2S_GetConversationsRequest(this Session session)
|
||||
{
|
||||
using var request = Fantasy.C2S_GetConversationsRequest.Create(session.Scene);
|
||||
return (S2C_GetConversationsResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_SendMailResponse> C2S_SendMailRequest(this Session session, C2S_SendMailRequest request)
|
||||
{
|
||||
return (S2C_SendMailResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_SendMailResponse> C2S_SendMailRequest(this Session session, long target, string content, List<AwardInfo> items)
|
||||
{
|
||||
using var request = Fantasy.C2S_SendMailRequest.Create(session.Scene);
|
||||
request.Target = target;
|
||||
request.Content = content;
|
||||
request.Items = items;
|
||||
return (S2C_SendMailResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_DeleteMailResponse> C2S_DeleteMailRequest(this Session session, C2S_DeleteMailRequest request)
|
||||
{
|
||||
return (S2C_DeleteMailResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_DeleteMailResponse> C2S_DeleteMailRequest(this Session session, long id)
|
||||
{
|
||||
using var request = Fantasy.C2S_DeleteMailRequest.Create(session.Scene);
|
||||
request.Id = id;
|
||||
return (S2C_DeleteMailResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void S2C_HaveMail(this Session session, S2C_HaveMail message)
|
||||
{
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void S2C_HaveMail(this Session session, MailInfo mail, string key)
|
||||
{
|
||||
using var message = Fantasy.S2C_HaveMail.Create(session.Scene);
|
||||
message.Mail = mail;
|
||||
message.Key = key;
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void S2C_MailState(this Session session, S2C_MailState message)
|
||||
{
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void S2C_MailState(this Session session, int mailState, long mailId)
|
||||
{
|
||||
using var message = Fantasy.S2C_MailState.Create(session.Scene);
|
||||
message.MailState = mailState;
|
||||
message.MailId = mailId;
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_CreateChannelResponse> C2S_CreateChannelRequest(this Session session, C2S_CreateChannelRequest request)
|
||||
{
|
||||
return (S2C_CreateChannelResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_CreateChannelResponse> C2S_CreateChannelRequest(this Session session, string name)
|
||||
{
|
||||
using var request = Fantasy.C2S_CreateChannelRequest.Create(session.Scene);
|
||||
request.Name = name;
|
||||
return (S2C_CreateChannelResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_JoinChannelResponse> C2S_JoinChannelRequest(this Session session, C2S_JoinChannelRequest request)
|
||||
{
|
||||
return (S2C_JoinChannelResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_JoinChannelResponse> C2S_JoinChannelRequest(this Session session, long target)
|
||||
{
|
||||
using var request = Fantasy.C2S_JoinChannelRequest.Create(session.Scene);
|
||||
request.Target = target;
|
||||
return (S2C_JoinChannelResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_SendMessageResponse> C2S_SendMessageRequest(this Session session, C2S_SendMessageRequest request)
|
||||
{
|
||||
return (S2C_SendMessageResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_SendMessageResponse> C2S_SendMessageRequest(this Session session, string message, long target)
|
||||
{
|
||||
using var request = Fantasy.C2S_SendMessageRequest.Create(session.Scene);
|
||||
request.Message = message;
|
||||
request.Target = target;
|
||||
return (S2C_SendMessageResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void S2C_Message(this Session session, S2C_Message message)
|
||||
{
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void S2C_Message(this Session session, ChatMessageInfo message)
|
||||
{
|
||||
using var message = Fantasy.S2C_Message.Create(session.Scene);
|
||||
message.Message = message;
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_CreateClubResponse> C2S_CreateClubRequest(this Session session, C2S_CreateClubRequest request)
|
||||
{
|
||||
return (S2C_CreateClubResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_CreateClubResponse> C2S_CreateClubRequest(this Session session, string name)
|
||||
{
|
||||
using var request = Fantasy.C2S_CreateClubRequest.Create(session.Scene);
|
||||
request.Name = name;
|
||||
return (S2C_CreateClubResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_GetClubInfoResponse> C2S_GetClubInfoRequest(this Session session, C2S_GetClubInfoRequest request)
|
||||
{
|
||||
return (S2C_GetClubInfoResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_GetClubInfoResponse> C2S_GetClubInfoRequest(this Session session, long clubId)
|
||||
{
|
||||
using var request = Fantasy.C2S_GetClubInfoRequest.Create(session.Scene);
|
||||
request.ClubId = clubId;
|
||||
return (S2C_GetClubInfoResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_GetMemberListResponse> C2S_GetMemberListRequest(this Session session, C2S_GetMemberListRequest request)
|
||||
{
|
||||
return (S2C_GetMemberListResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_GetMemberListResponse> C2S_GetMemberListRequest(this Session session, long clubId)
|
||||
{
|
||||
using var request = Fantasy.C2S_GetMemberListRequest.Create(session.Scene);
|
||||
request.ClubId = clubId;
|
||||
return (S2C_GetMemberListResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_GetClubListResponse> C2S_GetClubListRequest(this Session session, C2S_GetClubListRequest request)
|
||||
{
|
||||
return (S2C_GetClubListResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_GetClubListResponse> C2S_GetClubListRequest(this Session session)
|
||||
{
|
||||
using var request = Fantasy.C2S_GetClubListRequest.Create(session.Scene);
|
||||
return (S2C_GetClubListResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_JoinClubResponse> C2S_JoinClubRequest(this Session session, C2S_JoinClubRequest request)
|
||||
{
|
||||
return (S2C_JoinClubResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_JoinClubResponse> C2S_JoinClubRequest(this Session session, long clubId)
|
||||
{
|
||||
using var request = Fantasy.C2S_JoinClubRequest.Create(session.Scene);
|
||||
request.ClubId = clubId;
|
||||
return (S2C_JoinClubResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_LeaveClubResponse> C2S_LeaveClubRequest(this Session session, C2S_LeaveClubRequest request)
|
||||
{
|
||||
return (S2C_LeaveClubResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_LeaveClubResponse> C2S_LeaveClubRequest(this Session session, long clubId)
|
||||
{
|
||||
using var request = Fantasy.C2S_LeaveClubRequest.Create(session.Scene);
|
||||
request.ClubId = clubId;
|
||||
return (S2C_LeaveClubResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_DissolveClubResponse> C2S_DissolveClubRequest(this Session session, C2S_DissolveClubRequest request)
|
||||
{
|
||||
return (S2C_DissolveClubResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_DissolveClubResponse> C2S_DissolveClubRequest(this Session session, long clubId)
|
||||
{
|
||||
using var request = Fantasy.C2S_DissolveClubRequest.Create(session.Scene);
|
||||
request.ClubId = clubId;
|
||||
return (S2C_DissolveClubResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_DisposeJoinResponse> C2S_DisposeJoinRequest(this Session session, C2S_DisposeJoinRequest request)
|
||||
{
|
||||
return (S2C_DisposeJoinResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static async FTask<S2C_DisposeJoinResponse> C2S_DisposeJoinRequest(this Session session, long clubId, long applicantId, int agree)
|
||||
{
|
||||
using var request = Fantasy.C2S_DisposeJoinRequest.Create(session.Scene);
|
||||
request.ClubId = clubId;
|
||||
request.ApplicantId = applicantId;
|
||||
request.Agree = agree;
|
||||
return (S2C_DisposeJoinResponse)await session.Call(request);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void S2C_ClubChange(this Session session, S2C_ClubChange message)
|
||||
{
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void S2C_ClubChange(this Session session, ClubInfo club, int changeType)
|
||||
{
|
||||
using var message = Fantasy.S2C_ClubChange.Create(session.Scene);
|
||||
message.Club = club;
|
||||
message.ChangeType = changeType;
|
||||
session.Send(message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bb560e77a377e5e48871dc9494a3c0d3
|
||||
@@ -1,7 +1,7 @@
|
||||
using ProtoBuf;
|
||||
using System;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using NBC.Network.Interface;
|
||||
using NBC.Serialize;
|
||||
@@ -10,7 +10,7 @@ using NBC.Serialize;
|
||||
namespace NBC
|
||||
{
|
||||
[ProtoContract]
|
||||
public partial class C2A_LoginRequest : AMessage, IRequest, IProto
|
||||
public partial class C2A_LoginRequest : AMessage, IRequest
|
||||
{
|
||||
public static C2A_LoginRequest Create(Scene scene)
|
||||
{
|
||||
@@ -39,7 +39,7 @@ namespace NBC
|
||||
public int Region { get; set; }
|
||||
}
|
||||
[ProtoContract]
|
||||
public partial class A2C_LoginResponse : AMessage, IResponse, IProto
|
||||
public partial class A2C_LoginResponse : AMessage, IResponse
|
||||
{
|
||||
public static A2C_LoginResponse Create(Scene scene)
|
||||
{
|
||||
@@ -63,7 +63,7 @@ namespace NBC
|
||||
/// 客户端登录到Gate服务器
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2G_LoginRequest : AMessage, IRequest, IProto
|
||||
public partial class C2G_LoginRequest : AMessage, IRequest
|
||||
{
|
||||
public static C2G_LoginRequest Create(Scene scene)
|
||||
{
|
||||
@@ -83,7 +83,7 @@ namespace NBC
|
||||
public string ToKen { get; set; }
|
||||
}
|
||||
[ProtoContract]
|
||||
public partial class G2C_LoginResponse : AMessage, IResponse, IProto
|
||||
public partial class G2C_LoginResponse : AMessage, IResponse
|
||||
{
|
||||
public static G2C_LoginResponse Create(Scene scene)
|
||||
{
|
||||
@@ -107,7 +107,7 @@ namespace NBC
|
||||
/// 通知客户端重复登录
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class G2C_RepeatLogin : AMessage, IMessage, IProto
|
||||
public partial class G2C_RepeatLogin : AMessage, IMessage
|
||||
{
|
||||
public static G2C_RepeatLogin Create(Scene scene)
|
||||
{
|
||||
@@ -122,7 +122,7 @@ namespace NBC
|
||||
public uint OpCode() { return OuterOpcode.G2C_RepeatLogin; }
|
||||
}
|
||||
[ProtoContract]
|
||||
public partial class C2Game_GetRoleInfoRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2Game_GetRoleInfoRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2Game_GetRoleInfoRequest Create(Scene scene)
|
||||
{
|
||||
@@ -141,7 +141,7 @@ namespace NBC
|
||||
public int RouteType => Fantasy.RouteType.GameRoute;
|
||||
}
|
||||
[ProtoContract]
|
||||
public partial class Game2C_GetRoleInfoResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class Game2C_GetRoleInfoResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static Game2C_GetRoleInfoResponse Create(Scene scene)
|
||||
{
|
||||
@@ -165,3 +165,4 @@ namespace NBC
|
||||
public uint ErrorCode { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Fantasy
|
||||
namespace NBC
|
||||
{
|
||||
public static partial class OuterOpcode
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
namespace Fantasy
|
||||
namespace NBC
|
||||
{
|
||||
// Roaming协议定义(需要定义10000以上、因为10000以内的框架预留)
|
||||
public static class RoamingType
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using ProtoBuf;
|
||||
using System;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using NBC.Network.Interface;
|
||||
using NBC.Serialize;
|
||||
@@ -13,7 +13,7 @@ namespace NBC
|
||||
/// 用户进入地图
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class Map2C_RoleEnterRoomNotify : AMessage, ICustomRouteMessage, IProto
|
||||
public partial class Map2C_RoleEnterRoomNotify : AMessage, ICustomRouteMessage
|
||||
{
|
||||
public static Map2C_RoleEnterRoomNotify Create(Scene scene)
|
||||
{
|
||||
@@ -36,7 +36,7 @@ namespace NBC
|
||||
/// 用户离开地图
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class Map2C_RoleExitRoomNotify : AMessage, ICustomRouteMessage, IProto
|
||||
public partial class Map2C_RoleExitRoomNotify : AMessage, ICustomRouteMessage
|
||||
{
|
||||
public static Map2C_RoleExitRoomNotify Create(Scene scene)
|
||||
{
|
||||
@@ -56,7 +56,7 @@ namespace NBC
|
||||
public long Id { get; set; }
|
||||
}
|
||||
[ProtoContract]
|
||||
public partial class C2Map_RolePropertyChange : AMessage, ICustomRouteMessage, IProto
|
||||
public partial class C2Map_RolePropertyChange : AMessage, ICustomRouteMessage
|
||||
{
|
||||
public static C2Map_RolePropertyChange Create(Scene scene)
|
||||
{
|
||||
@@ -79,7 +79,7 @@ namespace NBC
|
||||
/// 玩家状态变化同步
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class Map2C_RoleStateNotify : AMessage, ICustomRouteMessage, IProto
|
||||
public partial class Map2C_RoleStateNotify : AMessage, ICustomRouteMessage
|
||||
{
|
||||
public static Map2C_RoleStateNotify Create(Scene scene)
|
||||
{
|
||||
@@ -105,7 +105,7 @@ namespace NBC
|
||||
/// 玩家钓组变化
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class Map2C_RoleGearChangeNotify : AMessage, ICustomRouteMessage, IProto
|
||||
public partial class Map2C_RoleGearChangeNotify : AMessage, ICustomRouteMessage
|
||||
{
|
||||
public static Map2C_RoleGearChangeNotify Create(Scene scene)
|
||||
{
|
||||
@@ -128,7 +128,7 @@ namespace NBC
|
||||
public List<GearInfo> Gears = new List<GearInfo>();
|
||||
}
|
||||
[ProtoContract]
|
||||
public partial class Map2C_RolePropertyChangeNotify : AMessage, ICustomRouteMessage, IProto
|
||||
public partial class Map2C_RolePropertyChangeNotify : AMessage, ICustomRouteMessage
|
||||
{
|
||||
public static Map2C_RolePropertyChangeNotify Create(Scene scene)
|
||||
{
|
||||
@@ -151,7 +151,7 @@ namespace NBC
|
||||
public List<KeyValueInt64> Propertys = new List<KeyValueInt64>();
|
||||
}
|
||||
[ProtoContract]
|
||||
public partial class C2Map_Move : AMessage, ICustomRouteMessage, IProto
|
||||
public partial class C2Map_Move : AMessage, ICustomRouteMessage
|
||||
{
|
||||
public static C2Map_Move Create(Scene scene)
|
||||
{
|
||||
@@ -186,7 +186,7 @@ namespace NBC
|
||||
public long Timestamp { get; set; }
|
||||
}
|
||||
[ProtoContract]
|
||||
public partial class C2Map_Look : AMessage, ICustomRouteMessage, IProto
|
||||
public partial class C2Map_Look : AMessage, ICustomRouteMessage
|
||||
{
|
||||
public static C2Map_Look Create(Scene scene)
|
||||
{
|
||||
@@ -212,7 +212,7 @@ namespace NBC
|
||||
/// 玩家移动推送
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class Map2C_MoveNotify : AMessage, ICustomRouteMessage, IProto
|
||||
public partial class Map2C_MoveNotify : AMessage, ICustomRouteMessage
|
||||
{
|
||||
public static Map2C_MoveNotify Create(Scene scene)
|
||||
{
|
||||
@@ -253,7 +253,7 @@ namespace NBC
|
||||
/// 玩家旋转推送
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class Map2C_LookeNotify : AMessage, ICustomRouteMessage, IProto
|
||||
public partial class Map2C_LookeNotify : AMessage, ICustomRouteMessage
|
||||
{
|
||||
public static Map2C_LookeNotify Create(Scene scene)
|
||||
{
|
||||
@@ -279,3 +279,4 @@ namespace NBC
|
||||
public long Timestamp { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Fantasy
|
||||
namespace NBC
|
||||
{
|
||||
// Route协议定义(需要定义1000以上、因为1000以内的框架预留)
|
||||
public static class RouteType
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using ProtoBuf;
|
||||
using System;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using NBC.Network.Interface;
|
||||
using NBC.Serialize;
|
||||
@@ -16,7 +16,7 @@ namespace NBC
|
||||
/// 会话信息
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class ConversationInfo : AMessage, IProto
|
||||
public partial class ConversationInfo : AMessage
|
||||
{
|
||||
public static ConversationInfo Create(Scene scene)
|
||||
{
|
||||
@@ -36,7 +36,7 @@ namespace NBC
|
||||
public List<MailInfo> List = new List<MailInfo>();
|
||||
}
|
||||
[ProtoContract]
|
||||
public partial class MailInfo : AMessage, IProto
|
||||
public partial class MailInfo : AMessage
|
||||
{
|
||||
public static MailInfo Create(Scene scene)
|
||||
{
|
||||
@@ -74,7 +74,7 @@ namespace NBC
|
||||
/// 请求会话列表
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2S_GetConversationsRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2S_GetConversationsRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2S_GetConversationsRequest Create(Scene scene)
|
||||
{
|
||||
@@ -96,7 +96,7 @@ namespace NBC
|
||||
/// 请求会话列表响应
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class S2C_GetConversationsResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class S2C_GetConversationsResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static S2C_GetConversationsResponse Create(Scene scene)
|
||||
{
|
||||
@@ -120,7 +120,7 @@ namespace NBC
|
||||
/// 发送邮件消息
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2S_SendMailRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2S_SendMailRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2S_SendMailRequest Create(Scene scene)
|
||||
{
|
||||
@@ -151,7 +151,7 @@ namespace NBC
|
||||
/// 发送邮件消息响应
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class S2C_SendMailResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class S2C_SendMailResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static S2C_SendMailResponse Create(Scene scene)
|
||||
{
|
||||
@@ -172,7 +172,7 @@ namespace NBC
|
||||
/// 发送删除会话消息
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2S_DeleteMailRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2S_DeleteMailRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2S_DeleteMailRequest Create(Scene scene)
|
||||
{
|
||||
@@ -197,7 +197,7 @@ namespace NBC
|
||||
/// 发送删除会话消息响应
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class S2C_DeleteMailResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class S2C_DeleteMailResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static S2C_DeleteMailResponse Create(Scene scene)
|
||||
{
|
||||
@@ -221,7 +221,7 @@ namespace NBC
|
||||
/// 新邮件推送
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class S2C_HaveMail : AMessage, ICustomRouteMessage, IProto
|
||||
public partial class S2C_HaveMail : AMessage, ICustomRouteMessage
|
||||
{
|
||||
public static S2C_HaveMail Create(Scene scene)
|
||||
{
|
||||
@@ -244,7 +244,7 @@ namespace NBC
|
||||
public string Key { get; set; }
|
||||
}
|
||||
[ProtoContract]
|
||||
public partial class S2C_MailState : AMessage, ICustomRouteMessage, IProto
|
||||
public partial class S2C_MailState : AMessage, ICustomRouteMessage
|
||||
{
|
||||
public static S2C_MailState Create(Scene scene)
|
||||
{
|
||||
@@ -270,7 +270,7 @@ namespace NBC
|
||||
/// /////////// ******** 频道聊天 *******/////////////
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class ChatUserInfo : AMessage, IProto
|
||||
public partial class ChatUserInfo : AMessage
|
||||
{
|
||||
public static ChatUserInfo Create(Scene scene)
|
||||
{
|
||||
@@ -290,7 +290,7 @@ namespace NBC
|
||||
public long Name { get; set; }
|
||||
}
|
||||
[ProtoContract]
|
||||
public partial class ChatMessageInfo : AMessage, IProto
|
||||
public partial class ChatMessageInfo : AMessage
|
||||
{
|
||||
public static ChatMessageInfo Create(Scene scene)
|
||||
{
|
||||
@@ -322,7 +322,7 @@ namespace NBC
|
||||
/// 创建频道
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2S_CreateChannelRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2S_CreateChannelRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2S_CreateChannelRequest Create(Scene scene)
|
||||
{
|
||||
@@ -347,7 +347,7 @@ namespace NBC
|
||||
/// 创建频道响应
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class S2C_CreateChannelResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class S2C_CreateChannelResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static S2C_CreateChannelResponse Create(Scene scene)
|
||||
{
|
||||
@@ -371,7 +371,7 @@ namespace NBC
|
||||
/// 请求进入频道
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2S_JoinChannelRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2S_JoinChannelRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2S_JoinChannelRequest Create(Scene scene)
|
||||
{
|
||||
@@ -396,7 +396,7 @@ namespace NBC
|
||||
/// 进入频道响应
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class S2C_JoinChannelResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class S2C_JoinChannelResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static S2C_JoinChannelResponse Create(Scene scene)
|
||||
{
|
||||
@@ -417,7 +417,7 @@ namespace NBC
|
||||
/// 发送消息
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2S_SendMessageRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2S_SendMessageRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2S_SendMessageRequest Create(Scene scene)
|
||||
{
|
||||
@@ -445,7 +445,7 @@ namespace NBC
|
||||
/// 发送消息响应
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class S2C_SendMessageResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class S2C_SendMessageResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static S2C_SendMessageResponse Create(Scene scene)
|
||||
{
|
||||
@@ -466,7 +466,7 @@ namespace NBC
|
||||
/// 推送消息
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class S2C_Message : AMessage, ICustomRouteMessage, IProto
|
||||
public partial class S2C_Message : AMessage, ICustomRouteMessage
|
||||
{
|
||||
public static S2C_Message Create(Scene scene)
|
||||
{
|
||||
@@ -489,7 +489,7 @@ namespace NBC
|
||||
/// /////////// ******** 工会 *******/////////////
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class ClubInfo : AMessage, IProto
|
||||
public partial class ClubInfo : AMessage
|
||||
{
|
||||
public static ClubInfo Create(Scene scene)
|
||||
{
|
||||
@@ -521,7 +521,7 @@ namespace NBC
|
||||
/// 请求创建工会
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2S_CreateClubRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2S_CreateClubRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2S_CreateClubRequest Create(Scene scene)
|
||||
{
|
||||
@@ -546,7 +546,7 @@ namespace NBC
|
||||
/// 创建工会响应
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class S2C_CreateClubResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class S2C_CreateClubResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static S2C_CreateClubResponse Create(Scene scene)
|
||||
{
|
||||
@@ -570,7 +570,7 @@ namespace NBC
|
||||
/// 请求工会信息
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2S_GetClubInfoRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2S_GetClubInfoRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2S_GetClubInfoRequest Create(Scene scene)
|
||||
{
|
||||
@@ -595,7 +595,7 @@ namespace NBC
|
||||
/// 响应工会信息
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class S2C_GetClubInfoResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class S2C_GetClubInfoResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static S2C_GetClubInfoResponse Create(Scene scene)
|
||||
{
|
||||
@@ -619,7 +619,7 @@ namespace NBC
|
||||
/// 请求工会成员列表
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2S_GetMemberListRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2S_GetMemberListRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2S_GetMemberListRequest Create(Scene scene)
|
||||
{
|
||||
@@ -644,7 +644,7 @@ namespace NBC
|
||||
/// 响应工会成员列表
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class S2C_GetMemberListResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class S2C_GetMemberListResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static S2C_GetMemberListResponse Create(Scene scene)
|
||||
{
|
||||
@@ -668,7 +668,7 @@ namespace NBC
|
||||
/// 获取工会列表请求
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2S_GetClubListRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2S_GetClubListRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2S_GetClubListRequest Create(Scene scene)
|
||||
{
|
||||
@@ -690,7 +690,7 @@ namespace NBC
|
||||
/// 获取工会列表响应
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class S2C_GetClubListResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class S2C_GetClubListResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static S2C_GetClubListResponse Create(Scene scene)
|
||||
{
|
||||
@@ -714,7 +714,7 @@ namespace NBC
|
||||
/// 请求加入工会
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2S_JoinClubRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2S_JoinClubRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2S_JoinClubRequest Create(Scene scene)
|
||||
{
|
||||
@@ -739,7 +739,7 @@ namespace NBC
|
||||
/// 响应加入工会
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class S2C_JoinClubResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class S2C_JoinClubResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static S2C_JoinClubResponse Create(Scene scene)
|
||||
{
|
||||
@@ -763,7 +763,7 @@ namespace NBC
|
||||
/// 请求退出工会
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2S_LeaveClubRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2S_LeaveClubRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2S_LeaveClubRequest Create(Scene scene)
|
||||
{
|
||||
@@ -788,7 +788,7 @@ namespace NBC
|
||||
/// 响应退出工会
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class S2C_LeaveClubResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class S2C_LeaveClubResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static S2C_LeaveClubResponse Create(Scene scene)
|
||||
{
|
||||
@@ -812,7 +812,7 @@ namespace NBC
|
||||
/// 请求解散工会
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2S_DissolveClubRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2S_DissolveClubRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2S_DissolveClubRequest Create(Scene scene)
|
||||
{
|
||||
@@ -837,7 +837,7 @@ namespace NBC
|
||||
/// 响应解散工会
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class S2C_DissolveClubResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class S2C_DissolveClubResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static S2C_DissolveClubResponse Create(Scene scene)
|
||||
{
|
||||
@@ -861,7 +861,7 @@ namespace NBC
|
||||
/// 请求操作申请
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2S_DisposeJoinRequest : AMessage, ICustomRouteRequest, IProto
|
||||
public partial class C2S_DisposeJoinRequest : AMessage, ICustomRouteRequest
|
||||
{
|
||||
public static C2S_DisposeJoinRequest Create(Scene scene)
|
||||
{
|
||||
@@ -892,7 +892,7 @@ namespace NBC
|
||||
/// 响应操作申请
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class S2C_DisposeJoinResponse : AMessage, ICustomRouteResponse, IProto
|
||||
public partial class S2C_DisposeJoinResponse : AMessage, ICustomRouteResponse
|
||||
{
|
||||
public static S2C_DisposeJoinResponse Create(Scene scene)
|
||||
{
|
||||
@@ -922,7 +922,7 @@ namespace NBC
|
||||
/// 推送消息
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class S2C_ClubChange : AMessage, ICustomRouteMessage, IProto
|
||||
public partial class S2C_ClubChange : AMessage, ICustomRouteMessage
|
||||
{
|
||||
public static S2C_ClubChange Create(Scene scene)
|
||||
{
|
||||
@@ -945,3 +945,4 @@ namespace NBC
|
||||
public int ChangeType { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -125,8 +125,8 @@ namespace NBF
|
||||
{
|
||||
await Task.Delay(100);
|
||||
CommonTopPanel.Show();
|
||||
// LoginPanel.Show();
|
||||
PreviewPanel.Show();
|
||||
LoginPanel.Show();
|
||||
// PreviewPanel.Show();
|
||||
}
|
||||
|
||||
#region New
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public class FantasySettingsProvider : SettingsProvider
|
||||
{
|
||||
private SerializedObject _serializedObject;
|
||||
private SerializedProperty _autoCopyAssembly;
|
||||
private SerializedProperty _hotUpdatePath;
|
||||
private SerializedProperty _hotUpdateAssemblyDefinitions;
|
||||
private SerializedProperty _linkAssemblyDefinitions;
|
||||
private SerializedProperty _includeAssembly;
|
||||
public FantasySettingsProvider() : base("Project/Fantasy Settings", SettingsScope.Project) { }
|
||||
|
||||
public override void OnActivate(string searchContext, VisualElement rootElement)
|
||||
{
|
||||
Init();
|
||||
base.OnActivate(searchContext, rootElement);
|
||||
}
|
||||
|
||||
public override void OnDeactivate()
|
||||
{
|
||||
base.OnDeactivate();
|
||||
FantasySettingsScriptableObject.Save();
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
_serializedObject?.Dispose();
|
||||
_serializedObject = new SerializedObject(FantasySettingsScriptableObject.Instance);
|
||||
_autoCopyAssembly = _serializedObject.FindProperty("autoCopyAssembly");
|
||||
_hotUpdatePath = _serializedObject.FindProperty("hotUpdatePath");
|
||||
_hotUpdateAssemblyDefinitions = _serializedObject.FindProperty("hotUpdateAssemblyDefinitions");
|
||||
_linkAssemblyDefinitions = _serializedObject.FindProperty("linkAssemblyDefinitions");
|
||||
_includeAssembly = _serializedObject.FindProperty("includeAssembly");
|
||||
}
|
||||
|
||||
public override void OnGUI(string searchContext)
|
||||
{
|
||||
if (_serializedObject == null || !_serializedObject.targetObject)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
using (CreateSettingsWindowGUIScope())
|
||||
{
|
||||
_serializedObject!.Update();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(_autoCopyAssembly);
|
||||
EditorGUILayout.PropertyField(_hotUpdatePath);
|
||||
EditorGUILayout.PropertyField(_hotUpdateAssemblyDefinitions);
|
||||
EditorGUILayout.PropertyField(_includeAssembly);
|
||||
EditorGUILayout.PropertyField(_linkAssemblyDefinitions);
|
||||
// EditorGUILayout.HelpBox("默认包括Fantasy.Unity,所以不需要再次指定。", MessageType.Info);
|
||||
|
||||
if (GUILayout.Button("GenerateLinkXml"))
|
||||
{
|
||||
LinkXmlGenerator.GenerateLinkXml();
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
_serializedObject.ApplyModifiedProperties();
|
||||
FantasySettingsScriptableObject.Save();
|
||||
EditorApplication.RepaintHierarchyWindow();
|
||||
}
|
||||
|
||||
base.OnGUI(searchContext);
|
||||
}
|
||||
}
|
||||
|
||||
private IDisposable CreateSettingsWindowGUIScope()
|
||||
{
|
||||
var unityEditorAssembly = System.Reflection.Assembly.GetAssembly(typeof(EditorWindow));
|
||||
var type = unityEditorAssembly.GetType("UnityEditor.SettingsWindow+GUIScope");
|
||||
return Activator.CreateInstance(type) as IDisposable;
|
||||
}
|
||||
|
||||
static FantasySettingsProvider _provider;
|
||||
|
||||
[SettingsProvider]
|
||||
public static SettingsProvider CreateMyCustomSettingsProvider()
|
||||
{
|
||||
if (FantasySettingsScriptableObject.Instance && _provider == null)
|
||||
{
|
||||
_provider = new FantasySettingsProvider();
|
||||
using (var so = new SerializedObject(FantasySettingsScriptableObject.Instance))
|
||||
{
|
||||
_provider.keywords = GetSearchKeywordsFromSerializedObject(so);
|
||||
}
|
||||
}
|
||||
return _provider;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using NBC.DataStructure.Collection;
|
||||
|
||||
// ReSharper disable CollectionNeverQueried.Global
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
|
||||
namespace NBC.Assembly
|
||||
{
|
||||
/// <summary>
|
||||
/// AssemblyInfo提供有关程序集和类型的信息
|
||||
/// </summary>
|
||||
public sealed class AssemblyInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 唯一标识
|
||||
/// </summary>
|
||||
public readonly long AssemblyIdentity;
|
||||
/// <summary>
|
||||
/// 获取或设置与此程序集相关联的 <see cref="Assembly"/> 实例。
|
||||
/// </summary>
|
||||
public System.Reflection.Assembly Assembly { get; private set; }
|
||||
/// <summary>
|
||||
/// 程序集类型集合,获取一个列表,包含从程序集加载的所有类型。
|
||||
/// </summary>
|
||||
public readonly List<Type> AssemblyTypeList = new List<Type>();
|
||||
/// <summary>
|
||||
/// 程序集类型分组集合,获取一个分组列表,将接口类型映射到实现这些接口的类型。
|
||||
/// </summary>
|
||||
public readonly OneToManyList<Type, Type> AssemblyTypeGroupList = new OneToManyList<Type, Type>();
|
||||
|
||||
/// <summary>
|
||||
/// 初始化 <see cref="AssemblyInfo"/> 类的新实例。
|
||||
/// </summary>
|
||||
/// <param name="assemblyIdentity"></param>
|
||||
public AssemblyInfo(long assemblyIdentity)
|
||||
{
|
||||
AssemblyIdentity = assemblyIdentity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从指定的程序集加载类型信息并进行分类。
|
||||
/// </summary>
|
||||
/// <param name="assembly">要加载信息的程序集。</param>
|
||||
public void Load(System.Reflection.Assembly assembly)
|
||||
{
|
||||
Assembly = assembly;
|
||||
var assemblyTypes = assembly.GetTypes().ToList();
|
||||
|
||||
foreach (var type in assemblyTypes)
|
||||
{
|
||||
if (type.IsAbstract || type.IsInterface)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var interfaces = type.GetInterfaces();
|
||||
|
||||
foreach (var interfaceType in interfaces)
|
||||
{
|
||||
AssemblyTypeGroupList.Add(interfaceType, type);
|
||||
}
|
||||
}
|
||||
|
||||
AssemblyTypeList.AddRange(assemblyTypes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重新加载程序集的类型信息。
|
||||
/// </summary>
|
||||
/// <param name="assembly"></param>
|
||||
public void ReLoad(System.Reflection.Assembly assembly)
|
||||
{
|
||||
Unload();
|
||||
Load(assembly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 卸载程序集的类型信息。
|
||||
/// </summary>
|
||||
public void Unload()
|
||||
{
|
||||
AssemblyTypeList.Clear();
|
||||
AssemblyTypeGroupList.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,286 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using NBC.Async;
|
||||
using NBC.Helper;
|
||||
|
||||
#pragma warning disable CS8604 // Possible null reference argument.
|
||||
#pragma warning disable CS8602 // Dereference of a possibly null reference.
|
||||
#pragma warning disable CS8603
|
||||
#pragma warning disable CS8618
|
||||
namespace NBC.Assembly
|
||||
{
|
||||
/// <summary>
|
||||
/// 管理程序集加载和卸载的帮助类。
|
||||
/// </summary>
|
||||
public static class AssemblySystem
|
||||
{
|
||||
#if FANTASY_WEBGL
|
||||
private static readonly List<IAssembly> AssemblySystems = new List<IAssembly>();
|
||||
private static readonly Dictionary<long, AssemblyInfo> AssemblyList = new Dictionary<long, AssemblyInfo>();
|
||||
#else
|
||||
private static readonly ConcurrentQueue<IAssembly> AssemblySystems = new ConcurrentQueue<IAssembly>();
|
||||
private static readonly ConcurrentDictionary<long, AssemblyInfo> AssemblyList = new ConcurrentDictionary<long, AssemblyInfo>();
|
||||
#endif
|
||||
/// <summary>
|
||||
/// 初始化 AssemblySystem。(仅限内部)
|
||||
/// </summary>
|
||||
/// <param name="assemblies"></param>
|
||||
internal static async FTask InnerInitialize(params System.Reflection.Assembly[] assemblies)
|
||||
{
|
||||
await LoadAssembly(typeof(AssemblySystem).Assembly);
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
await LoadAssembly(assembly);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载指定的程序集,并触发相应的事件。
|
||||
/// </summary>
|
||||
/// <param name="assembly">要加载的程序集。</param>
|
||||
/// <param name="isCurrentDomain">如果当前Domain中已经存在同名的Assembly,使用Domain中的程序集。</param>
|
||||
public static async FTask LoadAssembly(System.Reflection.Assembly assembly, bool isCurrentDomain = true)
|
||||
{
|
||||
if (isCurrentDomain)
|
||||
{
|
||||
var currentDomainAssemblies = System.AppDomain.CurrentDomain.GetAssemblies();
|
||||
var currentAssembly = currentDomainAssemblies.FirstOrDefault(d => d.GetName().Name == assembly.GetName().Name);
|
||||
if (currentAssembly != null)
|
||||
{
|
||||
assembly = currentAssembly;
|
||||
}
|
||||
}
|
||||
|
||||
var assemblyIdentity = AssemblyIdentity(assembly);
|
||||
|
||||
if (AssemblyList.TryGetValue(assemblyIdentity, out var assemblyInfo))
|
||||
{
|
||||
assemblyInfo.ReLoad(assembly);
|
||||
foreach (var assemblySystem in AssemblySystems)
|
||||
{
|
||||
await assemblySystem.ReLoad(assemblyIdentity);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assemblyInfo = new AssemblyInfo(assemblyIdentity);
|
||||
assemblyInfo.Load(assembly);
|
||||
AssemblyList.TryAdd(assemblyIdentity, assemblyInfo);
|
||||
foreach (var assemblySystem in AssemblySystems)
|
||||
{
|
||||
await assemblySystem.Load(assemblyIdentity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 卸载程序集
|
||||
/// </summary>
|
||||
/// <param name="assembly"></param>
|
||||
public static async FTask UnLoadAssembly(System.Reflection.Assembly assembly)
|
||||
{
|
||||
var assemblyIdentity = AssemblyIdentity(assembly);
|
||||
|
||||
if (!AssemblyList.Remove(assemblyIdentity, out var assemblyInfo))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
assemblyInfo.Unload();
|
||||
foreach (var assemblySystem in AssemblySystems)
|
||||
{
|
||||
await assemblySystem.OnUnLoad(assemblyIdentity);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将AssemblySystem接口的object注册到程序集管理中心
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
public static async FTask Register(object obj)
|
||||
{
|
||||
if (obj is not IAssembly assemblySystem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#if FANTASY_WEBGL
|
||||
AssemblySystems.Add(assemblySystem);
|
||||
#else
|
||||
AssemblySystems.Enqueue(assemblySystem);
|
||||
#endif
|
||||
foreach (var (assemblyIdentity, _) in AssemblyList)
|
||||
{
|
||||
await assemblySystem.Load(assemblyIdentity);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 程序集管理中心卸载注册的Load、ReLoad、UnLoad的接口
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
public static void UnRegister(object obj)
|
||||
{
|
||||
if (obj is not IAssembly assemblySystem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#if FANTASY_WEBGL
|
||||
AssemblySystems.Remove(assemblySystem);
|
||||
#else
|
||||
var count = AssemblySystems.Count;
|
||||
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
if (!AssemblySystems.TryDequeue(out var removeAssemblySystem))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (removeAssemblySystem == assemblySystem)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
AssemblySystems.Enqueue(removeAssemblySystem);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有已加载程序集中的所有类型。
|
||||
/// </summary>
|
||||
/// <returns>所有已加载程序集中的类型。</returns>
|
||||
public static IEnumerable<Type> ForEach()
|
||||
{
|
||||
foreach (var (_, assemblyInfo) in AssemblyList)
|
||||
{
|
||||
foreach (var type in assemblyInfo.AssemblyTypeList)
|
||||
{
|
||||
yield return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定程序集中的所有类型。
|
||||
/// </summary>
|
||||
/// <param name="assemblyIdentity">程序集唯一标识。</param>
|
||||
/// <returns>指定程序集中的类型。</returns>
|
||||
public static IEnumerable<Type> ForEach(long assemblyIdentity)
|
||||
{
|
||||
if (!AssemblyList.TryGetValue(assemblyIdentity, out var assemblyInfo))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
foreach (var type in assemblyInfo.AssemblyTypeList)
|
||||
{
|
||||
yield return type;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有已加载程序集中实现指定类型的所有类型。
|
||||
/// </summary>
|
||||
/// <param name="findType">要查找的基类或接口类型。</param>
|
||||
/// <returns>所有已加载程序集中实现指定类型的类型。</returns>
|
||||
public static IEnumerable<Type> ForEach(Type findType)
|
||||
{
|
||||
foreach (var (_, assemblyInfo) in AssemblyList)
|
||||
{
|
||||
if (!assemblyInfo.AssemblyTypeGroupList.TryGetValue(findType, out var assemblyLoad))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var type in assemblyLoad)
|
||||
{
|
||||
yield return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定程序集中实现指定类型的所有类型。
|
||||
/// </summary>
|
||||
/// <param name="assemblyIdentity">程序集唯一标识。</param>
|
||||
/// <param name="findType">要查找的基类或接口类型。</param>
|
||||
/// <returns>指定程序集中实现指定类型的类型。</returns>
|
||||
public static IEnumerable<Type> ForEach(long assemblyIdentity, Type findType)
|
||||
{
|
||||
if (!AssemblyList.TryGetValue(assemblyIdentity, out var assemblyInfo))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (!assemblyInfo.AssemblyTypeGroupList.TryGetValue(findType, out var assemblyLoad))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
foreach (var type in assemblyLoad)
|
||||
{
|
||||
yield return type;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定程序集的实例。
|
||||
/// </summary>
|
||||
/// <param name="assemblyIdentity">程序集名称。</param>
|
||||
/// <returns>指定程序集的实例,如果未加载则返回 null。</returns>
|
||||
public static System.Reflection.Assembly GetAssembly(long assemblyIdentity)
|
||||
{
|
||||
return !AssemblyList.TryGetValue(assemblyIdentity, out var assemblyInfo) ? null : assemblyInfo.Assembly;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前框架注册的Assembly
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<System.Reflection.Assembly> ForEachAssembly
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (var (_, assemblyInfo) in AssemblyList)
|
||||
{
|
||||
yield return assemblyInfo.Assembly;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据Assembly的强命名计算唯一标识。
|
||||
/// </summary>
|
||||
/// <param name="assembly"></param>
|
||||
/// <returns></returns>
|
||||
private static long AssemblyIdentity(System.Reflection.Assembly assembly)
|
||||
{
|
||||
return HashCodeHelper.ComputeHash64(assembly.GetName().Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放资源,卸载所有加载的程序集。
|
||||
/// </summary>
|
||||
public static void Dispose()
|
||||
{
|
||||
DisposeAsync().Coroutine();
|
||||
}
|
||||
|
||||
private static async FTask DisposeAsync()
|
||||
{
|
||||
foreach (var (_, assemblyInfo) in AssemblyList.ToArray())
|
||||
{
|
||||
await UnLoadAssembly(assemblyInfo.Assembly);
|
||||
}
|
||||
|
||||
AssemblyList.Clear();
|
||||
AssemblySystems.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using System;
|
||||
using NBC.Async;
|
||||
|
||||
namespace NBC.Assembly
|
||||
{
|
||||
/// <summary>
|
||||
/// 实现这个接口、会再程序集首次加载、卸载、重载的时候调用
|
||||
/// </summary>
|
||||
public interface IAssembly : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// 程序集加载时调用
|
||||
/// </summary>
|
||||
/// <param name="assemblyIdentity">程序集标识</param>
|
||||
public FTask Load(long assemblyIdentity);
|
||||
/// <summary>
|
||||
/// 程序集重新加载的时候调用
|
||||
/// </summary>
|
||||
/// <param name="assemblyIdentity">程序集标识</param>
|
||||
public FTask ReLoad(long assemblyIdentity);
|
||||
/// <summary>
|
||||
/// 卸载的时候调用
|
||||
/// </summary>
|
||||
/// <param name="assemblyIdentity">程序集标识</param>
|
||||
public FTask OnUnLoad(long assemblyIdentity);
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class BaseAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Field | AttributeTargets.Method)]
|
||||
public class SortAttribute : Attribute
|
||||
{
|
||||
public int Sort;
|
||||
|
||||
public SortAttribute(int sort)
|
||||
{
|
||||
Sort = sort;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32bc35c38967479d81a79bd1354d38e8
|
||||
timeCreated: 1733995116
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ccc2499679c40909ac59a0a325c78c4
|
||||
timeCreated: 1759160041
|
||||
@@ -1,90 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public interface IConfigContext
|
||||
{
|
||||
// 定义非泛型接口
|
||||
}
|
||||
|
||||
public class ConfigContext<T> : IConfigContext where T : IConfigTable
|
||||
{
|
||||
private static List<T> _cacheList = new List<T>();
|
||||
|
||||
#region Cache
|
||||
|
||||
public void Association(List<T> list)
|
||||
{
|
||||
if (list != null)
|
||||
{
|
||||
_cacheList = list;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public int Count()
|
||||
{
|
||||
return _cacheList.Count;
|
||||
}
|
||||
|
||||
public int Count(Func<T, bool> predicate)
|
||||
{
|
||||
return _cacheList.Count(predicate);
|
||||
}
|
||||
|
||||
public T Get(uint key)
|
||||
{
|
||||
return First(key);
|
||||
}
|
||||
|
||||
public T Fist()
|
||||
{
|
||||
return _cacheList.First();
|
||||
}
|
||||
|
||||
public T Last()
|
||||
{
|
||||
return _cacheList.Last();
|
||||
}
|
||||
|
||||
public T Fist(Predicate<T> match)
|
||||
{
|
||||
return Get(match);
|
||||
}
|
||||
|
||||
public T Last(Predicate<T> match)
|
||||
{
|
||||
return _cacheList.FindLast(match);
|
||||
}
|
||||
|
||||
public T Get(Predicate<T> match)
|
||||
{
|
||||
return _cacheList.Find(match);
|
||||
}
|
||||
|
||||
public T GetRandom()
|
||||
{
|
||||
Random random = new Random();
|
||||
// 随机从列表中取一个对象
|
||||
return _cacheList[random.Next(_cacheList.Count)];
|
||||
}
|
||||
|
||||
public List<T> GetList()
|
||||
{
|
||||
return _cacheList;
|
||||
}
|
||||
|
||||
public List<T> GetList(Predicate<T> match)
|
||||
{
|
||||
return _cacheList.FindAll(match);
|
||||
}
|
||||
|
||||
private T First(uint key)
|
||||
{
|
||||
return _cacheList.Find(t => t.Key == key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f916dd8f41b047068d570fc87f9163c2
|
||||
timeCreated: 1760064105
|
||||
@@ -1,115 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using NBC.Serialize;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置表帮助类
|
||||
/// </summary>
|
||||
public static class ConfigTableHelper
|
||||
{
|
||||
private static readonly Dictionary<Type, IConfigContext> _dictionary = new Dictionary<Type, IConfigContext>();
|
||||
|
||||
/// <summary>
|
||||
/// 初始化ConfigTableHelper
|
||||
/// </summary>
|
||||
public static void Initialize(string json)
|
||||
{
|
||||
var jsonObj = JObject.Parse(json);
|
||||
Dictionary<string, JArray> tokens = new();
|
||||
foreach (var item in jsonObj)
|
||||
{
|
||||
try
|
||||
{
|
||||
var name = item.Key;
|
||||
var value = item.Value;
|
||||
if (value is JArray jArray)
|
||||
{
|
||||
tokens[name] = jArray;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"读表异常,请检查,name={item.Key} ex={e}");
|
||||
}
|
||||
}
|
||||
|
||||
//反射获取所有IConfigTable的非抽象类
|
||||
var tableTypes = GetAllConfigTableTypes();
|
||||
foreach (var type in tableTypes)
|
||||
{
|
||||
var name = type.Name;
|
||||
if (tokens.TryGetValue(name, out var jArray))
|
||||
{
|
||||
// 通过反射调用 ParseJson 方法
|
||||
var parseMethod = type.GetMethod("ParseJson", BindingFlags.Public | BindingFlags.Static);
|
||||
parseMethod?.Invoke(null, new object[] { jArray });
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static ConfigContext<T> Table<T>() where T : IConfigTable
|
||||
{
|
||||
var type = typeof(T);
|
||||
if (_dictionary.TryGetValue(type, out var context))
|
||||
{
|
||||
return context as ConfigContext<T>;
|
||||
}
|
||||
|
||||
var jsonContext = new ConfigContext<T>();
|
||||
_dictionary[type] = jsonContext;
|
||||
return jsonContext;
|
||||
}
|
||||
|
||||
public static List<T> ParseLine<T>(JArray arr) where T : IConfigTable, new()
|
||||
{
|
||||
List<T> list = new List<T>();
|
||||
foreach (var jToken in arr)
|
||||
{
|
||||
T instance = jToken.ToObject<T>();
|
||||
|
||||
if (instance != null)
|
||||
{
|
||||
list.Add(instance);
|
||||
}
|
||||
}
|
||||
|
||||
var context = Table<T>();
|
||||
context.Association(list);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有实现了 IConfigTable 接口的非抽象类
|
||||
/// </summary>
|
||||
/// <returns>所有非抽象的配置对象类</returns>
|
||||
private static List<Type> GetAllConfigTableTypes()
|
||||
{
|
||||
var types = new List<Type>();
|
||||
var interfaceType = typeof(IConfigTable);
|
||||
|
||||
// 遍历当前程序集中的所有类型
|
||||
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
foreach (var type in assembly.GetTypes())
|
||||
{
|
||||
// 检查是否实现了 IConfigTable 接口,并且不是抽象类
|
||||
if (interfaceType.IsAssignableFrom(type) && !type.IsAbstract && !type.IsInterface)
|
||||
{
|
||||
types.Add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return types;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de53a788ec4e446eb6c07c50c65afcc2
|
||||
timeCreated: 1759160093
|
||||
@@ -1,19 +0,0 @@
|
||||
namespace NBC
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示是一个配置文件
|
||||
/// </summary>
|
||||
public interface IConfigTable
|
||||
{
|
||||
public uint Key { get; }
|
||||
}
|
||||
|
||||
public interface IConfigItemTable
|
||||
{
|
||||
public string Model { get; }
|
||||
|
||||
public string Quality { get; }
|
||||
|
||||
public string Icon { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df4eb038440a4a498e27ccaf23a1cd9b
|
||||
timeCreated: 1759160060
|
||||
@@ -1,472 +0,0 @@
|
||||
// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
using NBC.Entitas;
|
||||
using NBC.Assembly;
|
||||
using NBC.Async;
|
||||
using NBC.DataStructure.Collection;
|
||||
using NBC.Entitas.Interface;
|
||||
using NBC.Helper;
|
||||
|
||||
#pragma warning disable CS8602 // Dereference of a possibly null reference.
|
||||
#pragma warning disable CS8765 // Nullability of type of parameter doesn't match overridden member (possibly because of nullability attributes).
|
||||
|
||||
#pragma warning disable CS8604 // Possible null reference argument.
|
||||
#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type.
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
namespace NBC.Entitas
|
||||
{
|
||||
internal sealed class UpdateQueueInfo
|
||||
{
|
||||
public bool IsStop;
|
||||
public readonly Type Type;
|
||||
public readonly long RunTimeId;
|
||||
|
||||
public UpdateQueueInfo(Type type, long runTimeId)
|
||||
{
|
||||
Type = type;
|
||||
IsStop = false;
|
||||
RunTimeId = runTimeId;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class FrameUpdateQueueInfo
|
||||
{
|
||||
public readonly Type Type;
|
||||
public readonly long RunTimeId;
|
||||
|
||||
public FrameUpdateQueueInfo(Type type, long runTimeId)
|
||||
{
|
||||
Type = type;
|
||||
RunTimeId = runTimeId;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct CustomEntitiesSystemKey : IEquatable<CustomEntitiesSystemKey>
|
||||
{
|
||||
public int CustomEventType { get; }
|
||||
public Type EntitiesType { get; }
|
||||
public CustomEntitiesSystemKey(int customEventType, Type entitiesType)
|
||||
{
|
||||
CustomEventType = customEventType;
|
||||
EntitiesType = entitiesType;
|
||||
}
|
||||
public bool Equals(CustomEntitiesSystemKey other)
|
||||
{
|
||||
return CustomEventType == other.CustomEventType && EntitiesType == other.EntitiesType;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is CustomEntitiesSystemKey other && Equals(other);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(CustomEventType, EntitiesType);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Entity管理组件
|
||||
/// </summary>
|
||||
public sealed class EntityComponent : Entity, ISceneUpdate, IAssembly
|
||||
{
|
||||
private readonly OneToManyList<long, Type> _assemblyList = new();
|
||||
private readonly OneToManyList<long, Type> _assemblyHashCodes = new();
|
||||
|
||||
private readonly Dictionary<Type, IAwakeSystem> _awakeSystems = new();
|
||||
private readonly Dictionary<Type, IUpdateSystem> _updateSystems = new();
|
||||
private readonly Dictionary<Type, IDestroySystem> _destroySystems = new();
|
||||
private readonly Dictionary<Type, IDeserializeSystem> _deserializeSystems = new();
|
||||
private readonly Dictionary<Type, IFrameUpdateSystem> _frameUpdateSystem = new();
|
||||
|
||||
private readonly OneToManyList<long, CustomEntitiesSystemKey> _assemblyCustomSystemList = new();
|
||||
private readonly Dictionary<CustomEntitiesSystemKey, ICustomEntitiesSystem> _customEntitiesSystems = new Dictionary<CustomEntitiesSystemKey, ICustomEntitiesSystem>();
|
||||
|
||||
private readonly Dictionary<Type, long> _hashCodes = new Dictionary<Type, long>();
|
||||
private readonly Queue<UpdateQueueInfo> _updateQueue = new Queue<UpdateQueueInfo>();
|
||||
private readonly Queue<FrameUpdateQueueInfo> _frameUpdateQueue = new Queue<FrameUpdateQueueInfo>();
|
||||
private readonly Dictionary<long, UpdateQueueInfo> _updateQueueDic = new Dictionary<long, UpdateQueueInfo>();
|
||||
|
||||
internal async FTask<EntityComponent> Initialize()
|
||||
{
|
||||
await AssemblySystem.Register(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
#region Assembly
|
||||
|
||||
public FTask Load(long assemblyIdentity)
|
||||
{
|
||||
var task = FTask.Create(false);
|
||||
Scene?.ThreadSynchronizationContext.Post(() =>
|
||||
{
|
||||
LoadInner(assemblyIdentity);
|
||||
task.SetResult();
|
||||
});
|
||||
return task;
|
||||
}
|
||||
|
||||
public FTask ReLoad(long assemblyIdentity)
|
||||
{
|
||||
var task = FTask.Create(false);
|
||||
Scene?.ThreadSynchronizationContext.Post(() =>
|
||||
{
|
||||
OnUnLoadInner(assemblyIdentity);
|
||||
LoadInner(assemblyIdentity);
|
||||
task.SetResult();
|
||||
});
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
public FTask OnUnLoad(long assemblyIdentity)
|
||||
{
|
||||
var task = FTask.Create(false);
|
||||
Scene?.ThreadSynchronizationContext.Post(() =>
|
||||
{
|
||||
OnUnLoadInner(assemblyIdentity);
|
||||
task.SetResult();
|
||||
});
|
||||
return task;
|
||||
}
|
||||
|
||||
private void LoadInner(long assemblyIdentity)
|
||||
{
|
||||
foreach (var entityType in AssemblySystem.ForEach(assemblyIdentity, typeof(IEntity)))
|
||||
{
|
||||
_hashCodes.Add(entityType, HashCodeHelper.ComputeHash64(entityType.FullName));
|
||||
_assemblyHashCodes.Add(assemblyIdentity, entityType);
|
||||
}
|
||||
|
||||
foreach (var entitiesSystemType in AssemblySystem.ForEach(assemblyIdentity, typeof(IEntitiesSystem)))
|
||||
{
|
||||
Type entitiesType = null;
|
||||
var entity = Activator.CreateInstance(entitiesSystemType);
|
||||
|
||||
switch (entity)
|
||||
{
|
||||
case IAwakeSystem iAwakeSystem:
|
||||
{
|
||||
entitiesType = iAwakeSystem.EntitiesType();
|
||||
_awakeSystems.Add(entitiesType, iAwakeSystem);
|
||||
break;
|
||||
}
|
||||
case IDestroySystem iDestroySystem:
|
||||
{
|
||||
entitiesType = iDestroySystem.EntitiesType();
|
||||
_destroySystems.Add(entitiesType, iDestroySystem);
|
||||
break;
|
||||
}
|
||||
case IDeserializeSystem iDeserializeSystem:
|
||||
{
|
||||
entitiesType = iDeserializeSystem.EntitiesType();
|
||||
_deserializeSystems.Add(entitiesType, iDeserializeSystem);
|
||||
break;
|
||||
}
|
||||
case IUpdateSystem iUpdateSystem:
|
||||
{
|
||||
entitiesType = iUpdateSystem.EntitiesType();
|
||||
_updateSystems.Add(entitiesType, iUpdateSystem);
|
||||
break;
|
||||
}
|
||||
case IFrameUpdateSystem iFrameUpdateSystem:
|
||||
{
|
||||
entitiesType = iFrameUpdateSystem.EntitiesType();
|
||||
_frameUpdateSystem.Add(entitiesType, iFrameUpdateSystem);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Log.Error($"IEntitiesSystem not support type {entitiesSystemType}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_assemblyList.Add(assemblyIdentity, entitiesType);
|
||||
}
|
||||
|
||||
foreach (var customEntitiesSystemType in AssemblySystem.ForEach(assemblyIdentity, typeof(ICustomEntitiesSystem)))
|
||||
{
|
||||
var entity = (ICustomEntitiesSystem)Activator.CreateInstance(customEntitiesSystemType);
|
||||
var customEntitiesSystemKey = new CustomEntitiesSystemKey(entity.CustomEventType, entity.EntitiesType());
|
||||
_customEntitiesSystems.Add(customEntitiesSystemKey, entity);
|
||||
_assemblyCustomSystemList.Add(assemblyIdentity, customEntitiesSystemKey);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnUnLoadInner(long assemblyIdentity)
|
||||
{
|
||||
if (_assemblyHashCodes.TryGetValue(assemblyIdentity, out var entityType))
|
||||
{
|
||||
foreach (var type in entityType)
|
||||
{
|
||||
_hashCodes.Remove(type);
|
||||
}
|
||||
|
||||
_assemblyHashCodes.RemoveByKey(assemblyIdentity);
|
||||
}
|
||||
|
||||
if (_assemblyList.TryGetValue(assemblyIdentity, out var assembly))
|
||||
{
|
||||
foreach (var type in assembly)
|
||||
{
|
||||
_awakeSystems.Remove(type);
|
||||
_updateSystems.Remove(type);
|
||||
_destroySystems.Remove(type);
|
||||
_deserializeSystems.Remove(type);
|
||||
_frameUpdateSystem.Remove(type);
|
||||
}
|
||||
|
||||
_assemblyList.RemoveByKey(assemblyIdentity);
|
||||
}
|
||||
|
||||
if (_assemblyCustomSystemList.TryGetValue(assemblyIdentity, out var customSystemAssembly))
|
||||
{
|
||||
foreach (var customEntitiesSystemKey in customSystemAssembly)
|
||||
{
|
||||
_customEntitiesSystems.Remove(customEntitiesSystemKey);
|
||||
}
|
||||
|
||||
_assemblyCustomSystemList.RemoveByKey(assemblyIdentity);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event
|
||||
|
||||
/// <summary>
|
||||
/// 触发实体的唤醒方法
|
||||
/// </summary>
|
||||
/// <param name="entity">实体对象</param>
|
||||
public void Awake(Entity entity)
|
||||
{
|
||||
if (!_awakeSystems.TryGetValue(entity.Type, out var awakeSystem))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
awakeSystem.Invoke(entity);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"{entity.Type.FullName} Error {e}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 触发实体的销毁方法
|
||||
/// </summary>
|
||||
/// <param name="entity">实体对象</param>
|
||||
public void Destroy(Entity entity)
|
||||
{
|
||||
if (!_destroySystems.TryGetValue(entity.Type, out var system))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
system.Invoke(entity);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"{entity.Type.FullName} Destroy Error {e}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 触发实体的反序列化方法
|
||||
/// </summary>
|
||||
/// <param name="entity">实体对象</param>
|
||||
public void Deserialize(Entity entity)
|
||||
{
|
||||
if (!_deserializeSystems.TryGetValue(entity.Type, out var system))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
system.Invoke(entity);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"{entity.Type.FullName} Deserialize Error {e}");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CustomEvent
|
||||
|
||||
public void CustomSystem(Entity entity, int customEventType)
|
||||
{
|
||||
var customEntitiesSystemKey = new CustomEntitiesSystemKey(customEventType, entity.Type);
|
||||
|
||||
if (!_customEntitiesSystems.TryGetValue(customEntitiesSystemKey, out var system))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
system.Invoke(entity);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"{entity.Type.FullName} CustomSystem Error {e}");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Update
|
||||
|
||||
/// <summary>
|
||||
/// 将实体加入更新队列,准备进行更新
|
||||
/// </summary>
|
||||
/// <param name="entity">实体对象</param>
|
||||
public void StartUpdate(Entity entity)
|
||||
{
|
||||
var type = entity.Type;
|
||||
var entityRuntimeId = entity.RuntimeId;
|
||||
|
||||
if (_updateSystems.ContainsKey(type))
|
||||
{
|
||||
var updateQueueInfo = new UpdateQueueInfo(type, entityRuntimeId);
|
||||
_updateQueue.Enqueue(updateQueueInfo);
|
||||
_updateQueueDic.Add(entityRuntimeId, updateQueueInfo);
|
||||
}
|
||||
|
||||
if (_frameUpdateSystem.ContainsKey(type))
|
||||
{
|
||||
_frameUpdateQueue.Enqueue(new FrameUpdateQueueInfo(type, entityRuntimeId));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止实体进行更新
|
||||
/// </summary>
|
||||
/// <param name="entity">实体对象</param>
|
||||
public void StopUpdate(Entity entity)
|
||||
{
|
||||
if (!_updateQueueDic.Remove(entity.RuntimeId, out var updateQueueInfo))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
updateQueueInfo.IsStop = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行实体系统的更新逻辑
|
||||
/// </summary>
|
||||
public void Update()
|
||||
{
|
||||
var updateQueueCount = _updateQueue.Count;
|
||||
|
||||
while (updateQueueCount-- > 0)
|
||||
{
|
||||
var updateQueueStruct = _updateQueue.Dequeue();
|
||||
|
||||
if (updateQueueStruct.IsStop)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!_updateSystems.TryGetValue(updateQueueStruct.Type, out var updateSystem))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var entity = Scene.GetEntity(updateQueueStruct.RunTimeId);
|
||||
|
||||
if (entity == null || entity.IsDisposed)
|
||||
{
|
||||
_updateQueueDic.Remove(updateQueueStruct.RunTimeId);
|
||||
continue;
|
||||
}
|
||||
|
||||
_updateQueue.Enqueue(updateQueueStruct);
|
||||
|
||||
try
|
||||
{
|
||||
updateSystem.Invoke(entity);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"{updateQueueStruct.Type.FullName} Update Error {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行实体系统的帧更新逻辑
|
||||
/// </summary>
|
||||
public void FrameUpdate()
|
||||
{
|
||||
var count = _frameUpdateQueue.Count;
|
||||
|
||||
while (count-- > 0)
|
||||
{
|
||||
var frameUpdateQueueStruct = _frameUpdateQueue.Dequeue();
|
||||
|
||||
if (!_frameUpdateSystem.TryGetValue(frameUpdateQueueStruct.Type, out var frameUpdateSystem))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var entity = Scene.GetEntity(frameUpdateQueueStruct.RunTimeId);
|
||||
|
||||
if (entity == null || entity.IsDisposed)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_frameUpdateQueue.Enqueue(frameUpdateQueueStruct);
|
||||
|
||||
try
|
||||
{
|
||||
frameUpdateSystem.Invoke(entity);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"{frameUpdateQueueStruct.Type.FullName} FrameUpdate Error {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public long GetHashCode(Type type)
|
||||
{
|
||||
return _hashCodes[type];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放实体系统管理器资源
|
||||
/// </summary>
|
||||
public override void Dispose()
|
||||
{
|
||||
_updateQueue.Clear();
|
||||
_frameUpdateQueue.Clear();
|
||||
|
||||
_assemblyList.Clear();
|
||||
_awakeSystems.Clear();
|
||||
_updateSystems.Clear();
|
||||
_destroySystems.Clear();
|
||||
_deserializeSystems.Clear();
|
||||
_frameUpdateSystem.Clear();
|
||||
|
||||
AssemblySystem.UnRegister(this);
|
||||
base.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,255 +0,0 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using NBC.Assembly;
|
||||
using NBC.Async;
|
||||
using NBC.DataStructure.Collection;
|
||||
using NBC.Entitas;
|
||||
|
||||
// ReSharper disable PossibleMultipleEnumeration
|
||||
#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type.
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
// ReSharper disable MethodOverloadWithOptionalParameter
|
||||
|
||||
namespace NBC.Event
|
||||
{
|
||||
internal sealed class EventCache
|
||||
{
|
||||
public readonly Type EnventType;
|
||||
public readonly object Obj;
|
||||
public EventCache(Type enventType, object obj)
|
||||
{
|
||||
EnventType = enventType;
|
||||
Obj = obj;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class EventComponent : Entity, IAssembly
|
||||
{
|
||||
private readonly OneToManyList<Type, IEvent> _events = new();
|
||||
private readonly OneToManyList<Type, IAsyncEvent> _asyncEvents = new();
|
||||
private readonly OneToManyList<long, EventCache> _assemblyEvents = new();
|
||||
private readonly OneToManyList<long, EventCache> _assemblyAsyncEvents = new();
|
||||
|
||||
internal async FTask<EventComponent> Initialize()
|
||||
{
|
||||
await AssemblySystem.Register(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
#region Assembly
|
||||
|
||||
public async FTask Load(long assemblyIdentity)
|
||||
{
|
||||
var tcs = FTask.Create(false);
|
||||
Scene?.ThreadSynchronizationContext.Post(() =>
|
||||
{
|
||||
LoadInner(assemblyIdentity);
|
||||
tcs.SetResult();
|
||||
});
|
||||
await tcs;
|
||||
}
|
||||
|
||||
public async FTask ReLoad(long assemblyIdentity)
|
||||
{
|
||||
var tcs = FTask.Create(false);
|
||||
Scene?.ThreadSynchronizationContext.Post(() =>
|
||||
{
|
||||
OnUnLoadInner(assemblyIdentity);
|
||||
LoadInner(assemblyIdentity);
|
||||
tcs.SetResult();
|
||||
});
|
||||
await tcs;
|
||||
}
|
||||
|
||||
public async FTask OnUnLoad(long assemblyIdentity)
|
||||
{
|
||||
var tcs = FTask.Create(false);
|
||||
Scene?.ThreadSynchronizationContext.Post(() =>
|
||||
{
|
||||
OnUnLoadInner(assemblyIdentity);
|
||||
tcs.SetResult();
|
||||
});
|
||||
await tcs;
|
||||
}
|
||||
|
||||
private void LoadInner(long assemblyIdentity)
|
||||
{
|
||||
|
||||
foreach (var type in AssemblySystem.ForEach(assemblyIdentity, typeof(IEvent)))
|
||||
{
|
||||
var @event = (IEvent)Activator.CreateInstance(type);
|
||||
|
||||
if (@event == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var eventType = @event.EventType();
|
||||
_events.Add(eventType, @event);
|
||||
_assemblyEvents.Add(assemblyIdentity, new EventCache(eventType, @event));
|
||||
}
|
||||
_events.SortAll();
|
||||
|
||||
foreach (var type in AssemblySystem.ForEach(assemblyIdentity, typeof(IAsyncEvent)))
|
||||
{
|
||||
var @event = (IAsyncEvent)Activator.CreateInstance(type);
|
||||
|
||||
if (@event == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var eventType = @event.EventType();
|
||||
_asyncEvents.Add(eventType, @event);
|
||||
_assemblyAsyncEvents.Add(assemblyIdentity, new EventCache(eventType, @event));
|
||||
}
|
||||
_asyncEvents.SortAll();
|
||||
}
|
||||
|
||||
private void OnUnLoadInner(long assemblyIdentity)
|
||||
{
|
||||
if (_assemblyEvents.TryGetValue(assemblyIdentity, out var events))
|
||||
{
|
||||
foreach (var @event in events)
|
||||
{
|
||||
_events.RemoveValue(@event.EnventType, (IEvent)@event.Obj);
|
||||
}
|
||||
|
||||
_assemblyEvents.RemoveByKey(assemblyIdentity);
|
||||
}
|
||||
|
||||
if (_assemblyAsyncEvents.TryGetValue(assemblyIdentity, out var asyncEvents))
|
||||
{
|
||||
foreach (var @event in asyncEvents)
|
||||
{
|
||||
_asyncEvents.RemoveValue(@event.EnventType, (IAsyncEvent)@event.Obj);
|
||||
}
|
||||
|
||||
_assemblyAsyncEvents.RemoveByKey(assemblyIdentity);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Publish
|
||||
|
||||
/// <summary>
|
||||
/// 发布一个值类型的事件数据。
|
||||
/// </summary>
|
||||
/// <typeparam name="TEventData">事件数据类型(值类型)。</typeparam>
|
||||
/// <param name="eventData">事件数据实例。</param>
|
||||
public void Publish<TEventData>(TEventData eventData) where TEventData : struct
|
||||
{
|
||||
if (!_events.TryGetValue(typeof(TEventData), out var list))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var @event in list)
|
||||
{
|
||||
try
|
||||
{
|
||||
@event.Invoke(eventData);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发布一个继承自 Entity 的事件数据。
|
||||
/// </summary>
|
||||
/// <typeparam name="TEventData">事件数据类型(继承自 Entity)。</typeparam>
|
||||
/// <param name="eventData">事件数据实例。</param>
|
||||
/// <param name="isDisposed">是否释放事件数据。</param>
|
||||
public void Publish<TEventData>(TEventData eventData, bool isDisposed = true) where TEventData : Entity
|
||||
{
|
||||
if (!_events.TryGetValue(typeof(TEventData), out var list))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var @event in list)
|
||||
{
|
||||
try
|
||||
{
|
||||
@event.Invoke(eventData);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
if (isDisposed)
|
||||
{
|
||||
eventData.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步发布一个值类型的事件数据。
|
||||
/// </summary>
|
||||
/// <typeparam name="TEventData">事件数据类型(值类型)。</typeparam>
|
||||
/// <param name="eventData">事件数据实例。</param>
|
||||
/// <returns>表示异步操作的任务。</returns>
|
||||
public async FTask PublishAsync<TEventData>(TEventData eventData) where TEventData : struct
|
||||
{
|
||||
if (!_asyncEvents.TryGetValue(typeof(TEventData), out var list))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var tasks = ListPool<FTask>.Create();
|
||||
|
||||
foreach (var @event in list)
|
||||
{
|
||||
tasks.Add(@event.InvokeAsync(eventData));
|
||||
}
|
||||
|
||||
await FTask.WaitAll(tasks);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步发布一个继承自 Entity 的事件数据。
|
||||
/// </summary>
|
||||
/// <typeparam name="TEventData">事件数据类型(继承自 Entity)。</typeparam>
|
||||
/// <param name="eventData">事件数据实例。</param>
|
||||
/// <param name="isDisposed">是否释放事件数据。</param>
|
||||
/// <returns>表示异步操作的任务。</returns>
|
||||
public async FTask PublishAsync<TEventData>(TEventData eventData, bool isDisposed = true) where TEventData : Entity
|
||||
{
|
||||
if (!_asyncEvents.TryGetValue(eventData.GetType(), out var list))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var tasks = ListPool<FTask>.Create();
|
||||
|
||||
foreach (var @event in list)
|
||||
{
|
||||
tasks.Add(@event.InvokeAsync(eventData));
|
||||
}
|
||||
|
||||
await FTask.WaitAll(tasks);
|
||||
|
||||
if (isDisposed)
|
||||
{
|
||||
eventData.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
_events.Clear();
|
||||
_asyncEvents.Clear();
|
||||
_assemblyEvents.Clear();
|
||||
_assemblyAsyncEvents.Clear();
|
||||
base.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
using System;
|
||||
using NBC.Async;
|
||||
|
||||
namespace NBC.Event
|
||||
{
|
||||
/// <summary>
|
||||
/// 事件的接口
|
||||
/// </summary>
|
||||
public interface IEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// 用于指定事件的Type
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Type EventType();
|
||||
/// <summary>
|
||||
/// 时间内部使用的入口
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
void Invoke(object self);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步事件的接口
|
||||
/// </summary>
|
||||
public interface IAsyncEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="IEvent.EventType"/>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Type EventType();
|
||||
/// <summary>
|
||||
/// <see cref="IEvent.Invoke"/>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
FTask InvokeAsync(object self);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 事件的抽象类,要使用事件必须要继承这个抽象接口。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要监听的事件泛型类型</typeparam>
|
||||
public abstract class EventSystem<T> : IEvent
|
||||
{
|
||||
private readonly Type _selfType = typeof(T);
|
||||
/// <summary>
|
||||
/// <see cref="IEvent.EventType"/>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Type EventType()
|
||||
{
|
||||
return _selfType;
|
||||
}
|
||||
/// <summary>
|
||||
/// 事件调用的方法,要在这个方法里编写事件发生的逻辑
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
protected abstract void Handler(T self);
|
||||
/// <summary>
|
||||
/// <see cref="IEvent.Invoke"/>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public void Invoke(object self)
|
||||
{
|
||||
try
|
||||
{
|
||||
Handler((T) self);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"{_selfType.Name} Error {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 异步事件的抽象类,要使用事件必须要继承这个抽象接口。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要监听的事件泛型类型</typeparam>
|
||||
public abstract class AsyncEventSystem<T> : IAsyncEvent
|
||||
{
|
||||
private readonly Type _selfType = typeof(T);
|
||||
/// <summary>
|
||||
/// <see cref="IEvent.EventType"/>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Type EventType()
|
||||
{
|
||||
return _selfType;
|
||||
}
|
||||
/// <summary>
|
||||
/// 事件调用的方法,要在这个方法里编写事件发生的逻辑
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
protected abstract FTask Handler(T self);
|
||||
/// <summary>
|
||||
/// <see cref="IEvent.Invoke"/>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async FTask InvokeAsync(object self)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Handler((T) self);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"{_selfType.Name} Error {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
namespace NBC.Entitas.Interface
|
||||
{
|
||||
/// <summary>
|
||||
/// Entity保存到数据库的时候会根据子组件设置分离存储特性分表存储在不同的集合表中
|
||||
/// </summary>
|
||||
public interface ISingleCollectionRoot { }
|
||||
public static class SingleCollectionRootChecker<T> where T : Entity
|
||||
{
|
||||
public static bool IsSupported { get; }
|
||||
|
||||
static SingleCollectionRootChecker()
|
||||
{
|
||||
IsSupported = typeof(ISingleCollectionRoot).IsAssignableFrom(typeof(T));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
namespace NBC.Entitas.Interface
|
||||
{
|
||||
/// <summary>
|
||||
/// Entity支持数据库
|
||||
/// </summary>
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public interface ISupportedDataBase { }
|
||||
|
||||
public static class SupportedDataBaseChecker<T> where T : Entity
|
||||
{
|
||||
public static bool IsSupported { get; }
|
||||
|
||||
static SupportedDataBaseChecker()
|
||||
{
|
||||
IsSupported = typeof(ISupportedDataBase).IsAssignableFrom(typeof(T));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae64989e8b146443e99c66290b20a3c8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,20 +0,0 @@
|
||||
using System;
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
namespace NBC.Entitas.Interface
|
||||
{
|
||||
/// <summary>
|
||||
/// 支持再一个组件里添加多个同类型组件
|
||||
/// </summary>
|
||||
public interface ISupportedMultiEntity : IDisposable { }
|
||||
|
||||
public static class SupportedMultiEntityChecker<T> where T : Entity
|
||||
{
|
||||
public static bool IsSupported { get; }
|
||||
|
||||
static SupportedMultiEntityChecker()
|
||||
{
|
||||
IsSupported = typeof(ISupportedMultiEntity).IsAssignableFrom(typeof(T));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 36105e7ed5c974fdabf37eead97ef95c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,47 +0,0 @@
|
||||
using System;
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
namespace NBC.Entitas.Interface
|
||||
{
|
||||
// Entity是单一集合、保存到数据库的时候不会跟随父组件保存在一个集合里、会单独保存在一个集合里
|
||||
// 需要配合SingleCollectionAttribute一起使用、如在Entity类头部定义SingleCollectionAttribute(typeOf(Unit))
|
||||
// SingleCollectionAttribute用来定义这个Entity是属于哪个Entity的子集
|
||||
/// <summary>
|
||||
/// 定义实体支持单一集合存储的接口。当实体需要单独存储在一个集合中,并且在保存到数据库时不会与父组件一起保存在同一个集合中时,应实现此接口。
|
||||
/// </summary>
|
||||
public interface ISupportedSingleCollection { }
|
||||
public static class SupportedSingleCollectionChecker<T> where T : Entity
|
||||
{
|
||||
public static bool IsSupported { get; }
|
||||
|
||||
static SupportedSingleCollectionChecker()
|
||||
{
|
||||
IsSupported = typeof(ISupportedSingleCollection).IsAssignableFrom(typeof(T));
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 表示用于指定实体的单一集合存储属性。此属性用于配合 <see cref="ISupportedSingleCollection"/> 接口使用,
|
||||
/// 用于定义实体属于哪个父实体的子集合,以及在数据库中使用的集合名称。
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
|
||||
public class SingleCollectionAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取父实体的类型,指示此实体是属于哪个父实体的子集合。
|
||||
/// </summary>
|
||||
public readonly Type RootType;
|
||||
/// <summary>
|
||||
/// 获取在数据库中使用的集合名称。
|
||||
/// </summary>
|
||||
public readonly string CollectionName;
|
||||
/// <summary>
|
||||
/// 初始化 <see cref="SingleCollectionAttribute"/> 类的新实例,指定父实体类型和集合名称。
|
||||
/// </summary>
|
||||
/// <param name="rootType">父实体的类型。</param>
|
||||
/// <param name="collectionName">在数据库中使用的集合名称。</param>
|
||||
public SingleCollectionAttribute(Type rootType, string collectionName)
|
||||
{
|
||||
RootType = rootType;
|
||||
CollectionName = collectionName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: afd453d04ac254206a9bb83664a888a0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,16 +0,0 @@
|
||||
namespace NBC.Entitas.Interface
|
||||
{
|
||||
/// <summary>
|
||||
/// Entity支持传送
|
||||
/// </summary>
|
||||
public interface ISupportedTransfer { }
|
||||
public static class SupportedTransferChecker<T> where T : Entity
|
||||
{
|
||||
public static bool IsSupported { get; }
|
||||
|
||||
static SupportedTransferChecker()
|
||||
{
|
||||
IsSupported = typeof(ISupportedTransfer).IsAssignableFrom(typeof(T));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a127a7c6e345a42e3860b804457f0fe5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8babd948f5d51430db4d8ac333b25d54
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 287ae5e33ccda4c28946371bcad4755b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,31 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace NBC.Entitas.Interface
|
||||
{
|
||||
internal interface IFrameUpdateSystem : IEntitiesSystem { }
|
||||
/// <summary>
|
||||
/// 帧更新时间的抽象接口
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public abstract class FrameUpdateSystem<T> : IFrameUpdateSystem where T : Entity
|
||||
{
|
||||
/// <summary>
|
||||
/// 实体的类型
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Type EntitiesType() => typeof(T);
|
||||
/// <summary>
|
||||
/// 事件的抽象方法,需要自己实现这个方法
|
||||
/// </summary>
|
||||
/// <param name="self">触发事件的实体实例</param>
|
||||
protected abstract void FrameUpdate(T self);
|
||||
/// <summary>
|
||||
/// 框架内部调用的触发FrameUpdate的方法
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
public void Invoke(Entity self)
|
||||
{
|
||||
FrameUpdate((T) self);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b785fffadcd8c4461b1f1fcf397728b9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,344 +0,0 @@
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using NBC.Async;
|
||||
|
||||
namespace NBC.Helper
|
||||
{
|
||||
/// <summary>
|
||||
/// 提供字节操作辅助方法的静态类。
|
||||
/// </summary>
|
||||
public static class ByteHelper
|
||||
{
|
||||
private static readonly string[] Suffix = { "Byte", "KB", "MB", "GB", "TB" };
|
||||
|
||||
/// <summary>
|
||||
/// 从指定的文件流中读取一个 64 位整数。
|
||||
/// </summary>
|
||||
public static long ReadInt64(FileStream stream)
|
||||
{
|
||||
var buffer = new byte[8];
|
||||
stream.Read(buffer, 0, 8);
|
||||
return BitConverter.ToInt64(buffer, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从指定的文件流中读取一个 32 位整数。
|
||||
/// </summary>
|
||||
public static int ReadInt32(FileStream stream)
|
||||
{
|
||||
var buffer = new byte[4];
|
||||
stream.Read(buffer, 0, 4);
|
||||
return BitConverter.ToInt32(buffer, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从指定的内存流中读取一个 64 位整数。
|
||||
/// </summary>
|
||||
public static long ReadInt64(MemoryStream stream)
|
||||
{
|
||||
var buffer = new byte[8];
|
||||
stream.Read(buffer, 0, 8);
|
||||
return BitConverter.ToInt64(buffer, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从指定的内存流中读取一个 32 位整数。
|
||||
/// </summary>
|
||||
public static int ReadInt32(MemoryStream stream)
|
||||
{
|
||||
var buffer = new byte[4];
|
||||
stream.Read(buffer, 0, 4);
|
||||
return BitConverter.ToInt32(buffer, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将字节转换为十六进制字符串表示。
|
||||
/// </summary>
|
||||
public static string ToHex(this byte b)
|
||||
{
|
||||
return b.ToString("X2");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将字节数组转换为十六进制字符串表示。
|
||||
/// </summary>
|
||||
public static string ToHex(this byte[] bytes)
|
||||
{
|
||||
var stringBuilder = new StringBuilder();
|
||||
foreach (var b in bytes)
|
||||
{
|
||||
stringBuilder.Append(b.ToString("X2"));
|
||||
}
|
||||
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将字节数组按指定格式转换为十六进制字符串表示。
|
||||
/// </summary>
|
||||
public static string ToHex(this byte[] bytes, string format)
|
||||
{
|
||||
var stringBuilder = new StringBuilder();
|
||||
foreach (var b in bytes)
|
||||
{
|
||||
stringBuilder.Append(b.ToString(format));
|
||||
}
|
||||
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将字节数组的指定范围按十六进制格式转换为字符串表示。
|
||||
/// </summary>
|
||||
public static string ToHex(this byte[] bytes, int offset, int count)
|
||||
{
|
||||
var stringBuilder = new StringBuilder();
|
||||
for (var i = offset; i < offset + count; ++i)
|
||||
{
|
||||
stringBuilder.Append(bytes[i].ToString("X2"));
|
||||
}
|
||||
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将字节数组转换为默认编码的字符串表示。
|
||||
/// </summary>
|
||||
public static string ToStr(this byte[] bytes)
|
||||
{
|
||||
return Encoding.Default.GetString(bytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将字节数组的指定范围按默认编码转换为字符串表示。
|
||||
/// </summary>
|
||||
public static string ToStr(this byte[] bytes, int index, int count)
|
||||
{
|
||||
return Encoding.Default.GetString(bytes, index, count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将字节数组转换为 UTF-8 编码的字符串表示。
|
||||
/// </summary>
|
||||
public static string Utf8ToStr(this byte[] bytes)
|
||||
{
|
||||
return Encoding.UTF8.GetString(bytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将字节数组的指定范围按 UTF-8 编码转换为字符串表示。
|
||||
/// </summary>
|
||||
public static string Utf8ToStr(this byte[] bytes, int index, int count)
|
||||
{
|
||||
return Encoding.UTF8.GetString(bytes, index, count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将无符号整数写入字节数组的指定偏移位置。
|
||||
/// </summary>
|
||||
public static void WriteTo(this byte[] bytes, int offset, uint num)
|
||||
{
|
||||
bytes[offset] = (byte)(num & 0xff);
|
||||
bytes[offset + 1] = (byte)((num & 0xff00) >> 8);
|
||||
bytes[offset + 2] = (byte)((num & 0xff0000) >> 16);
|
||||
bytes[offset + 3] = (byte)((num & 0xff000000) >> 24);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将有符号整数写入字节数组的指定偏移位置。
|
||||
/// </summary>
|
||||
public static void WriteTo(this byte[] bytes, int offset, int num)
|
||||
{
|
||||
bytes[offset] = (byte)(num & 0xff);
|
||||
bytes[offset + 1] = (byte)((num & 0xff00) >> 8);
|
||||
bytes[offset + 2] = (byte)((num & 0xff0000) >> 16);
|
||||
bytes[offset + 3] = (byte)((num & 0xff000000) >> 24);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将字节写入字节数组的指定偏移位置。
|
||||
/// </summary>
|
||||
public static void WriteTo(this byte[] bytes, int offset, byte num)
|
||||
{
|
||||
bytes[offset] = num;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将有符号短整数写入字节数组的指定偏移位置。
|
||||
/// </summary>
|
||||
public static void WriteTo(this byte[] bytes, int offset, short num)
|
||||
{
|
||||
bytes[offset] = (byte)(num & 0xff);
|
||||
bytes[offset + 1] = (byte)((num & 0xff00) >> 8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将无符号短整数写入字节数组的指定偏移位置。
|
||||
/// </summary>
|
||||
public static void WriteTo(this byte[] bytes, int offset, ushort num)
|
||||
{
|
||||
bytes[offset] = (byte)(num & 0xff);
|
||||
bytes[offset + 1] = (byte)((num & 0xff00) >> 8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将字节数转换为可读的速度表示。
|
||||
/// </summary>
|
||||
/// <param name="byteCount">字节数</param>
|
||||
/// <returns>可读的速度表示</returns>
|
||||
public static string ToReadableSpeed(this long byteCount)
|
||||
{
|
||||
var i = 0;
|
||||
double dblSByte = byteCount;
|
||||
if (byteCount <= 1024)
|
||||
{
|
||||
return $"{dblSByte:0.##}{Suffix[i]}";
|
||||
}
|
||||
|
||||
for (i = 0; byteCount / 1024 > 0; i++, byteCount /= 1024)
|
||||
{
|
||||
dblSByte = byteCount / 1024.0;
|
||||
}
|
||||
|
||||
return $"{dblSByte:0.##}{Suffix[i]}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将字节数转换为可读的速度表示。
|
||||
/// </summary>
|
||||
/// <param name="byteCount">字节数</param>
|
||||
/// <returns>可读的速度表示</returns>
|
||||
public static string ToReadableSpeed(this ulong byteCount)
|
||||
{
|
||||
var i = 0;
|
||||
double dblSByte = byteCount;
|
||||
|
||||
if (byteCount <= 1024)
|
||||
{
|
||||
return $"{dblSByte:0.##}{Suffix[i]}";
|
||||
}
|
||||
|
||||
for (i = 0; byteCount / 1024 > 0; i++, byteCount /= 1024)
|
||||
{
|
||||
dblSByte = byteCount / 1024.0;
|
||||
}
|
||||
|
||||
return $"{dblSByte:0.##}{Suffix[i]}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 合并两个字节数组。
|
||||
/// </summary>
|
||||
/// <param name="bytes">第一个字节数组</param>
|
||||
/// <param name="otherBytes">第二个字节数组</param>
|
||||
/// <returns>合并后的字节数组</returns>
|
||||
public static byte[] MergeBytes(byte[] bytes, byte[] otherBytes)
|
||||
{
|
||||
var result = new byte[bytes.Length + otherBytes.Length];
|
||||
bytes.CopyTo(result, 0);
|
||||
otherBytes.CopyTo(result, bytes.Length);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据int值获取字节数组。
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="buffer"></param>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void GetBytes(this int value, byte[] buffer)
|
||||
{
|
||||
if (buffer.Length < 4)
|
||||
{
|
||||
throw new ArgumentException("Buffer too small.");
|
||||
}
|
||||
|
||||
MemoryMarshal.Write(buffer.AsSpan(), ref value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据int值获取字节数组。
|
||||
/// </summary>
|
||||
/// <param name="memoryStream"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void WriteBytes(this MemoryStream memoryStream, int value)
|
||||
{
|
||||
using var memoryOwner = MemoryPool<byte>.Shared.Rent(4);
|
||||
var memorySpan = memoryOwner.Memory.Span;
|
||||
|
||||
MemoryMarshal.Write(memorySpan, ref value);
|
||||
memoryStream.Write(memorySpan);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据uint值获取字节数组。
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="buffer"></param>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void GetBytes(ref this uint value, byte[] buffer)
|
||||
{
|
||||
if (buffer.Length < 4)
|
||||
{
|
||||
throw new ArgumentException("Buffer too small.");
|
||||
}
|
||||
|
||||
MemoryMarshal.Write(buffer.AsSpan(), ref value);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据uint值获取字节数组。
|
||||
/// </summary>
|
||||
/// <param name="memoryStream"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void WriteBytes(this MemoryStream memoryStream, uint value)
|
||||
{
|
||||
using var memoryOwner = MemoryPool<byte>.Shared.Rent(4);
|
||||
var memorySpan = memoryOwner.Memory.Span;
|
||||
MemoryMarshal.Write(memorySpan, ref value);
|
||||
memoryStream.Write(memorySpan);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据int值获取字节数组。
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="buffer"></param>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void GetBytes(this long value, byte[] buffer)
|
||||
{
|
||||
if (buffer.Length < 8)
|
||||
{
|
||||
throw new ArgumentException("Buffer too small.");
|
||||
}
|
||||
MemoryMarshal.Write(buffer.AsSpan(), ref value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据uint值获取字节数组。
|
||||
/// </summary>
|
||||
/// <param name="memoryStream"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void WriteBytes(this MemoryStream memoryStream, long value)
|
||||
{
|
||||
using var memoryOwner = MemoryPool<byte>.Shared.Rent(8);
|
||||
var memorySpan = memoryOwner.Memory.Span;
|
||||
MemoryMarshal.Write(memorySpan, ref value);
|
||||
memoryStream.Write(memorySpan);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
// ReSharper disable InconsistentNaming
|
||||
|
||||
namespace NBC.Helper
|
||||
{
|
||||
/// <summary>
|
||||
/// HashCode算法帮助类
|
||||
/// </summary>
|
||||
public static partial class HashCodeHelper
|
||||
{
|
||||
private static readonly SHA256 Sha256Hash = SHA256.Create();
|
||||
|
||||
/// <summary>
|
||||
/// 计算两个字符串的HashCode
|
||||
/// </summary>
|
||||
/// <param name="a"></param>
|
||||
/// <param name="b"></param>
|
||||
/// <returns></returns>
|
||||
public static int GetHashCode(string a, string b)
|
||||
{
|
||||
var hash = 17;
|
||||
hash = hash * 31 + a.GetHashCode();
|
||||
hash = hash * 31 + b.GetHashCode();
|
||||
return hash;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用bkdr算法生成一个long的值
|
||||
/// </summary>
|
||||
/// <param name="str"></param>
|
||||
/// <returns></returns>
|
||||
public static unsafe long GetBKDRHashCode(string str)
|
||||
{
|
||||
ulong hash = 0;
|
||||
// 如果要修改这个种子、建议选择一个质数来做种子
|
||||
const uint seed = 13131; // 31 131 1313 13131 131313 etc..
|
||||
fixed (char* p = str)
|
||||
{
|
||||
for (var i = 0; i < str.Length; i++)
|
||||
{
|
||||
var c = p[i];
|
||||
var high = (byte)(c >> 8);
|
||||
var low = (byte)(c & byte.MaxValue);
|
||||
hash = hash * seed + high;
|
||||
hash = hash * seed + low;
|
||||
}
|
||||
}
|
||||
return (long)hash;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用MurmurHash3算法生成一个uint的值
|
||||
/// </summary>
|
||||
/// <param name="str"></param>
|
||||
/// <returns></returns>
|
||||
public static unsafe uint MurmurHash3(string str)
|
||||
{
|
||||
const uint seed = 0xc58f1a7b;
|
||||
uint hash = seed;
|
||||
uint c1 = 0xcc9e2d51;
|
||||
uint c2 = 0x1b873593;
|
||||
|
||||
fixed (char* p = str)
|
||||
{
|
||||
var current = p;
|
||||
|
||||
for (var i = 0; i < str.Length; i++)
|
||||
{
|
||||
var k1 = (uint)(*current);
|
||||
k1 *= c1;
|
||||
k1 = (k1 << 15) | (k1 >> (32 - 15));
|
||||
k1 *= c2;
|
||||
|
||||
hash ^= k1;
|
||||
hash = (hash << 13) | (hash >> (32 - 13));
|
||||
hash = hash * 5 + 0xe6546b64;
|
||||
|
||||
current++;
|
||||
}
|
||||
}
|
||||
|
||||
hash ^= (uint)str.Length;
|
||||
hash ^= hash >> 16;
|
||||
hash *= 0x85ebca6b;
|
||||
hash ^= hash >> 13;
|
||||
hash *= 0xc2b2ae35;
|
||||
hash ^= hash >> 16;
|
||||
return hash;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用MurmurHash3算法生成一个long的值
|
||||
/// </summary>
|
||||
/// <param name="str"></param>
|
||||
/// <returns></returns>
|
||||
public static unsafe long ComputeHash64(string str)
|
||||
{
|
||||
const ulong seed = 0xc58f1a7bc58f1a7bUL; // 64-bit seed
|
||||
var hash = seed;
|
||||
var c1 = 0x87c37b91114253d5UL;
|
||||
var c2 = 0x4cf5ad432745937fUL;
|
||||
|
||||
fixed (char* p = str)
|
||||
{
|
||||
var current = p;
|
||||
|
||||
for (var i = 0; i < str.Length; i++)
|
||||
{
|
||||
var k1 = (ulong)(*current);
|
||||
k1 *= c1;
|
||||
k1 = (k1 << 31) | (k1 >> (64 - 31));
|
||||
k1 *= c2;
|
||||
|
||||
hash ^= k1;
|
||||
hash = (hash << 27) | (hash >> (64 - 27));
|
||||
hash = hash * 5 + 0x52dce729;
|
||||
|
||||
current++;
|
||||
}
|
||||
}
|
||||
|
||||
hash ^= (ulong)str.Length;
|
||||
hash ^= hash >> 33;
|
||||
hash *= 0xff51afd7ed558ccdUL;
|
||||
hash ^= hash >> 33;
|
||||
hash *= 0xc4ceb9fe1a85ec53UL;
|
||||
hash ^= hash >> 33;
|
||||
return (long)hash;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据字符串计算一个Hash值
|
||||
/// </summary>
|
||||
/// <param name="rawData"></param>
|
||||
/// <returns></returns>
|
||||
public static int ComputeSha256HashAsInt(string rawData)
|
||||
{
|
||||
var bytes = Sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(rawData));
|
||||
return (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using NBC.Helper;
|
||||
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
namespace NBC.IdFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示一个运行时的ID。
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct RuntimeIdStruct
|
||||
{
|
||||
// RuntimeId:23 + 8 + 8 + 25 = 64
|
||||
// +-------------------+-----------------------------+--------------------------------------+
|
||||
// | time(23) 最大60天 | SceneId(16) 最多65535个Scene | sequence(25) 每秒每个进程能生产33554431个
|
||||
// +-------------------+-----------------------------+--------------------------------------+
|
||||
public uint Time { get; private set; }
|
||||
public uint SceneId { get; private set; }
|
||||
public uint Sequence { get; private set; }
|
||||
|
||||
public const uint MaskSequence = 0x1FFFFFF;
|
||||
public const uint MaskSceneId = 0xFFFF;
|
||||
public const uint MaskTime = 0x7FFFFF;
|
||||
|
||||
/// <summary>
|
||||
/// RuntimeIdStruct(如果超过下面参数的设定该ID会失效)。
|
||||
/// </summary>
|
||||
/// <param name="time">time不能超过8388607</param>
|
||||
/// <param name="sceneId">sceneId不能超过65535</param>
|
||||
/// <param name="sequence">sequence不能超过33554431</param>
|
||||
public RuntimeIdStruct(uint time, uint sceneId, uint sequence)
|
||||
{
|
||||
// 因为都是在配置表里拿到参数、所以这个不做边界判定、能节省一点点性能。
|
||||
Time = time;
|
||||
SceneId = sceneId;
|
||||
Sequence = sequence;
|
||||
}
|
||||
|
||||
public static implicit operator long(RuntimeIdStruct runtimeIdStruct)
|
||||
{
|
||||
ulong result = runtimeIdStruct.Sequence;
|
||||
result |= (ulong)runtimeIdStruct.SceneId << 25;
|
||||
result |= (ulong)runtimeIdStruct.Time << 41;
|
||||
return (long)result;
|
||||
}
|
||||
|
||||
public static implicit operator RuntimeIdStruct(long runtimeId)
|
||||
{
|
||||
var result = (ulong)runtimeId;
|
||||
var runtimeIdStruct = new RuntimeIdStruct
|
||||
{
|
||||
Sequence = (uint)(result & MaskSequence)
|
||||
};
|
||||
result >>= 25;
|
||||
runtimeIdStruct.SceneId = (byte)(result & MaskSceneId);
|
||||
result >>= 16;
|
||||
runtimeIdStruct.Time = (uint)(result & MaskTime);
|
||||
return runtimeIdStruct;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class RuntimeIdFactory : IRuntimeIdFactory
|
||||
{
|
||||
private readonly uint _sceneId;
|
||||
|
||||
private uint _lastTime;
|
||||
private uint _lastSequence;
|
||||
private readonly long _epochNow;
|
||||
private readonly long _epoch1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000;
|
||||
|
||||
private RuntimeIdFactory() { }
|
||||
|
||||
public RuntimeIdFactory(uint sceneId) : this(TimeHelper.Now, sceneId) { }
|
||||
|
||||
public RuntimeIdFactory(long epochNow, uint sceneId)
|
||||
{
|
||||
switch (sceneId)
|
||||
{
|
||||
case > 65535:
|
||||
{
|
||||
throw new NotSupportedException($"sceneId:{sceneId} cannot be greater than 255255");
|
||||
}
|
||||
default:
|
||||
{
|
||||
_sceneId = (ushort)sceneId;
|
||||
_epochNow = epochNow - _epoch1970;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public long Create
|
||||
{
|
||||
get
|
||||
{
|
||||
var time = (uint)((TimeHelper.Now - _epochNow) / 1000);
|
||||
|
||||
if (time > _lastTime)
|
||||
{
|
||||
_lastTime = time;
|
||||
_lastSequence = 0;
|
||||
}
|
||||
else if (++_lastSequence > RuntimeIdStruct.MaskSequence - 1)
|
||||
{
|
||||
_lastTime++;
|
||||
_lastSequence = 0;
|
||||
}
|
||||
|
||||
return new RuntimeIdStruct(time, _sceneId, _lastSequence);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class RuntimeIdFactoryTool : IIdFactoryTool
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public uint GetTime(ref long runtimeId)
|
||||
{
|
||||
var result = (ulong)runtimeId >> 41;
|
||||
return (uint)(result & RuntimeIdStruct.MaskTime);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public uint GetSceneId(ref long runtimeId)
|
||||
{
|
||||
var result = (ulong)runtimeId >> 25;
|
||||
return (uint)(result & RuntimeIdStruct.MaskSceneId);
|
||||
}
|
||||
|
||||
public byte GetWorldId(ref long entityId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
namespace NBC.IdFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Id扩展工具接口
|
||||
/// </summary>
|
||||
public interface IIdFactoryTool
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得创建时间
|
||||
/// </summary>
|
||||
/// <param name="entityId"></param>
|
||||
/// <returns></returns>
|
||||
public uint GetTime(ref long entityId);
|
||||
/// <summary>
|
||||
/// 获得SceneId
|
||||
/// </summary>
|
||||
/// <param name="entityId"></param>
|
||||
/// <returns></returns>
|
||||
public uint GetSceneId(ref long entityId);
|
||||
/// <summary>
|
||||
/// 获得WorldId
|
||||
/// </summary>
|
||||
/// <param name="entityId"></param>
|
||||
/// <returns></returns>
|
||||
public byte GetWorldId(ref long entityId);
|
||||
}
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using NBC.Helper;
|
||||
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
namespace NBC.IdFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示一个运行时的ID。
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct WorldRuntimeIdStruct
|
||||
{
|
||||
// RuntimeId:23 + 8 + 8 + 25 = 64
|
||||
// +-------------------+--------------------------+-----------------------+--------------------------------------+
|
||||
// | time(23) 最大60天 | SceneId(8) 最多255个Scene | WordId(8) 最多255个世界 | sequence(25) 每秒每个进程能生产33554431个
|
||||
// +-------------------+--------------------------+-----------------------+--------------------------------------+
|
||||
public uint Time { get; private set; }
|
||||
public uint SceneId { get; private set; }
|
||||
public byte WordId { get; private set; }
|
||||
public uint Sequence { get; private set; }
|
||||
|
||||
public const uint MaskSequence = 0x1FFFFFF;
|
||||
public const uint MaskSceneId = 0xFF;
|
||||
public const uint MaskWordId = 0xFF;
|
||||
public const uint MaskTime = 0x7FFFFF;
|
||||
|
||||
/// <summary>
|
||||
/// WorldRuntimeIdStruct(如果超过下面参数的设定该ID会失效)。
|
||||
/// </summary>
|
||||
/// <param name="time">time不能超过8388607</param>
|
||||
/// <param name="sceneId">sceneId不能超过255</param>
|
||||
/// <param name="wordId">wordId不能超过255</param>
|
||||
/// <param name="sequence">sequence不能超过33554431</param>
|
||||
public WorldRuntimeIdStruct(uint time, uint sceneId, byte wordId, uint sequence)
|
||||
{
|
||||
// 因为都是在配置表里拿到参数、所以这个不做边界判定、能节省一点点性能。
|
||||
Time = time;
|
||||
SceneId = sceneId;
|
||||
WordId = wordId;
|
||||
Sequence = sequence;
|
||||
}
|
||||
|
||||
public static implicit operator long(WorldRuntimeIdStruct runtimeIdStruct)
|
||||
{
|
||||
ulong result = runtimeIdStruct.Sequence;
|
||||
result |= (ulong)runtimeIdStruct.WordId << 25;
|
||||
result |= (ulong)(runtimeIdStruct.SceneId % (runtimeIdStruct.WordId * 1000)) << 33;
|
||||
result |= (ulong)runtimeIdStruct.Time << 41;
|
||||
return (long)result;
|
||||
}
|
||||
|
||||
public static implicit operator WorldRuntimeIdStruct(long runtimeId)
|
||||
{
|
||||
var result = (ulong)runtimeId;
|
||||
var runtimeIdStruct = new WorldRuntimeIdStruct
|
||||
{
|
||||
Sequence = (uint)(result & MaskSequence)
|
||||
};
|
||||
result >>= 25;
|
||||
runtimeIdStruct.WordId = (byte)(result & MaskWordId);
|
||||
result >>= 8;
|
||||
runtimeIdStruct.SceneId = (uint)(result & MaskSceneId) + (uint)runtimeIdStruct.WordId * 1000;
|
||||
result >>= 8;
|
||||
runtimeIdStruct.Time = (uint)(result & MaskTime);
|
||||
return runtimeIdStruct;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class WorldRuntimeIdFactory : IRuntimeIdFactory
|
||||
{
|
||||
private readonly uint _sceneId;
|
||||
private readonly byte _worldId;
|
||||
|
||||
private uint _lastTime;
|
||||
private uint _lastSequence;
|
||||
private readonly long _epochNow;
|
||||
private readonly long _epoch1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000;
|
||||
|
||||
private WorldRuntimeIdFactory() { }
|
||||
|
||||
public WorldRuntimeIdFactory(uint sceneId, byte worldId) : this(TimeHelper.Now, sceneId, worldId) { }
|
||||
|
||||
public WorldRuntimeIdFactory(long epochNow, uint sceneId, byte worldId)
|
||||
{
|
||||
switch (sceneId)
|
||||
{
|
||||
case > 255255:
|
||||
{
|
||||
throw new NotSupportedException($"sceneId:{sceneId} cannot be greater than 255255");
|
||||
}
|
||||
case < 1001:
|
||||
{
|
||||
throw new NotSupportedException($"sceneId:{sceneId} cannot be less than 1001");
|
||||
}
|
||||
default:
|
||||
{
|
||||
_sceneId = sceneId;
|
||||
_worldId = worldId;
|
||||
_epochNow = epochNow - _epoch1970;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public long Create
|
||||
{
|
||||
get
|
||||
{
|
||||
var time = (uint)((TimeHelper.Now - _epochNow) / 1000);
|
||||
|
||||
if (time > _lastTime)
|
||||
{
|
||||
_lastTime = time;
|
||||
_lastSequence = 0;
|
||||
}
|
||||
else if (++_lastSequence > WorldRuntimeIdStruct.MaskSequence - 1)
|
||||
{
|
||||
_lastTime++;
|
||||
_lastSequence = 0;
|
||||
}
|
||||
|
||||
return new WorldRuntimeIdStruct(time, _sceneId, _worldId, _lastSequence);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class WorldRuntimeIdFactoryTool : IIdFactoryTool
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public uint GetTime(ref long runtimeId)
|
||||
{
|
||||
var result = (ulong)runtimeId >> 41;
|
||||
return (uint)(result & WorldRuntimeIdStruct.MaskTime);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public uint GetSceneId(ref long runtimeId)
|
||||
{
|
||||
var result = (ulong)runtimeId >> 25;
|
||||
var worldId = (uint)(result & WorldRuntimeIdStruct.MaskWordId) * 1000;
|
||||
result >>= 8;
|
||||
return (uint)(result & WorldRuntimeIdStruct.MaskSceneId) + worldId;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public byte GetWorldId(ref long runtimeId)
|
||||
{
|
||||
var result = (ulong)runtimeId >> 25;
|
||||
return (byte)(result & WorldRuntimeIdStruct.MaskWordId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
namespace NBC.LowLevel
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct FixedBytes1
|
||||
{
|
||||
private byte _e0;
|
||||
|
||||
public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As<FixedBytes1, byte>(ref Unsafe.AsRef(in this)), Unsafe.SizeOf<FixedBytes1>());
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct FixedBytes2
|
||||
{
|
||||
private FixedBytes1 _e0;
|
||||
private FixedBytes1 _e1;
|
||||
|
||||
public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As<FixedBytes2, byte>(ref Unsafe.AsRef(in this)), Unsafe.SizeOf<FixedBytes2>());
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct FixedBytes4
|
||||
{
|
||||
private FixedBytes2 _e0;
|
||||
private FixedBytes2 _e1;
|
||||
|
||||
public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As<FixedBytes4, byte>(ref Unsafe.AsRef(in this)), Unsafe.SizeOf<FixedBytes4>());
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct FixedBytes8
|
||||
{
|
||||
private FixedBytes4 _e0;
|
||||
private FixedBytes4 _e1;
|
||||
|
||||
public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As<FixedBytes8, byte>(ref Unsafe.AsRef(in this)), Unsafe.SizeOf<FixedBytes8>());
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct FixedBytes16
|
||||
{
|
||||
private FixedBytes8 _e0;
|
||||
private FixedBytes8 _e1;
|
||||
|
||||
public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As<FixedBytes16, byte>(ref Unsafe.AsRef(in this)), Unsafe.SizeOf<FixedBytes16>());
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct FixedBytes32
|
||||
{
|
||||
private FixedBytes16 _e0;
|
||||
private FixedBytes16 _e1;
|
||||
|
||||
public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As<FixedBytes32, byte>(ref Unsafe.AsRef(in this)), Unsafe.SizeOf<FixedBytes32>());
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct FixedBytes64
|
||||
{
|
||||
private FixedBytes32 _e0;
|
||||
private FixedBytes32 _e1;
|
||||
|
||||
public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As<FixedBytes64, byte>(ref Unsafe.AsRef(in this)), Unsafe.SizeOf<FixedBytes64>());
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct FixedBytes128
|
||||
{
|
||||
private FixedBytes64 _e0;
|
||||
private FixedBytes64 _e1;
|
||||
|
||||
public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As<FixedBytes128, byte>(ref Unsafe.AsRef(in this)), Unsafe.SizeOf<FixedBytes128>());
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct FixedBytes256
|
||||
{
|
||||
private FixedBytes128 _e0;
|
||||
private FixedBytes128 _e1;
|
||||
|
||||
public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As<FixedBytes256, byte>(ref Unsafe.AsRef(in this)), Unsafe.SizeOf<FixedBytes256>());
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct FixedBytes512
|
||||
{
|
||||
private FixedBytes256 _e0;
|
||||
private FixedBytes256 _e1;
|
||||
|
||||
public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As<FixedBytes512, byte>(ref Unsafe.AsRef(in this)), Unsafe.SizeOf<FixedBytes512>());
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct FixedBytes1024
|
||||
{
|
||||
private FixedBytes512 _e0;
|
||||
private FixedBytes512 _e1;
|
||||
|
||||
public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref Unsafe.As<FixedBytes1024, byte>(ref Unsafe.AsRef(in this)), Unsafe.SizeOf<FixedBytes1024>());
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 47dc46c1900aa42ae940be683ce35ccf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,171 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace NBC.LowLevel
|
||||
{
|
||||
public static class XxHash
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int Hash32(string obj, uint seed = 0) => Hash32(obj.AsSpan(), seed);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int Hash32<T>(in T obj, uint seed = 0) where T : unmanaged => Hash32(MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As<T, byte>(ref Unsafe.AsRef(in obj)), Unsafe.SizeOf<T>()), seed);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int Hash32<T>(ReadOnlySpan<T> buffer, uint seed = 0) where T : unmanaged => Hash32(MemoryMarshal.Cast<T, byte>(buffer), seed);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int Hash32(ReadOnlySpan<byte> buffer, uint seed = 0)
|
||||
{
|
||||
int length = buffer.Length;
|
||||
ref byte local1 = ref MemoryMarshal.GetReference(buffer);
|
||||
uint num1;
|
||||
if (buffer.Length >= 16)
|
||||
{
|
||||
uint num2 = seed + 606290984U;
|
||||
uint num3 = seed + 2246822519U;
|
||||
uint num4 = seed;
|
||||
uint num5 = seed - 2654435761U;
|
||||
for (; length >= 16; length -= 16)
|
||||
{
|
||||
const nint elementOffset1 = 4;
|
||||
const nint elementOffset2 = 8;
|
||||
const nint elementOffset3 = 12;
|
||||
nint byteOffset = buffer.Length - length;
|
||||
ref byte local2 = ref Unsafe.AddByteOffset(ref local1, byteOffset);
|
||||
uint num6 = num2 + Unsafe.ReadUnaligned<uint>(ref local2) * 2246822519U;
|
||||
num2 = (uint)((((int)num6 << 13) | (int)(num6 >> 19)) * -1640531535);
|
||||
uint num7 = num3 + Unsafe.ReadUnaligned<uint>(ref Unsafe.AddByteOffset(ref local2, elementOffset1)) * 2246822519U;
|
||||
num3 = (uint)((((int)num7 << 13) | (int)(num7 >> 19)) * -1640531535);
|
||||
uint num8 = num4 + Unsafe.ReadUnaligned<uint>(ref Unsafe.AddByteOffset(ref local2, elementOffset2)) * 2246822519U;
|
||||
num4 = (uint)((((int)num8 << 13) | (int)(num8 >> 19)) * -1640531535);
|
||||
uint num9 = num5 + Unsafe.ReadUnaligned<uint>(ref Unsafe.AddByteOffset(ref local2, elementOffset3)) * 2246822519U;
|
||||
num5 = (uint)((((int)num9 << 13) | (int)(num9 >> 19)) * -1640531535);
|
||||
}
|
||||
|
||||
num1 = (uint)((((int)num2 << 1) | (int)(num2 >> 31)) + (((int)num3 << 7) | (int)(num3 >> 25)) + (((int)num4 << 12) | (int)(num4 >> 20)) + (((int)num5 << 18) | (int)(num5 >> 14)) + buffer.Length);
|
||||
}
|
||||
else
|
||||
num1 = (uint)((int)seed + 374761393 + buffer.Length);
|
||||
|
||||
for (; length >= 4; length -= 4)
|
||||
{
|
||||
nint byteOffset = buffer.Length - length;
|
||||
uint num10 = Unsafe.ReadUnaligned<uint>(ref Unsafe.AddByteOffset(ref local1, byteOffset));
|
||||
uint num11 = num1 + num10 * 3266489917U;
|
||||
num1 = (uint)((((int)num11 << 17) | (int)(num11 >> 15)) * 668265263);
|
||||
}
|
||||
|
||||
nint byteOffset1 = buffer.Length - length;
|
||||
ref byte local3 = ref Unsafe.AddByteOffset(ref local1, byteOffset1);
|
||||
for (int index = 0; index < length; ++index)
|
||||
{
|
||||
nint byteOffset2 = index;
|
||||
uint num12 = Unsafe.AddByteOffset(ref local3, byteOffset2);
|
||||
uint num13 = num1 + num12 * 374761393U;
|
||||
num1 = (uint)((((int)num13 << 11) | (int)(num13 >> 21)) * -1640531535);
|
||||
}
|
||||
|
||||
#if NET7_0_OR_GREATER
|
||||
int num14 = ((int)num1 ^ (int)(num1 >> 15)) * -2048144777;
|
||||
int num15 = (num14 ^ (num14 >>> 13)) * -1028477379;
|
||||
return num15 ^ (num15 >>> 16);
|
||||
#else
|
||||
int num14 = ((int)num1 ^ (int)(num1 >> 15)) * -2048144777;
|
||||
int num15 = (num14 ^ (int)((uint)num14 >> 13)) * -1028477379;
|
||||
return num15 ^ (int)((uint)num15 >> 16);
|
||||
#endif
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static long Hash64(string obj, ulong seed = 0) => Hash64(obj.AsSpan(), seed);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static long Hash64<T>(in T obj, ulong seed = 0) where T : unmanaged => Hash64(MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As<T, byte>(ref Unsafe.AsRef(in obj)), Unsafe.SizeOf<T>()), seed);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static long Hash64<T>(ReadOnlySpan<T> buffer, ulong seed = 0) where T : unmanaged => Hash64(MemoryMarshal.Cast<T, byte>(buffer), seed);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static long Hash64(ReadOnlySpan<byte> buffer, ulong seed = 0)
|
||||
{
|
||||
ref var local1 = ref MemoryMarshal.GetReference(buffer);
|
||||
var length = buffer.Length;
|
||||
ulong num1;
|
||||
if (buffer.Length >= 32)
|
||||
{
|
||||
var num2 = seed + 6983438078262162902UL;
|
||||
var num3 = seed + 14029467366897019727UL;
|
||||
var num4 = seed;
|
||||
var num5 = seed - 11400714785074694791UL;
|
||||
for (; length >= 32; length -= 32)
|
||||
{
|
||||
ref var local2 = ref Unsafe.AddByteOffset(ref local1, (IntPtr)(buffer.Length - length));
|
||||
var num6 = num2 + Unsafe.ReadUnaligned<ulong>(ref local2) * 14029467366897019727UL;
|
||||
num2 = (ulong)((((long)num6 << 31) | (long)(num6 >> 33)) * -7046029288634856825L);
|
||||
var num7 = num3 + Unsafe.ReadUnaligned<ulong>(ref Unsafe.AddByteOffset(ref local2, new UIntPtr(8U))) * 14029467366897019727UL;
|
||||
num3 = (ulong)((((long)num7 << 31) | (long)(num7 >> 33)) * -7046029288634856825L);
|
||||
var num8 = num4 + Unsafe.ReadUnaligned<ulong>(ref Unsafe.AddByteOffset(ref local2, new UIntPtr(16U))) * 14029467366897019727UL;
|
||||
num4 = (ulong)((((long)num8 << 31) | (long)(num8 >> 33)) * -7046029288634856825L);
|
||||
var num9 = num5 + Unsafe.ReadUnaligned<ulong>(ref Unsafe.AddByteOffset(ref local2, new UIntPtr(24U))) * 14029467366897019727UL;
|
||||
num5 = (ulong)((((long)num9 << 31) | (long)(num9 >> 33)) * -7046029288634856825L);
|
||||
}
|
||||
|
||||
var num10 = (((long)num2 << 1) | (long)(num2 >> 63)) + (((long)num3 << 7) | (long)(num3 >> 57)) + (((long)num4 << 12) | (long)(num4 >> 52)) + (((long)num5 << 18) | (long)(num5 >> 46));
|
||||
var num11 = num2 * 14029467366897019727UL;
|
||||
var num12 = (((long)num11 << 31) | (long)(num11 >> 33)) * -7046029288634856825L;
|
||||
var num13 = (num10 ^ num12) * -7046029288634856825L + -8796714831421723037L;
|
||||
var num14 = num3 * 14029467366897019727UL;
|
||||
var num15 = (((long)num14 << 31) | (long)(num14 >> 33)) * -7046029288634856825L;
|
||||
var num16 = (num13 ^ num15) * -7046029288634856825L + -8796714831421723037L;
|
||||
var num17 = num4 * 14029467366897019727UL;
|
||||
var num18 = (((long)num17 << 31) | (long)(num17 >> 33)) * -7046029288634856825L;
|
||||
var num19 = (num16 ^ num18) * -7046029288634856825L + -8796714831421723037L;
|
||||
var num20 = num5 * 14029467366897019727UL;
|
||||
var num21 = (((long)num20 << 31) | (long)(num20 >> 33)) * -7046029288634856825L;
|
||||
num1 = (ulong)((num19 ^ num21) * -7046029288634856825L + -8796714831421723037L);
|
||||
}
|
||||
else
|
||||
num1 = seed + 2870177450012600261UL;
|
||||
|
||||
var num22 = num1 + (ulong)buffer.Length;
|
||||
for (; length >= 8; length -= 8)
|
||||
{
|
||||
var num23 = Unsafe.ReadUnaligned<ulong>(ref Unsafe.AddByteOffset(ref local1, (IntPtr)(buffer.Length - length))) * 14029467366897019727UL;
|
||||
var num24 = (ulong)((((long)num23 << 31) | (long)(num23 >> 33)) * -7046029288634856825L);
|
||||
var num25 = num22 ^ num24;
|
||||
num22 = (ulong)((((long)num25 << 27) | (long)(num25 >> 37)) * -7046029288634856825L + -8796714831421723037L);
|
||||
}
|
||||
|
||||
if (length >= 4)
|
||||
{
|
||||
ulong num26 = Unsafe.ReadUnaligned<uint>(ref Unsafe.AddByteOffset(ref local1, (IntPtr)(buffer.Length - length)));
|
||||
var num27 = num22 ^ (num26 * 11400714785074694791UL);
|
||||
num22 = (ulong)((((long)num27 << 23) | (long)(num27 >> 41)) * -4417276706812531889L + 1609587929392839161L);
|
||||
length -= 4;
|
||||
}
|
||||
|
||||
for (var byteOffset = 0; byteOffset < length; ++byteOffset)
|
||||
{
|
||||
ulong num28 = Unsafe.AddByteOffset(ref Unsafe.AddByteOffset(ref local1, (IntPtr)(buffer.Length - length)), (IntPtr)byteOffset);
|
||||
var num29 = num22 ^ (num28 * 2870177450012600261UL);
|
||||
num22 = (ulong)((((long)num29 << 11) | (long)(num29 >> 53)) * -7046029288634856825L);
|
||||
}
|
||||
|
||||
#if NET7_0_OR_GREATER
|
||||
var num30 = (long)num22;
|
||||
var num31 = (num30 ^ (num30 >>> 33)) * -4417276706812531889L;
|
||||
var num32 = (num31 ^ (num31 >>> 29)) * 1609587929392839161L;
|
||||
return num32 ^ (num32 >>> 32);
|
||||
#else
|
||||
var num30 = (long)num22;
|
||||
var num31 = (num30 ^ (long)((ulong)num30 >> 33)) * -4417276706812531889L;
|
||||
var num32 = (num31 ^ (long)((ulong)num31 >> 29)) * 1609587929392839161L;
|
||||
return num32 ^ (long)((ulong)num32 >> 32);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c48425f83e5934ed89216dd6ccc52288
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,337 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using NBC.Network;
|
||||
using NBC.Assembly;
|
||||
using NBC.Async;
|
||||
using NBC.DataStructure.Collection;
|
||||
using NBC.DataStructure.Dictionary;
|
||||
using NBC.Entitas;
|
||||
using NBC.InnerMessage;
|
||||
|
||||
#pragma warning disable CS8604 // Possible null reference argument.
|
||||
|
||||
#pragma warning disable CS8602 // Dereference of a possibly null reference.
|
||||
#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type.
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
namespace NBC.Network.Interface
|
||||
{
|
||||
/// <summary>
|
||||
/// 用于存储消息处理器的信息,包括类型和对象实例。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">消息处理器的类型</typeparam>
|
||||
internal sealed class HandlerInfo<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置消息处理器对象。
|
||||
/// </summary>
|
||||
public T Obj;
|
||||
/// <summary>
|
||||
/// 获取或设置消息处理器的类型。
|
||||
/// </summary>
|
||||
public Type Type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 网络消息分发组件。
|
||||
/// </summary>
|
||||
public sealed class MessageDispatcherComponent : Entity, IAssembly
|
||||
{
|
||||
public long AssemblyIdentity { get; set; }
|
||||
private readonly Dictionary<Type, Type> _responseTypes = new Dictionary<Type, Type>();
|
||||
private readonly DoubleMapDictionary<uint, Type> _networkProtocols = new DoubleMapDictionary<uint, Type>();
|
||||
private readonly Dictionary<Type, IMessageHandler> _messageHandlers = new Dictionary<Type, IMessageHandler>();
|
||||
private readonly OneToManyList<long, Type> _assemblyResponseTypes = new OneToManyList<long, Type>();
|
||||
private readonly OneToManyList<long, uint> _assemblyNetworkProtocols = new OneToManyList<long, uint>();
|
||||
private readonly OneToManyList<long, HandlerInfo<IMessageHandler>> _assemblyMessageHandlers = new OneToManyList<long, HandlerInfo<IMessageHandler>>();
|
||||
private readonly Dictionary<Type, IMessageDelegateHandler> _messageDelegateHandlers = new Dictionary<Type, IMessageDelegateHandler>();
|
||||
|
||||
private CoroutineLock _receiveRouteMessageLock;
|
||||
|
||||
#region Initialize
|
||||
|
||||
internal async FTask<MessageDispatcherComponent> Initialize()
|
||||
{
|
||||
_receiveRouteMessageLock = Scene.CoroutineLockComponent.Create(GetType().TypeHandle.Value.ToInt64());
|
||||
await AssemblySystem.Register(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
public async FTask Load(long assemblyIdentity)
|
||||
{
|
||||
var tcs = FTask.Create(false);
|
||||
Scene?.ThreadSynchronizationContext.Post(() =>
|
||||
{
|
||||
LoadInner(assemblyIdentity);
|
||||
tcs.SetResult();
|
||||
});
|
||||
await tcs;
|
||||
}
|
||||
|
||||
private void LoadInner(long assemblyIdentity)
|
||||
{
|
||||
var nmsl = AssemblySystem.ForEach(assemblyIdentity, typeof(IMessage));
|
||||
// 遍历所有实现了IMessage接口的类型,获取OpCode并添加到_networkProtocols字典中
|
||||
foreach (var type in nmsl)
|
||||
{
|
||||
var obj = (IMessage) Activator.CreateInstance(type);
|
||||
var opCode = obj.OpCode();
|
||||
|
||||
_networkProtocols.Add(opCode, type);
|
||||
|
||||
var responseType = type.GetProperty("ResponseType");
|
||||
|
||||
// 如果类型具有ResponseType属性,将其添加到_responseTypes字典中
|
||||
if (responseType != null)
|
||||
{
|
||||
_responseTypes.Add(type, responseType.PropertyType);
|
||||
_assemblyResponseTypes.Add(assemblyIdentity, type);
|
||||
}
|
||||
|
||||
_assemblyNetworkProtocols.Add(assemblyIdentity, opCode);
|
||||
}
|
||||
|
||||
// 遍历所有实现了IMessageHandler接口的类型,创建实例并添加到_messageHandlers字典中
|
||||
foreach (var type in AssemblySystem.ForEach(assemblyIdentity, typeof(IMessageHandler)))
|
||||
{
|
||||
var obj = (IMessageHandler) Activator.CreateInstance(type);
|
||||
|
||||
if (obj == null)
|
||||
{
|
||||
throw new Exception($"message handle {type.Name} is null");
|
||||
}
|
||||
|
||||
var key = obj.Type();
|
||||
_messageHandlers.Add(key, obj);
|
||||
_assemblyMessageHandlers.Add(assemblyIdentity, new HandlerInfo<IMessageHandler>()
|
||||
{
|
||||
Obj = obj, Type = key
|
||||
});
|
||||
}
|
||||
|
||||
// 如果编译符号FANTASY_NET存在,遍历所有实现了IRouteMessageHandler接口的类型,创建实例并添加到_routeMessageHandlers字典中
|
||||
#if FANTASY_NET
|
||||
foreach (var type in AssemblySystem.ForEach(assemblyIdentity, typeof(IRouteMessageHandler)))
|
||||
{
|
||||
var obj = (IRouteMessageHandler) Activator.CreateInstance(type);
|
||||
|
||||
if (obj == null)
|
||||
{
|
||||
throw new Exception($"message handle {type.Name} is null");
|
||||
}
|
||||
|
||||
var key = obj.Type();
|
||||
_routeMessageHandlers.Add(key, obj);
|
||||
_assemblyRouteMessageHandlers.Add(assemblyIdentity, new HandlerInfo<IRouteMessageHandler>()
|
||||
{
|
||||
Obj = obj, Type = key
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var type in AssemblySystem.ForEach(assemblyIdentity, typeof(ICustomRoute)))
|
||||
{
|
||||
var obj = (ICustomRoute) Activator.CreateInstance(type);
|
||||
|
||||
if (obj == null)
|
||||
{
|
||||
throw new Exception($"message handle {type.Name} is null");
|
||||
}
|
||||
|
||||
var opCode = obj.OpCode();
|
||||
_customRouteMap[opCode] = obj.RouteType;
|
||||
_assemblyCustomRouteMap.Add(assemblyIdentity, opCode);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public async FTask ReLoad(long assemblyIdentity)
|
||||
{
|
||||
var tcs = FTask.Create(false);
|
||||
Scene?.ThreadSynchronizationContext.Post(() =>
|
||||
{
|
||||
OnUnLoadInner(assemblyIdentity);
|
||||
LoadInner(assemblyIdentity);
|
||||
tcs.SetResult();
|
||||
});
|
||||
await tcs;
|
||||
}
|
||||
|
||||
public async FTask OnUnLoad(long assemblyIdentity)
|
||||
{
|
||||
var tcs = FTask.Create(false);
|
||||
Scene?.ThreadSynchronizationContext.Post(() =>
|
||||
{
|
||||
OnUnLoadInner(assemblyIdentity);
|
||||
tcs.SetResult();
|
||||
});
|
||||
await tcs;
|
||||
}
|
||||
|
||||
private void OnUnLoadInner(long assemblyIdentity)
|
||||
{
|
||||
// 移除程序集对应的ResponseType类型和OpCode信息
|
||||
if (_assemblyResponseTypes.TryGetValue(assemblyIdentity, out var removeResponseTypes))
|
||||
{
|
||||
foreach (var removeResponseType in removeResponseTypes)
|
||||
{
|
||||
_responseTypes.Remove(removeResponseType);
|
||||
}
|
||||
|
||||
_assemblyResponseTypes.RemoveByKey(assemblyIdentity);
|
||||
}
|
||||
|
||||
if (_assemblyNetworkProtocols.TryGetValue(assemblyIdentity, out var removeNetworkProtocols))
|
||||
{
|
||||
foreach (var removeNetworkProtocol in removeNetworkProtocols)
|
||||
{
|
||||
_networkProtocols.RemoveByKey(removeNetworkProtocol);
|
||||
}
|
||||
|
||||
_assemblyNetworkProtocols.RemoveByKey(assemblyIdentity);
|
||||
}
|
||||
|
||||
// 移除程序集对应的消息处理器信息
|
||||
if (_assemblyMessageHandlers.TryGetValue(assemblyIdentity, out var removeMessageHandlers))
|
||||
{
|
||||
foreach (var removeMessageHandler in removeMessageHandlers)
|
||||
{
|
||||
_messageHandlers.Remove(removeMessageHandler.Type);
|
||||
}
|
||||
|
||||
_assemblyMessageHandlers.RemoveByKey(assemblyIdentity);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 手动注册一个消息处理器。
|
||||
/// </summary>
|
||||
/// <param name="delegate"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public void RegisterHandler<T>(MessageDelegate<T> @delegate) where T : IMessage
|
||||
{
|
||||
var type = typeof(T);
|
||||
|
||||
if (!_messageDelegateHandlers.TryGetValue(type, out var messageDelegate))
|
||||
{
|
||||
messageDelegate = new MessageDelegateHandler<T>();
|
||||
_messageDelegateHandlers.Add(type,messageDelegate);
|
||||
}
|
||||
|
||||
messageDelegate.Register(@delegate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 手动卸载一个消息处理器,必须是通过RegisterHandler方法注册的消息处理器。
|
||||
/// </summary>
|
||||
/// <param name="delegate"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public void UnRegisterHandler<T>(MessageDelegate<T> @delegate) where T : IMessage
|
||||
{
|
||||
var type = typeof(T);
|
||||
|
||||
if (!_messageDelegateHandlers.TryGetValue(type, out var messageDelegate))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (messageDelegate.UnRegister(@delegate) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_messageDelegateHandlers.Remove(type);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 处理普通消息,将消息分发给相应的消息处理器。
|
||||
/// </summary>
|
||||
/// <param name="session">会话对象</param>
|
||||
/// <param name="type">消息类型</param>
|
||||
/// <param name="message">消息对象</param>
|
||||
/// <param name="rpcId">RPC标识</param>
|
||||
/// <param name="protocolCode">协议码</param>
|
||||
public void MessageHandler(Session session, Type type, object message, uint rpcId, uint protocolCode)
|
||||
{
|
||||
if(_messageDelegateHandlers.TryGetValue(type,out var messageDelegateHandler))
|
||||
{
|
||||
messageDelegateHandler.Handle(session, message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_messageHandlers.TryGetValue(type, out var messageHandler))
|
||||
{
|
||||
Log.Warning($"Scene:{session.Scene.Id} Found Unhandled Message: {message.GetType()}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 调用消息处理器的Handle方法并启动协程执行处理逻辑
|
||||
messageHandler.Handle(session, rpcId, protocolCode, message).Coroutine();
|
||||
}
|
||||
|
||||
internal void FailRouteResponse(Session session, Type requestType, uint error, uint rpcId)
|
||||
{
|
||||
var response = CreateRouteResponse(requestType, error);
|
||||
session.Send(response, rpcId);
|
||||
}
|
||||
|
||||
internal IResponse CreateResponse(Type requestType, uint error)
|
||||
{
|
||||
IResponse response;
|
||||
|
||||
if (_responseTypes.TryGetValue(requestType, out var responseType))
|
||||
{
|
||||
response = (IResponse) Activator.CreateInstance(responseType);
|
||||
}
|
||||
else
|
||||
{
|
||||
response = new Response();
|
||||
}
|
||||
|
||||
response.ErrorCode = error;
|
||||
return response;
|
||||
}
|
||||
|
||||
internal IRouteResponse CreateRouteResponse(Type requestType, uint error)
|
||||
{
|
||||
IRouteResponse response;
|
||||
|
||||
if (_responseTypes.TryGetValue(requestType, out var responseType))
|
||||
{
|
||||
response = (IRouteResponse) Activator.CreateInstance(responseType);
|
||||
}
|
||||
else
|
||||
{
|
||||
response = new RouteResponse();
|
||||
}
|
||||
|
||||
response.ErrorCode = error;
|
||||
return response;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据消息类型获取对应的OpCode。
|
||||
/// </summary>
|
||||
/// <param name="type">消息类型</param>
|
||||
/// <returns>消息对应的OpCode</returns>
|
||||
public uint GetOpCode(Type type)
|
||||
{
|
||||
return _networkProtocols.GetKeyByValue(type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据OpCode获取对应的消息类型。
|
||||
/// </summary>
|
||||
/// <param name="code">OpCode</param>
|
||||
/// <returns>OpCode对应的消息类型</returns>
|
||||
public Type GetOpCodeType(uint code)
|
||||
{
|
||||
return _networkProtocols.GetValueByKey(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
namespace NBC.Network
|
||||
{
|
||||
public struct OpCodeIdStruct
|
||||
{
|
||||
// OpCodeIdStruct:5 + 4 + 23 = 32
|
||||
// +-------------------------+-------------------------------------------+-----------------------------+
|
||||
// | protocol(5) 最多31种类型 | OpCodeProtocolType(4) 最多15种不同的网络协议 | Index(23) 最多8388607个协议 |
|
||||
// +-------------------------+-------------------------------------------+-----------------------------+
|
||||
public uint OpCodeProtocolType { get; private set; }
|
||||
public uint Protocol { get; private set; }
|
||||
public uint Index { get; private set; }
|
||||
|
||||
public OpCodeIdStruct(uint opCodeProtocolType, uint protocol, uint index)
|
||||
{
|
||||
OpCodeProtocolType = opCodeProtocolType;
|
||||
Protocol = protocol;
|
||||
Index = index;
|
||||
}
|
||||
|
||||
public static implicit operator uint(OpCodeIdStruct opCodeIdStruct)
|
||||
{
|
||||
var result = opCodeIdStruct.Index;
|
||||
result |= opCodeIdStruct.OpCodeProtocolType << 23;
|
||||
result |= opCodeIdStruct.Protocol << 27;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static implicit operator OpCodeIdStruct(uint opCodeId)
|
||||
{
|
||||
var opCodeIdStruct = new OpCodeIdStruct()
|
||||
{
|
||||
Index = opCodeId & 0x7FFFFF
|
||||
};
|
||||
opCodeId >>= 23;
|
||||
opCodeIdStruct.OpCodeProtocolType = opCodeId & 0xF;
|
||||
opCodeId >>= 4;
|
||||
opCodeIdStruct.Protocol = opCodeId & 0x1F;
|
||||
return opCodeIdStruct;
|
||||
}
|
||||
}
|
||||
|
||||
public static class OpCodeProtocolType
|
||||
{
|
||||
public const uint Bson = 1;
|
||||
public const uint ProtoBuf = 0;
|
||||
}
|
||||
|
||||
public static class OpCodeType
|
||||
{
|
||||
public const uint OuterMessage = 1;
|
||||
public const uint OuterRequest = 2;
|
||||
public const uint OuterResponse = 3;
|
||||
|
||||
public const uint InnerMessage = 4;
|
||||
public const uint InnerRequest = 5;
|
||||
public const uint InnerResponse = 6;
|
||||
|
||||
public const uint InnerRouteMessage = 7;
|
||||
public const uint InnerRouteRequest = 8;
|
||||
public const uint InnerRouteResponse = 9;
|
||||
|
||||
public const uint OuterAddressableMessage = 10;
|
||||
public const uint OuterAddressableRequest = 11;
|
||||
public const uint OuterAddressableResponse = 12;
|
||||
|
||||
public const uint InnerAddressableMessage = 13;
|
||||
public const uint InnerAddressableRequest = 14;
|
||||
public const uint InnerAddressableResponse = 15;
|
||||
|
||||
public const uint OuterCustomRouteMessage = 16;
|
||||
public const uint OuterCustomRouteRequest = 17;
|
||||
public const uint OuterCustomRouteResponse = 18;
|
||||
|
||||
public const uint OuterRoamingMessage = 19;
|
||||
public const uint OuterRoamingRequest = 20;
|
||||
public const uint OuterRoamingResponse = 21;
|
||||
|
||||
public const uint InnerRoamingMessage = 22;
|
||||
public const uint InnerRoamingRequest = 23;
|
||||
public const uint InnerRoamingResponse = 24;
|
||||
|
||||
public const uint OuterPingRequest = 30;
|
||||
public const uint OuterPingResponse = 31;
|
||||
}
|
||||
|
||||
public static class OpCode
|
||||
{
|
||||
public static readonly uint BenchmarkMessage = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.OuterMessage, 8388607);
|
||||
public static readonly uint BenchmarkRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.OuterRequest, 8388607);
|
||||
public static readonly uint BenchmarkResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.OuterResponse, 8388607);
|
||||
public static readonly uint PingRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.OuterPingRequest, 1);
|
||||
public static readonly uint PingResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.OuterPingResponse, 1);
|
||||
public static readonly uint DefaultResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerResponse, 1);
|
||||
public static readonly uint DefaultRouteResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 7);
|
||||
public static readonly uint AddressableAddRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 1);
|
||||
public static readonly uint AddressableAddResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 1);
|
||||
public static readonly uint AddressableGetRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 2);
|
||||
public static readonly uint AddressableGetResponse = Create(OpCodeProtocolType.ProtoBuf,OpCodeType.InnerRouteResponse,2);
|
||||
public static readonly uint AddressableRemoveRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 3);
|
||||
public static readonly uint AddressableRemoveResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 3);
|
||||
public static readonly uint AddressableLockRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 4);
|
||||
public static readonly uint AddressableLockResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 4);
|
||||
public static readonly uint AddressableUnLockRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 5);
|
||||
public static readonly uint AddressableUnLockResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 5);
|
||||
public static readonly uint LinkRoamingRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 6);
|
||||
public static readonly uint LinkRoamingResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 6);
|
||||
public static readonly uint UnLinkRoamingRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 8);
|
||||
public static readonly uint UnLinkRoamingResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 8);
|
||||
public static readonly uint LockTerminusIdRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 9);
|
||||
public static readonly uint LockTerminusIdResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 9);
|
||||
public static readonly uint UnLockTerminusIdRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 10);
|
||||
public static readonly uint UnLockTerminusIdResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 10);
|
||||
public static readonly uint GetTerminusIdRequest = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteRequest, 11);
|
||||
public static readonly uint GetTerminusIdResponse = Create(OpCodeProtocolType.ProtoBuf, OpCodeType.InnerRouteResponse, 11);
|
||||
|
||||
public static readonly uint TransferTerminusRequest = Create(OpCodeProtocolType.Bson, OpCodeType.InnerRouteRequest, 1);
|
||||
public static readonly uint TransferTerminusResponse = Create(OpCodeProtocolType.Bson, OpCodeType.InnerRouteResponse, 1);
|
||||
|
||||
public static uint Create(uint opCodeProtocolType, uint protocol, uint index)
|
||||
{
|
||||
return new OpCodeIdStruct(opCodeProtocolType, protocol, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
namespace NBC
|
||||
{
|
||||
internal interface ISceneUpdate
|
||||
{
|
||||
void Update();
|
||||
}
|
||||
|
||||
internal sealed class EmptySceneUpdate : ISceneUpdate
|
||||
{
|
||||
public void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace NBC.Serialize
|
||||
{
|
||||
/// <summary>
|
||||
/// 代表是一个ProtoBuf协议
|
||||
/// </summary>
|
||||
public interface IProto
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8890f4dc3e2c433fbd22b91ead3bfe4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,22 +0,0 @@
|
||||
namespace NBC
|
||||
{
|
||||
public interface ISingletonAwake
|
||||
{
|
||||
void Awake();
|
||||
}
|
||||
|
||||
public interface ISingletonAwake<A>
|
||||
{
|
||||
void Awake(A a);
|
||||
}
|
||||
|
||||
public interface ISingletonAwake<A, B>
|
||||
{
|
||||
void Awake(A a, B b);
|
||||
}
|
||||
|
||||
public interface ISingletonAwake<A, B, C>
|
||||
{
|
||||
void Awake(A a, B b, C c);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5543bf08377d4c0289f50e9b465963b6
|
||||
timeCreated: 1733994653
|
||||
@@ -1,85 +0,0 @@
|
||||
// using System;
|
||||
// using UnityEngine;
|
||||
//
|
||||
// namespace NBC
|
||||
// {
|
||||
// public class MonoManager : MonoBehaviour
|
||||
// {
|
||||
// public event Action OnUpdate;
|
||||
// public event Action OnLateUpdate;
|
||||
// public event Action OnFixedUpdate;
|
||||
// public event Action OnApplicationQuitAction;
|
||||
// public event Action<bool> OnApplicationPauseAction;
|
||||
//
|
||||
// private static bool IsQuiting { get; set; }
|
||||
//
|
||||
// private static MonoManager _inst;
|
||||
//
|
||||
// public static MonoManager Inst
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// if (_inst != null || IsQuiting) return _inst;
|
||||
// _inst = FindObjectOfType<MonoManager>();
|
||||
// if (_inst == null)
|
||||
// {
|
||||
// _inst = new GameObject("_MonoTimer").AddComponent<MonoManager>();
|
||||
// }
|
||||
//
|
||||
// return _inst;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// ///Creates the MonoManager singleton
|
||||
// public static void Create()
|
||||
// {
|
||||
// _inst = Inst;
|
||||
// }
|
||||
//
|
||||
// protected void OnApplicationQuit()
|
||||
// {
|
||||
// IsQuiting = true;
|
||||
// OnApplicationQuitAction?.Invoke();
|
||||
// }
|
||||
//
|
||||
// protected void OnApplicationPause(bool isPause)
|
||||
// {
|
||||
// OnApplicationPauseAction?.Invoke(isPause);
|
||||
// }
|
||||
//
|
||||
// protected void Awake()
|
||||
// {
|
||||
// if (_inst != null && _inst != this)
|
||||
// {
|
||||
// DestroyImmediate(this.gameObject);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// DontDestroyOnLoad(gameObject);
|
||||
// _inst = this;
|
||||
// }
|
||||
//
|
||||
// protected void Update()
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// OnUpdate?.Invoke();
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// Debug.LogError(e);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// protected void LateUpdate()
|
||||
// {
|
||||
// OnLateUpdate?.Invoke();
|
||||
// }
|
||||
//
|
||||
// protected void FixedUpdate()
|
||||
// {
|
||||
// OnFixedUpdate?.Invoke();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 869c4449527c495c833b9d848ce61968
|
||||
timeCreated: 1614234084
|
||||
@@ -1,82 +0,0 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public interface ISingletonReverseDispose
|
||||
{
|
||||
}
|
||||
|
||||
public abstract class DisposeObject : IDisposable, ISupportInitialize
|
||||
{
|
||||
public virtual void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void BeginInit()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void EndInit()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class ASingleton : DisposeObject
|
||||
{
|
||||
internal abstract void Register();
|
||||
}
|
||||
|
||||
public abstract class Singleton<T> : ASingleton where T : Singleton<T>
|
||||
{
|
||||
private bool _isDisposed;
|
||||
|
||||
|
||||
public static T Instance { get; private set; }
|
||||
|
||||
internal override void Register()
|
||||
{
|
||||
Instance = (T)this;
|
||||
}
|
||||
|
||||
public bool IsDisposed()
|
||||
{
|
||||
return this._isDisposed;
|
||||
}
|
||||
|
||||
protected virtual void Destroy()
|
||||
{
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
if (this._isDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this._isDisposed = true;
|
||||
|
||||
this.Destroy();
|
||||
|
||||
Instance = null;
|
||||
}
|
||||
}
|
||||
|
||||
public class SingletonMono<T> : MonoBehaviour where T : MonoBehaviour
|
||||
{
|
||||
public static T Instance { get; private set; }
|
||||
|
||||
protected void Awake()
|
||||
{
|
||||
Instance = this as T;
|
||||
OnAwake();
|
||||
}
|
||||
|
||||
protected virtual void OnAwake()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42905ef6b2464dbd92290701d39348a5
|
||||
timeCreated: 1715240819
|
||||
@@ -1,77 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
public class TimeInfo: Singleton<TimeInfo>, ISingletonAwake
|
||||
{
|
||||
private int timeZone;
|
||||
|
||||
public int TimeZone
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.timeZone;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.timeZone = value;
|
||||
dt = dt1970.AddHours(TimeZone);
|
||||
}
|
||||
}
|
||||
|
||||
private DateTime dt1970;
|
||||
private DateTime dt;
|
||||
|
||||
// ping消息会设置该值,原子操作
|
||||
public long ServerMinusClientTime { private get; set; }
|
||||
|
||||
public long FrameTime { get; private set; }
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
this.dt1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
this.dt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
this.FrameTime = this.ClientNow();
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// 赋值long型是原子操作,线程安全
|
||||
this.FrameTime = this.ClientNow();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据时间戳获取时间
|
||||
/// </summary>
|
||||
public DateTime ToDateTime(long timeStamp)
|
||||
{
|
||||
return dt.AddTicks(timeStamp * 10000);
|
||||
}
|
||||
|
||||
// 线程安全
|
||||
public long ClientNow()
|
||||
{
|
||||
return (DateTime.UtcNow.Ticks - this.dt1970.Ticks) / 10000;
|
||||
}
|
||||
|
||||
public long ServerNow()
|
||||
{
|
||||
return ClientNow() + this.ServerMinusClientTime;
|
||||
}
|
||||
|
||||
public long ClientFrameTime()
|
||||
{
|
||||
return this.FrameTime;
|
||||
}
|
||||
|
||||
public long ServerFrameTime()
|
||||
{
|
||||
return this.FrameTime + this.ServerMinusClientTime;
|
||||
}
|
||||
|
||||
public long Transition(DateTime d)
|
||||
{
|
||||
return (d.Ticks - dt.Ticks) / 10000;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fd695c053e2b4ac9b51cf819f764543f
|
||||
timeCreated: 1733994392
|
||||
@@ -1,411 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC
|
||||
{
|
||||
class TimerHandler
|
||||
{
|
||||
public string key;
|
||||
public bool repeat;
|
||||
public float delay;
|
||||
public bool userFrame;
|
||||
public float exeTime;
|
||||
public object caller;
|
||||
public Action<object> methodWithArgs; // 带参数的回调
|
||||
public Action methodWithoutArgs; // 不带参数的回调
|
||||
public object args;
|
||||
public bool jumpFrame;
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
caller = null;
|
||||
methodWithArgs = null;
|
||||
methodWithoutArgs = null;
|
||||
args = null;
|
||||
}
|
||||
|
||||
public void Run(bool withClear)
|
||||
{
|
||||
if (caller == null)
|
||||
{
|
||||
Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// 优先执行无参数回调
|
||||
methodWithoutArgs?.Invoke();
|
||||
// 如果没有无参数回调,则执行带参数回调
|
||||
methodWithArgs?.Invoke(args);
|
||||
|
||||
if (withClear) Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Timer
|
||||
{
|
||||
static Timer()
|
||||
{
|
||||
App.OnUpdate += Update;
|
||||
}
|
||||
|
||||
private static void Update()
|
||||
{
|
||||
_timer.Update();
|
||||
}
|
||||
|
||||
private static readonly TimerData _timer = new TimerData();
|
||||
|
||||
#region 无参数回调版本
|
||||
|
||||
/// <summary>
|
||||
/// 定时执行一次(无参数)
|
||||
/// </summary>
|
||||
public static void Once(float delay, object caller, Action method, bool coverBefore = true)
|
||||
{
|
||||
_timer.Once(delay, caller, method, coverBefore);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 定时重复执行(无参数)
|
||||
/// </summary>
|
||||
public static void Loop(float delay, object caller, Action method, bool coverBefore = true,
|
||||
bool jumpFrame = false)
|
||||
{
|
||||
_timer.Loop(delay, caller, method, coverBefore, jumpFrame);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 定时执行一次(基于帧率,无参数)
|
||||
/// </summary>
|
||||
public static void FrameOnce(int delay, object caller, Action method, bool coverBefore = true)
|
||||
{
|
||||
_timer.FrameOnce(delay, caller, method, coverBefore);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 定时重复执行(基于帧率,无参数)
|
||||
/// </summary>
|
||||
public static void FrameLoop(int delay, object caller, Action method, bool coverBefore = true)
|
||||
{
|
||||
_timer.FrameLoop(delay, caller, method, coverBefore);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理定时器(无参数版本)
|
||||
/// </summary>
|
||||
public static void Clear(object caller, Action method)
|
||||
{
|
||||
_timer.Clear(caller, method);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 带参数回调版本
|
||||
|
||||
/// <summary>
|
||||
/// 定时执行一次(带参数)
|
||||
/// </summary>
|
||||
public static void Once(float delay, object caller, Action<object> method, object args = null,
|
||||
bool coverBefore = true)
|
||||
{
|
||||
_timer.Once(delay, caller, method, args, coverBefore);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 定时重复执行(带参数)
|
||||
/// </summary>
|
||||
public static void Loop(float delay, object caller, Action<object> method, object args = null,
|
||||
bool coverBefore = true, bool jumpFrame = false)
|
||||
{
|
||||
_timer.Loop(delay, caller, method, args, coverBefore, jumpFrame);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 定时执行一次(基于帧率,带参数)
|
||||
/// </summary>
|
||||
public static void FrameOnce(int delay, object caller, Action<object> method, object args = null,
|
||||
bool coverBefore = true)
|
||||
{
|
||||
_timer.FrameOnce(delay, caller, method, args, coverBefore);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 定时重复执行(基于帧率,带参数)
|
||||
/// </summary>
|
||||
public static void FrameLoop(int delay, object caller, Action<object> method, object args = null,
|
||||
bool coverBefore = true)
|
||||
{
|
||||
_timer.FrameLoop(delay, caller, method, args, coverBefore);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理定时器(带参数版本)
|
||||
/// </summary>
|
||||
public static void Clear(object caller, Action<object> method)
|
||||
{
|
||||
_timer.Clear(caller, method);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 清理对象身上的所有定时器
|
||||
/// </summary>
|
||||
public static void ClearAll(object caller)
|
||||
{
|
||||
_timer.ClearAll(caller);
|
||||
}
|
||||
}
|
||||
|
||||
public class TimerData
|
||||
{
|
||||
private static readonly Queue<TimerHandler> _pool = new Queue<TimerHandler>();
|
||||
private static int _mid = 1;
|
||||
|
||||
public float CurrTimer = Time.time;
|
||||
public int CurrFrame = 0;
|
||||
private float _delta = 0;
|
||||
private float _lastTimer = Time.time;
|
||||
|
||||
private Dictionary<string, TimerHandler> _map = new Dictionary<string, TimerHandler>();
|
||||
private List<TimerHandler> _handlers = new List<TimerHandler>();
|
||||
private List<TimerHandler> _temp = new List<TimerHandler>();
|
||||
private int _count = 0;
|
||||
|
||||
public float delta => _delta;
|
||||
|
||||
internal void Update()
|
||||
{
|
||||
var frame = CurrFrame += 1;
|
||||
var now = Time.time;
|
||||
var awake = (now - _lastTimer) > 30000;
|
||||
|
||||
_delta = (now - _lastTimer);
|
||||
var timer = CurrTimer += _delta;
|
||||
_lastTimer = now;
|
||||
|
||||
_count = 0;
|
||||
for (int i = 0, n = _handlers.Count; i < n; i++)
|
||||
{
|
||||
var handler = _handlers[i];
|
||||
if (handler.methodWithArgs != null || handler.methodWithoutArgs != null)
|
||||
{
|
||||
var t = handler.userFrame ? frame : timer;
|
||||
if (t >= handler.exeTime)
|
||||
{
|
||||
if (handler.repeat)
|
||||
{
|
||||
if (!handler.jumpFrame || awake)
|
||||
{
|
||||
handler.exeTime += handler.delay;
|
||||
handler.Run(false);
|
||||
if (t > handler.exeTime)
|
||||
{
|
||||
handler.exeTime += Mathf.Ceil((t - handler.exeTime) / handler.delay) *
|
||||
handler.delay;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (t >= handler.exeTime)
|
||||
{
|
||||
handler.exeTime += handler.delay;
|
||||
handler.Run(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
handler.Run(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (_count > 30 || frame % 200 == 0) _clearHandlers();
|
||||
}
|
||||
|
||||
private void _clearHandlers()
|
||||
{
|
||||
var handlers = _handlers;
|
||||
for (int i = 0, n = handlers.Count; i < n; i++)
|
||||
{
|
||||
var handler = handlers[i];
|
||||
if (handler.methodWithArgs != null || handler.methodWithoutArgs != null)
|
||||
_temp.Add(handler);
|
||||
else
|
||||
_recoverHandler(handler);
|
||||
}
|
||||
|
||||
_handlers = _temp;
|
||||
handlers.Clear();
|
||||
_temp = handlers;
|
||||
}
|
||||
|
||||
private void _recoverHandler(TimerHandler handler)
|
||||
{
|
||||
if (_map.TryGetValue(handler.key, out var h) && h == handler)
|
||||
{
|
||||
_map.Remove(handler.key);
|
||||
handler.Clear();
|
||||
_pool.Enqueue(handler);
|
||||
}
|
||||
}
|
||||
|
||||
#region 无参数回调版本
|
||||
|
||||
public void Once(float delay, object caller, Action method, bool coverBefore = true)
|
||||
{
|
||||
_create(false, false, delay, caller, null, method, null, coverBefore);
|
||||
}
|
||||
|
||||
public void Loop(float delay, object caller, Action method, bool coverBefore = true, bool jumpFrame = false)
|
||||
{
|
||||
var handler = _create(false, true, delay, caller, null, method, null, coverBefore);
|
||||
if (handler != null) handler.jumpFrame = jumpFrame;
|
||||
}
|
||||
|
||||
public void FrameOnce(int delay, object caller, Action method, bool coverBefore = true)
|
||||
{
|
||||
_create(true, false, delay, caller, null, method, null, coverBefore);
|
||||
}
|
||||
|
||||
public void FrameLoop(int delay, object caller, Action method, bool coverBefore = true)
|
||||
{
|
||||
_create(true, true, delay, caller, null, method, null, coverBefore);
|
||||
}
|
||||
|
||||
public void Clear(object caller, Action method)
|
||||
{
|
||||
var handler = _getHandler(caller, null, method);
|
||||
handler?.Clear();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 带参数回调版本
|
||||
|
||||
public void Once(float delay, object caller, Action<object> method, object args = null, bool coverBefore = true)
|
||||
{
|
||||
_create(false, false, delay, caller, method, null, args, coverBefore);
|
||||
}
|
||||
|
||||
public void Loop(float delay, object caller, Action<object> method, object args = null, bool coverBefore = true,
|
||||
bool jumpFrame = false)
|
||||
{
|
||||
var handler = _create(false, true, delay, caller, method, null, args, coverBefore);
|
||||
if (handler != null) handler.jumpFrame = jumpFrame;
|
||||
}
|
||||
|
||||
public void FrameOnce(int delay, object caller, Action<object> method, object args = null,
|
||||
bool coverBefore = true)
|
||||
{
|
||||
_create(true, false, delay, caller, method, null, args, coverBefore);
|
||||
}
|
||||
|
||||
public void FrameLoop(int delay, object caller, Action<object> method, object args = null,
|
||||
bool coverBefore = true)
|
||||
{
|
||||
_create(true, true, delay, caller, method, null, args, coverBefore);
|
||||
}
|
||||
|
||||
public void Clear(object caller, Action<object> method)
|
||||
{
|
||||
var handler = _getHandler(caller, method, null);
|
||||
handler?.Clear();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private TimerHandler _create(bool useFrame, bool repeat, float delay, object caller,
|
||||
Action<object> methodWithArgs, Action methodWithoutArgs,
|
||||
object args, bool coverBefore)
|
||||
{
|
||||
// 如果延迟为0,则立即执行
|
||||
if (delay <= 0)
|
||||
{
|
||||
if (methodWithoutArgs != null)
|
||||
methodWithoutArgs.Invoke();
|
||||
else
|
||||
methodWithArgs?.Invoke(args);
|
||||
return null;
|
||||
}
|
||||
|
||||
TimerHandler handler;
|
||||
// 先覆盖相同函数的计时
|
||||
if (coverBefore)
|
||||
{
|
||||
handler = _getHandler(caller, methodWithArgs, methodWithoutArgs);
|
||||
if (handler != null)
|
||||
{
|
||||
handler.repeat = repeat;
|
||||
handler.userFrame = useFrame;
|
||||
handler.delay = delay;
|
||||
handler.caller = caller;
|
||||
handler.methodWithArgs = methodWithArgs;
|
||||
handler.methodWithoutArgs = methodWithoutArgs;
|
||||
handler.args = args;
|
||||
handler.exeTime = delay + (useFrame ? CurrFrame : CurrTimer + Time.time - _lastTimer);
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
|
||||
// 找到一个空闲的timerHandler
|
||||
handler = _pool.Count > 0 ? _pool.Dequeue() : new TimerHandler();
|
||||
handler.repeat = repeat;
|
||||
handler.userFrame = useFrame;
|
||||
handler.delay = delay;
|
||||
handler.caller = caller;
|
||||
handler.methodWithArgs = methodWithArgs;
|
||||
handler.methodWithoutArgs = methodWithoutArgs;
|
||||
handler.args = args;
|
||||
handler.exeTime = delay + (useFrame ? CurrFrame : CurrTimer + Time.time - _lastTimer);
|
||||
|
||||
// 索引handler
|
||||
_indexHandler(handler);
|
||||
|
||||
// 插入数组
|
||||
_handlers.Add(handler);
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
private TimerHandler _getHandler(object caller, Action<object> methodWithArgs, Action methodWithoutArgs)
|
||||
{
|
||||
var key = caller.GetHashCode() + "_" +
|
||||
(methodWithArgs?.GetHashCode() ?? methodWithoutArgs.GetHashCode());
|
||||
return _map.GetValueOrDefault(key);
|
||||
}
|
||||
|
||||
private void _indexHandler(TimerHandler handler)
|
||||
{
|
||||
var key = handler.caller.GetHashCode() + "_" +
|
||||
(handler.methodWithArgs?.GetHashCode() ?? handler.methodWithoutArgs.GetHashCode());
|
||||
handler.key = key;
|
||||
_map[key] = handler;
|
||||
}
|
||||
|
||||
public void ClearAll(object caller)
|
||||
{
|
||||
if (caller == null) return;
|
||||
for (int i = 0, n = _handlers.Count; i < n; i++)
|
||||
{
|
||||
var handler = _handlers[i];
|
||||
if (handler.caller == caller)
|
||||
{
|
||||
handler.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "handlers:" + _handlers.Count + "pool:" + _pool.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 34564c54c20648aab48bc9dcdc333435
|
||||
timeCreated: 1614222135
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5e43a71d0da8b419eb7cbef21c8c5f33
|
||||
guid: fd8c02dd1a87e714d8b5ae1bee13f2ef
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
11
Assets/Scripts/ThirdParty/Fantasy.Unity/.gitattributes
vendored
Normal file
11
Assets/Scripts/ThirdParty/Fantasy.Unity/.gitattributes
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# Unity YAML 文件使用 LF 换行符
|
||||
*.meta text eol=lf
|
||||
*.asmdef text eol=lf
|
||||
*.unity text eol=lf
|
||||
*.prefab text eol=lf
|
||||
*.mat text eol=lf
|
||||
*.asset text eol=lf
|
||||
*.json text eol=lf
|
||||
|
||||
# Source Generator DLL 是二进制文件
|
||||
*.dll binary
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 876bd2f6c6f095c4c9532c5812ea7545
|
||||
guid: 852fc04751ab07349a96fb31b98b9bf7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf2ee6bcf7bf9f94eb3eab2a87540dcd
|
||||
guid: 78c51fb0052fac049a29ae6289cda649
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -1,15 +1,15 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
|
||||
namespace NBC
|
||||
namespace Fantasy
|
||||
{
|
||||
internal static class CheckUnityVersion
|
||||
{
|
||||
[InitializeOnLoadMethod]
|
||||
private static void OnInitializeOnLoad()
|
||||
{
|
||||
#if !UNITY_2021_3_OR_NEWER
|
||||
Debug.LogError("Fantasy支持的最低版本为Unity2021.3.14f1c1");
|
||||
#if !UNITY_2022_3_OR_NEWER
|
||||
Debug.LogError("Fantasy支持的最低版本为Unity2022.3.622f2");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 455f338921e74471841971fd6b79db01
|
||||
guid: 208434147045e0d4bae1287de7e28fa3
|
||||
timeCreated: 1725943424
|
||||
18
Assets/Scripts/ThirdParty/Fantasy.Unity/Editor/Runtime/Fantasy.Editor.asmdef
vendored
Normal file
18
Assets/Scripts/ThirdParty/Fantasy.Unity/Editor/Runtime/Fantasy.Editor.asmdef
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "Fantasy.Editor",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:0b7224b83ba514121aa026f3857f820a"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
7
Assets/Scripts/ThirdParty/Fantasy.Unity/Editor/Runtime/Fantasy.Editor.asmdef.meta
vendored
Normal file
7
Assets/Scripts/ThirdParty/Fantasy.Unity/Editor/Runtime/Fantasy.Editor.asmdef.meta
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b5d7370e11934b547a4e8dac960ea72e
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -2,7 +2,7 @@ using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC
|
||||
namespace Fantasy
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
public static class FantasyStartup
|
||||
@@ -20,7 +20,7 @@ namespace NBC
|
||||
|
||||
if (string.IsNullOrEmpty(hotUpdatePath))
|
||||
{
|
||||
Debug.LogError("请先在菜单Fantasy-Fantasy Settings里设置HotUpdatePath目录位置");
|
||||
Debug.LogError("请先在菜单Fantasy-Fantasy Settings里设置自动拷贝程序集输出目录位置");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,14 @@ namespace NBC
|
||||
{
|
||||
Directory.CreateDirectory(hotUpdatePath);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
foreach (var file in Directory.GetFiles(hotUpdatePath))
|
||||
{
|
||||
File.Delete(file);
|
||||
}
|
||||
}
|
||||
|
||||
// ReSharper disable once StringLastIndexOfIsCultureSpecific.1
|
||||
if (hotUpdatePath.LastIndexOf("/") != hotUpdatePath.Length - 1)
|
||||
{
|
||||
@@ -1,3 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42156ba2865a4aa4a3e1e57b3ac9b984
|
||||
guid: 13e9d2b99522b124680b7723aaded8d9
|
||||
timeCreated: 1688276977
|
||||
@@ -1,34 +1,46 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBC
|
||||
namespace Fantasy
|
||||
{
|
||||
public class LinkXmlGenerator
|
||||
{
|
||||
private const string LinkPath = "Assets/link.xml";
|
||||
// 在Unity编辑器中运行该方法来生成link.xml文件
|
||||
[UnityEditor.MenuItem("Fantasy/Generate link.xml")]
|
||||
public static void GenerateLinkXml()
|
||||
{
|
||||
using (var writer = new StreamWriter("Assets/link.xml"))
|
||||
{
|
||||
writer.WriteLine("<linker>");
|
||||
var assemblyHashSet = new HashSet<string>();
|
||||
|
||||
foreach (var assembly in FantasySettingsScriptableObject.Instance.includeAssembly)
|
||||
{
|
||||
assemblyHashSet.Add(assembly);
|
||||
}
|
||||
|
||||
if (FantasySettingsScriptableObject.Instance?.linkAssemblyDefinitions != null)
|
||||
{
|
||||
foreach (var assemblyDefinition in FantasySettingsScriptableObject.Instance.linkAssemblyDefinitions)
|
||||
{
|
||||
assemblyHashSet.Add(assemblyDefinition.name);
|
||||
}
|
||||
}
|
||||
|
||||
if (assemblyHashSet.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
writer.WriteLine("<linker>");
|
||||
|
||||
foreach (var assembly in assemblyHashSet)
|
||||
{
|
||||
GenerateLinkXml(writer, assembly, LinkPath);
|
||||
Debug.Log($"{assembly} Link generation completed");
|
||||
}
|
||||
|
||||
if (FantasySettingsScriptableObject.Instance?.linkAssemblyDefinitions != null)
|
||||
{
|
||||
foreach (var linkAssembly in FantasySettingsScriptableObject.Instance.linkAssemblyDefinitions)
|
||||
{
|
||||
GenerateLinkXml(writer, linkAssembly.name, LinkPath);
|
||||
Debug.Log($"{linkAssembly.name} Link generation completed");
|
||||
}
|
||||
}
|
||||
writer.WriteLine("</linker>");
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cda4c9403de946df9c31654416193a21
|
||||
guid: 3360ff806a3d27d478e0e554ebbb291b
|
||||
timeCreated: 1722743236
|
||||
@@ -1,3 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a6997d946f3400e8c423fe1b9245f65
|
||||
guid: 4481b9186fbddb04f96e2e6e56e9ebfc
|
||||
timeCreated: 1688277110
|
||||
@@ -1,6 +1,6 @@
|
||||
using UnityEditor;
|
||||
|
||||
namespace NBC
|
||||
namespace Fantasy
|
||||
{
|
||||
public class FantasySettings
|
||||
{
|
||||
@@ -1,3 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 977a7c172c30403da60286ba39b7bc72
|
||||
guid: 6a31e33b6eab0e847a6e836cf0f9835d
|
||||
timeCreated: 1686913667
|
||||
725
Assets/Scripts/ThirdParty/Fantasy.Unity/Editor/Runtime/Settings/FantasySettingsProvider.cs
vendored
Normal file
725
Assets/Scripts/ThirdParty/Fantasy.Unity/Editor/Runtime/Settings/FantasySettingsProvider.cs
vendored
Normal file
@@ -0,0 +1,725 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Fantasy
|
||||
{
|
||||
public class FantasySettingsProvider : SettingsProvider
|
||||
{
|
||||
private SerializedObject _serializedObject;
|
||||
private SerializedProperty _autoCopyAssembly;
|
||||
private SerializedProperty _hotUpdatePath;
|
||||
private SerializedProperty _hotUpdateAssemblyDefinitions;
|
||||
private SerializedProperty _linkAssemblyDefinitions;
|
||||
private SerializedProperty _includeAssembly;
|
||||
private bool _showLinkXmlConfig = true; // 控制是否显示 Link.xml 配置
|
||||
public FantasySettingsProvider() : base("Project/Fantasy Settings", SettingsScope.Project) { }
|
||||
|
||||
public override void OnActivate(string searchContext, VisualElement rootElement)
|
||||
{
|
||||
Init();
|
||||
base.OnActivate(searchContext, rootElement);
|
||||
}
|
||||
|
||||
public override void OnDeactivate()
|
||||
{
|
||||
base.OnDeactivate();
|
||||
FantasySettingsScriptableObject.Save();
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
_serializedObject?.Dispose();
|
||||
_serializedObject = new SerializedObject(FantasySettingsScriptableObject.Instance);
|
||||
_autoCopyAssembly = _serializedObject.FindProperty("autoCopyAssembly");
|
||||
_hotUpdatePath = _serializedObject.FindProperty("hotUpdatePath");
|
||||
_hotUpdateAssemblyDefinitions = _serializedObject.FindProperty("hotUpdateAssemblyDefinitions");
|
||||
_linkAssemblyDefinitions = _serializedObject.FindProperty("linkAssemblyDefinitions");
|
||||
_includeAssembly = _serializedObject.FindProperty("includeAssembly");
|
||||
}
|
||||
|
||||
public override void OnGUI(string searchContext)
|
||||
{
|
||||
if (_serializedObject == null || !_serializedObject.targetObject)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
using (CreateSettingsWindowGUIScope())
|
||||
{
|
||||
_serializedObject!.Update();
|
||||
|
||||
// ============ Fantasy 框架集成检测 ============
|
||||
DrawCscRspInstallationSection();
|
||||
DrawSectionDivider();
|
||||
EditorGUILayout.Space(10);
|
||||
// ============ 程序集自动拷贝设置 ============
|
||||
EditorGUI.BeginChangeCheck();
|
||||
DrawAssemblyCopySection();
|
||||
DrawSectionDivider();
|
||||
// ============ Link.xml 生成设置 ============
|
||||
DrawLinkXmlSection();
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
_serializedObject.ApplyModifiedProperties();
|
||||
FantasySettingsScriptableObject.Save();
|
||||
EditorApplication.RepaintHierarchyWindow();
|
||||
}
|
||||
|
||||
base.OnGUI(searchContext);
|
||||
}
|
||||
}
|
||||
|
||||
private IDisposable CreateSettingsWindowGUIScope()
|
||||
{
|
||||
var unityEditorAssembly = System.Reflection.Assembly.GetAssembly(typeof(EditorWindow));
|
||||
var type = unityEditorAssembly.GetType("UnityEditor.SettingsWindow+GUIScope");
|
||||
return Activator.CreateInstance(type) as IDisposable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绘制 csc.rsp 安装状态区域
|
||||
/// </summary>
|
||||
private void DrawCscRspInstallationSection()
|
||||
{
|
||||
bool isInstalled = CheckCscRspStatus(out bool fileExists, out bool hasDefine);
|
||||
|
||||
// 状态框
|
||||
if (isInstalled)
|
||||
{
|
||||
// 已安装 - 绿色背景框
|
||||
GUIStyle boxStyle = new GUIStyle(GUI.skin.box)
|
||||
{
|
||||
padding = new RectOffset(10, 10, 10, 10),
|
||||
margin = new RectOffset(0, 0, 5, 5)
|
||||
};
|
||||
|
||||
Color originalColor = GUI.color;
|
||||
GUI.color = new Color(0.7f, 1f, 0.7f); // 绿色背景
|
||||
|
||||
EditorGUILayout.BeginVertical(boxStyle);
|
||||
GUI.color = originalColor;
|
||||
|
||||
GUIStyle installedButtonStyle = new GUIStyle(GUI.skin.button)
|
||||
{
|
||||
fontSize = 13,
|
||||
fontStyle = FontStyle.Bold,
|
||||
fixedHeight = 35
|
||||
};
|
||||
|
||||
Color originalBgColor = GUI.backgroundColor;
|
||||
GUI.backgroundColor = new Color(0.3f, 0.8f, 0.3f); // 绿色
|
||||
GUI.enabled = false; // 禁用按钮,只显示状态
|
||||
GUILayout.Button("✓ FANTASY_UNITY 已安装", installedButtonStyle);
|
||||
GUI.enabled = true;
|
||||
GUI.backgroundColor = originalBgColor;
|
||||
|
||||
EditorGUILayout.Space(3);
|
||||
EditorGUILayout.HelpBox("编译器配置正确,框架功能已启用", MessageType.Info);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 未安装 - 橙黄色背景框
|
||||
GUIStyle boxStyle = new GUIStyle(GUI.skin.box)
|
||||
{
|
||||
padding = new RectOffset(10, 10, 10, 10),
|
||||
margin = new RectOffset(0, 0, 5, 5)
|
||||
};
|
||||
|
||||
Color originalColor = GUI.color;
|
||||
GUI.color = Color.red; // 橙黄色背景
|
||||
|
||||
EditorGUILayout.BeginVertical(boxStyle);
|
||||
GUI.color = originalColor;
|
||||
|
||||
EditorGUILayout.Space(8);
|
||||
|
||||
// 醒目的大按钮
|
||||
GUIStyle buttonStyle = new GUIStyle(GUI.skin.button)
|
||||
{
|
||||
fontSize = 13,
|
||||
fontStyle = FontStyle.Bold,
|
||||
fixedHeight = 35
|
||||
};
|
||||
|
||||
Color originalBgColor = GUI.backgroundColor;
|
||||
GUI.backgroundColor = new Color(0.3f, 0.8f, 1f);
|
||||
if (GUILayout.Button("点击安装 FANTASY_UNITY", buttonStyle))
|
||||
{
|
||||
InstallFantasyUnityDefine();
|
||||
}
|
||||
GUI.backgroundColor = originalBgColor;
|
||||
|
||||
EditorGUILayout.Space(3);
|
||||
EditorGUILayout.HelpBox("安装后可能需要重新编译项目才能生效", MessageType.Info);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测 csc.rsp 文件状态
|
||||
/// </summary>
|
||||
/// <param name="fileExists">文件是否存在</param>
|
||||
/// <param name="hasDefine">是否包含 FANTASY_UNITY 定义</param>
|
||||
/// <returns>是否已正确安装</returns>
|
||||
private bool CheckCscRspStatus(out bool fileExists, out bool hasDefine)
|
||||
{
|
||||
string cscRspPath = Path.Combine(Application.dataPath, "csc.rsp");
|
||||
fileExists = File.Exists(cscRspPath);
|
||||
hasDefine = false;
|
||||
|
||||
if (fileExists)
|
||||
{
|
||||
string content = File.ReadAllText(cscRspPath);
|
||||
// 使用正则表达式精确匹配 FANTASY_UNITY(确保是完整的单词,不是其他定义的一部分)
|
||||
// 匹配条件:FANTASY_UNITY 后面是分号、空白字符、换行或文件结束
|
||||
hasDefine = System.Text.RegularExpressions.Regex.IsMatch(
|
||||
content,
|
||||
@"\bFANTASY_UNITY\b"
|
||||
);
|
||||
}
|
||||
|
||||
return fileExists && hasDefine;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 安装 FANTASY_UNITY 定义到 csc.rsp 文件
|
||||
/// </summary>
|
||||
private void InstallFantasyUnityDefine()
|
||||
{
|
||||
string cscRspPath = Path.Combine(Application.dataPath, "csc.rsp");
|
||||
|
||||
try
|
||||
{
|
||||
if (!File.Exists(cscRspPath))
|
||||
{
|
||||
// 创建新文件
|
||||
File.WriteAllText(cscRspPath, "-define:FANTASY_UNITY\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 读取现有内容
|
||||
string content = File.ReadAllText(cscRspPath);
|
||||
|
||||
// 使用正则表达式精确检测,避免误判(例如 FANTASY_UNITY123)
|
||||
bool hasFantasyUnity = System.Text.RegularExpressions.Regex.IsMatch(
|
||||
content,
|
||||
@"\bFANTASY_UNITY\b"
|
||||
);
|
||||
|
||||
if (!hasFantasyUnity)
|
||||
{
|
||||
// 查找是否已有 -define: 行
|
||||
string[] lines = content.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
bool defineLineFound = false;
|
||||
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
if (lines[i].TrimStart().StartsWith("-define:"))
|
||||
{
|
||||
// 添加到现有的 define 行
|
||||
if (lines[i].EndsWith(";"))
|
||||
{
|
||||
lines[i] = lines[i] + "FANTASY_UNITY";
|
||||
}
|
||||
else
|
||||
{
|
||||
lines[i] = lines[i] + ";FANTASY_UNITY";
|
||||
}
|
||||
defineLineFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (defineLineFound)
|
||||
{
|
||||
content = string.Join("\n", lines) + "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
// 添加新的 define 行到文件开头
|
||||
content = "-define:FANTASY_UNITY\n" + content;
|
||||
}
|
||||
|
||||
File.WriteAllText(cscRspPath, content);
|
||||
}
|
||||
}
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
EditorUtility.DisplayDialog("成功", "FANTASY_UNITY 已经安装成功。\n\n重新编译后生效。", "确定");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError($"安装 FANTASY_UNITY 失败: {ex.Message}");
|
||||
EditorUtility.DisplayDialog("错误", $"安装失败:\n{ex.Message}", "确定");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绘制分隔线
|
||||
/// </summary>
|
||||
private void DrawSectionDivider()
|
||||
{
|
||||
EditorGUILayout.Space(5);
|
||||
|
||||
Rect rect = EditorGUILayout.GetControlRect(false, 1);
|
||||
rect.height = 1;
|
||||
|
||||
// 绘制细线
|
||||
EditorGUI.DrawRect(rect, new Color(0.5f, 0.5f, 0.5f, 0.3f));
|
||||
|
||||
EditorGUILayout.Space(5);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绘制程序集自动拷贝设置区域
|
||||
/// </summary>
|
||||
private void DrawAssemblyCopySection()
|
||||
{
|
||||
// 标题
|
||||
GUIStyle titleStyle = new GUIStyle(EditorStyles.boldLabel)
|
||||
{
|
||||
fontSize = 14,
|
||||
alignment = TextAnchor.MiddleLeft
|
||||
};
|
||||
EditorGUILayout.LabelField("程序集自动拷贝", titleStyle);
|
||||
EditorGUILayout.Space(5);
|
||||
|
||||
// 功能说明
|
||||
GUIStyle descStyle = new GUIStyle(EditorStyles.wordWrappedLabel)
|
||||
{
|
||||
fontSize = 11,
|
||||
normal = { textColor = Color.gray }
|
||||
};
|
||||
EditorGUILayout.LabelField("Unity 编译后自动将指定的程序集文件(DLL + PDB)复制到目标目录,用于热更新或其他用途", descStyle);
|
||||
EditorGUILayout.Space(8);
|
||||
|
||||
// 主开关区域
|
||||
GUIStyle boxStyle = new GUIStyle(GUI.skin.box)
|
||||
{
|
||||
padding = new RectOffset(12, 12, 12, 12),
|
||||
margin = new RectOffset(0, 0, 0, 8)
|
||||
};
|
||||
|
||||
EditorGUILayout.BeginVertical(boxStyle);
|
||||
|
||||
// 开关 - 更大更明显
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
GUIStyle bigToggleStyle = new GUIStyle(EditorStyles.boldLabel)
|
||||
{
|
||||
fontSize = 13
|
||||
};
|
||||
|
||||
bool newValue = EditorGUILayout.ToggleLeft("启用自动拷贝", _autoCopyAssembly.boolValue, bigToggleStyle);
|
||||
|
||||
if (newValue != _autoCopyAssembly.boolValue)
|
||||
{
|
||||
_autoCopyAssembly.boolValue = newValue;
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (_autoCopyAssembly.boolValue)
|
||||
{
|
||||
GUIStyle statusLabel = new GUIStyle(EditorStyles.miniLabel)
|
||||
{
|
||||
fontSize = 11,
|
||||
normal = { textColor = new Color(0f, 0.6f, 0f) }
|
||||
};
|
||||
EditorGUILayout.LabelField("● 已启用", statusLabel, GUILayout.Width(60));
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIStyle statusLabel = new GUIStyle(EditorStyles.miniLabel)
|
||||
{
|
||||
fontSize = 11,
|
||||
normal = { textColor = Color.gray }
|
||||
};
|
||||
EditorGUILayout.LabelField("○ 已禁用", statusLabel, GUILayout.Width(60));
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
// 如果启用了自动拷贝,显示详细配置
|
||||
if (_autoCopyAssembly.boolValue)
|
||||
{
|
||||
EditorGUILayout.Space(15);
|
||||
|
||||
// 步骤 1:设置输出目录
|
||||
DrawStepHeader("1", "设置输出目录");
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.PropertyField(_hotUpdatePath, GUIContent.none);
|
||||
if (GUILayout.Button("选择文件夹", GUILayout.Width(80)))
|
||||
{
|
||||
string path = EditorUtility.OpenFolderPanel("选择程序集输出目录", _hotUpdatePath.stringValue, "");
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
_hotUpdatePath.stringValue = path;
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
// 路径状态提示
|
||||
if (string.IsNullOrEmpty(_hotUpdatePath.stringValue))
|
||||
{
|
||||
EditorGUILayout.Space(3);
|
||||
GUIStyle warningStyle = new GUIStyle(EditorStyles.miniLabel)
|
||||
{
|
||||
normal = { textColor = new Color(0.8f, 0.4f, 0f) }
|
||||
};
|
||||
EditorGUILayout.LabelField("⚠ 请先设置输出目录", warningStyle);
|
||||
}
|
||||
else if (!Directory.Exists(_hotUpdatePath.stringValue))
|
||||
{
|
||||
EditorGUILayout.Space(3);
|
||||
GUIStyle warningStyle = new GUIStyle(EditorStyles.miniLabel)
|
||||
{
|
||||
normal = { textColor = new Color(0.6f, 0.6f, 0f) }
|
||||
};
|
||||
EditorGUILayout.LabelField("ℹ 目录不存在,编译时将自动创建", warningStyle);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.Space(3);
|
||||
GUIStyle successStyle = new GUIStyle(EditorStyles.miniLabel)
|
||||
{
|
||||
normal = { textColor = new Color(0f, 0.6f, 0f) }
|
||||
};
|
||||
EditorGUILayout.LabelField("✓ 目录已配置", successStyle);
|
||||
}
|
||||
|
||||
EditorGUILayout.Space(15);
|
||||
|
||||
// 步骤 2:选择要拷贝的程序集
|
||||
DrawStepHeader("2", "程序集列表");
|
||||
|
||||
GUIStyle hintStyle = new GUIStyle(EditorStyles.miniLabel)
|
||||
{
|
||||
fontSize = 10,
|
||||
normal = { textColor = Color.gray }
|
||||
};
|
||||
EditorGUILayout.LabelField("选择需要自动拷贝的热更新程序集", hintStyle);
|
||||
EditorGUILayout.Space(10);
|
||||
|
||||
// 程序集列表区域
|
||||
if (_hotUpdateAssemblyDefinitions.arraySize == 0)
|
||||
{
|
||||
// 空状态提示框
|
||||
Color originalColor = GUI.color;
|
||||
GUI.color = new Color(0.95f, 0.95f, 0.95f);
|
||||
EditorGUILayout.BeginVertical(GUI.skin.box);
|
||||
GUI.color = originalColor;
|
||||
|
||||
EditorGUILayout.Space(10);
|
||||
|
||||
GUIStyle emptyIconStyle = new GUIStyle(EditorStyles.boldLabel)
|
||||
{
|
||||
fontSize = 20,
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
normal = { textColor = new Color(0.6f, 0.6f, 0.6f) }
|
||||
};
|
||||
EditorGUILayout.LabelField("📦", emptyIconStyle);
|
||||
|
||||
GUIStyle emptyTextStyle = new GUIStyle(EditorStyles.label)
|
||||
{
|
||||
fontSize = 11,
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
normal = { textColor = Color.gray }
|
||||
};
|
||||
EditorGUILayout.LabelField("暂未添加任何程序集", emptyTextStyle);
|
||||
|
||||
EditorGUILayout.Space(5);
|
||||
|
||||
GUIStyle addHintStyle = new GUIStyle(EditorStyles.miniLabel)
|
||||
{
|
||||
fontSize = 10,
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
normal = { textColor = new Color(0.3f, 0.6f, 1f) }
|
||||
};
|
||||
EditorGUILayout.LabelField("点击下方的 + 按钮添加程序集", addHintStyle);
|
||||
|
||||
EditorGUILayout.Space(10);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.Space(5);
|
||||
}
|
||||
|
||||
// 程序集列表
|
||||
EditorGUILayout.PropertyField(_hotUpdateAssemblyDefinitions, new GUIContent(""), true);
|
||||
|
||||
if (_hotUpdateAssemblyDefinitions.arraySize > 0)
|
||||
{
|
||||
EditorGUILayout.Space(5);
|
||||
GUIStyle successStyle = new GUIStyle(EditorStyles.miniLabel)
|
||||
{
|
||||
normal = { textColor = new Color(0f, 0.6f, 0f) }
|
||||
};
|
||||
EditorGUILayout.LabelField($"✓ 已添加 {_hotUpdateAssemblyDefinitions.arraySize} 个程序集", successStyle);
|
||||
}
|
||||
|
||||
// 配置完成状态总结
|
||||
bool isConfigured = !string.IsNullOrEmpty(_hotUpdatePath.stringValue) && _hotUpdateAssemblyDefinitions.arraySize > 0;
|
||||
|
||||
if (isConfigured)
|
||||
{
|
||||
Color originalColor = GUI.color;
|
||||
GUI.color = new Color(0.8f, 1f, 0.8f);
|
||||
EditorGUILayout.BeginVertical(GUI.skin.box);
|
||||
GUI.color = originalColor;
|
||||
|
||||
GUIStyle summaryStyle = new GUIStyle(EditorStyles.miniLabel)
|
||||
{
|
||||
fontSize = 11,
|
||||
normal = { textColor = new Color(0f, 0.5f, 0f) }
|
||||
};
|
||||
EditorGUILayout.LabelField($"✓ 配置完成!编译后将自动拷贝 {_hotUpdateAssemblyDefinitions.arraySize} 个程序集到目标目录", summaryStyle);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.Space(8);
|
||||
EditorGUILayout.HelpBox("启用后可在 Unity 编译完成时自动拷贝程序集文件", MessageType.Info);
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绘制步骤标题
|
||||
/// </summary>
|
||||
private void DrawStepHeader(string stepNumber, string title)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
// 步骤编号
|
||||
GUIStyle stepStyle = new GUIStyle(EditorStyles.boldLabel)
|
||||
{
|
||||
fontSize = 12,
|
||||
normal = { textColor = new Color(0.3f, 0.6f, 1f) }
|
||||
};
|
||||
EditorGUILayout.LabelField($"步骤 {stepNumber}:", stepStyle, GUILayout.Width(60));
|
||||
|
||||
// 步骤标题
|
||||
GUIStyle titleStyle = new GUIStyle(EditorStyles.boldLabel)
|
||||
{
|
||||
fontSize = 12
|
||||
};
|
||||
EditorGUILayout.LabelField(title, titleStyle);
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.Space(5);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绘制 Link.xml 生成设置区域
|
||||
/// </summary>
|
||||
private void DrawLinkXmlSection()
|
||||
{
|
||||
// 标题
|
||||
GUIStyle titleStyle = new GUIStyle(EditorStyles.boldLabel)
|
||||
{
|
||||
fontSize = 14,
|
||||
alignment = TextAnchor.MiddleLeft
|
||||
};
|
||||
EditorGUILayout.LabelField("Link.xml 代码裁剪配置", titleStyle);
|
||||
EditorGUILayout.Space(5);
|
||||
|
||||
// 功能说明
|
||||
GUIStyle descStyle = new GUIStyle(EditorStyles.wordWrappedLabel)
|
||||
{
|
||||
fontSize = 11,
|
||||
normal = { textColor = Color.gray }
|
||||
};
|
||||
EditorGUILayout.LabelField("配置 Link.xml 文件以防止 IL2CPP 编译时过度裁剪反射或动态调用的代码,确保运行时正常", descStyle);
|
||||
EditorGUILayout.Space(8);
|
||||
|
||||
GUIStyle boxStyle = new GUIStyle(GUI.skin.box)
|
||||
{
|
||||
padding = new RectOffset(12, 12, 12, 12),
|
||||
margin = new RectOffset(0, 0, 0, 8)
|
||||
};
|
||||
|
||||
EditorGUILayout.BeginVertical(boxStyle);
|
||||
|
||||
// 显示配置开关
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
GUIStyle bigToggleStyle = new GUIStyle(EditorStyles.boldLabel)
|
||||
{
|
||||
fontSize = 13
|
||||
};
|
||||
|
||||
_showLinkXmlConfig = EditorGUILayout.ToggleLeft("显示配置", _showLinkXmlConfig, bigToggleStyle);
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (_showLinkXmlConfig)
|
||||
{
|
||||
GUIStyle statusLabel = new GUIStyle(EditorStyles.miniLabel)
|
||||
{
|
||||
fontSize = 11,
|
||||
normal = { textColor = new Color(0.3f, 0.6f, 1f) }
|
||||
};
|
||||
EditorGUILayout.LabelField("● 已展开", statusLabel, GUILayout.Width(60));
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIStyle statusLabel = new GUIStyle(EditorStyles.miniLabel)
|
||||
{
|
||||
fontSize = 11,
|
||||
normal = { textColor = Color.gray }
|
||||
};
|
||||
EditorGUILayout.LabelField("○ 已折叠", statusLabel, GUILayout.Width(60));
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
// 如果显示配置,则展示详细内容
|
||||
if (_showLinkXmlConfig)
|
||||
{
|
||||
EditorGUILayout.Space(15);
|
||||
|
||||
// 程序集定义配置标题
|
||||
GUIStyle sectionTitleStyle = new GUIStyle(EditorStyles.boldLabel)
|
||||
{
|
||||
fontSize = 13
|
||||
};
|
||||
EditorGUILayout.LabelField("需要保护的程序集", sectionTitleStyle);
|
||||
EditorGUILayout.Space(3);
|
||||
|
||||
GUIStyle hintStyle = new GUIStyle(EditorStyles.miniLabel)
|
||||
{
|
||||
fontSize = 10,
|
||||
normal = { textColor = Color.gray }
|
||||
};
|
||||
EditorGUILayout.LabelField("选择需要在 IL2CPP 编译时防止代码裁剪的程序集", hintStyle);
|
||||
EditorGUILayout.Space(3);
|
||||
|
||||
// 默认包含程序集说明
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Space(5);
|
||||
GUIStyle defaultInfoStyle = new GUIStyle(EditorStyles.miniLabel)
|
||||
{
|
||||
fontSize = 10,
|
||||
normal = { textColor = new Color(0.4f, 0.6f, 0.8f) }
|
||||
};
|
||||
EditorGUILayout.LabelField("ℹ 默认包含:Assembly-CSharp、Fantasy.Unity", defaultInfoStyle);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.Space(10);
|
||||
|
||||
// 程序集列表区域
|
||||
if (_linkAssemblyDefinitions.arraySize == 0)
|
||||
{
|
||||
// 空状态提示框
|
||||
Color originalColor = GUI.color;
|
||||
GUI.color = new Color(0.95f, 0.95f, 0.95f);
|
||||
EditorGUILayout.BeginVertical(GUI.skin.box);
|
||||
GUI.color = originalColor;
|
||||
|
||||
EditorGUILayout.Space(10);
|
||||
|
||||
GUIStyle emptyIconStyle = new GUIStyle(EditorStyles.boldLabel)
|
||||
{
|
||||
fontSize = 20,
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
normal = { textColor = new Color(0.6f, 0.6f, 0.6f) }
|
||||
};
|
||||
EditorGUILayout.LabelField("📋", emptyIconStyle);
|
||||
|
||||
GUIStyle emptyTextStyle = new GUIStyle(EditorStyles.label)
|
||||
{
|
||||
fontSize = 11,
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
normal = { textColor = Color.gray }
|
||||
};
|
||||
EditorGUILayout.LabelField("暂未添加任何程序集", emptyTextStyle);
|
||||
|
||||
EditorGUILayout.Space(5);
|
||||
|
||||
GUIStyle addHintStyle = new GUIStyle(EditorStyles.miniLabel)
|
||||
{
|
||||
fontSize = 10,
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
normal = { textColor = new Color(0.3f, 0.6f, 1f) }
|
||||
};
|
||||
EditorGUILayout.LabelField("点击下方的 + 按钮添加程序集", addHintStyle);
|
||||
|
||||
EditorGUILayout.Space(10);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.Space(5);
|
||||
}
|
||||
|
||||
// 程序集列表
|
||||
EditorGUILayout.PropertyField(_linkAssemblyDefinitions, new GUIContent(""), true);
|
||||
|
||||
if (_linkAssemblyDefinitions.arraySize > 0)
|
||||
{
|
||||
EditorGUILayout.Space(5);
|
||||
GUIStyle successStyle = new GUIStyle(EditorStyles.miniLabel)
|
||||
{
|
||||
normal = { textColor = new Color(0f, 0.6f, 0f) }
|
||||
};
|
||||
EditorGUILayout.LabelField($"✓ 已添加 {_linkAssemblyDefinitions.arraySize} 个程序集", successStyle);
|
||||
}
|
||||
|
||||
EditorGUILayout.Space(15);
|
||||
|
||||
// 生成按钮区域
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
GUIStyle buttonStyle = new GUIStyle(GUI.skin.button)
|
||||
{
|
||||
fontSize = 13,
|
||||
fontStyle = FontStyle.Bold,
|
||||
fixedHeight = 35,
|
||||
fixedWidth = 200
|
||||
};
|
||||
|
||||
Color originalBgColor = GUI.backgroundColor;
|
||||
GUI.backgroundColor = new Color(0.4f, 0.7f, 1f);
|
||||
if (GUILayout.Button("生成 Link.xml 文件", buttonStyle))
|
||||
{
|
||||
LinkXmlGenerator.GenerateLinkXml();
|
||||
EditorUtility.DisplayDialog("操作成功", "Link.xml 文件已生成", "确定");
|
||||
}
|
||||
GUI.backgroundColor = originalBgColor;
|
||||
GUILayout.FlexibleSpace();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.Space(8);
|
||||
EditorGUILayout.HelpBox("点击上方开关展开配置", MessageType.Info);
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
static FantasySettingsProvider _provider;
|
||||
|
||||
[SettingsProvider]
|
||||
public static SettingsProvider CreateMyCustomSettingsProvider()
|
||||
{
|
||||
if (FantasySettingsScriptableObject.Instance && _provider == null)
|
||||
{
|
||||
_provider = new FantasySettingsProvider();
|
||||
using (var so = new SerializedObject(FantasySettingsScriptableObject.Instance))
|
||||
{
|
||||
_provider.keywords = GetSearchKeywordsFromSerializedObject(so);
|
||||
}
|
||||
}
|
||||
return _provider;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 047b2f13e73f413fa000bf7be979fb4a
|
||||
guid: 19a618703b49e3d4fbcd8223540a77f3
|
||||
timeCreated: 1688380387
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user