修改为luban
This commit is contained in:
@@ -4,6 +4,7 @@ using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
using NB.Chat;
|
||||
using NB.Game;
|
||||
using NBF.Social;
|
||||
|
||||
namespace NB.Common;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
using NB.Chat;
|
||||
using NB.Game;
|
||||
using NBF.Social;
|
||||
|
||||
namespace NB.Common;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ public static class ItemFactory
|
||||
/// <param name="configId"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <returns></returns>
|
||||
public static Item Create(Scene scene, uint configId, int count = 1)
|
||||
public static Item Create(Scene scene, int configId, int count = 1)
|
||||
{
|
||||
var item = Entity.Create<Item>(scene, true, true);
|
||||
item.ConfigId = configId;
|
||||
|
||||
@@ -2,7 +2,7 @@ namespace NB.Game;
|
||||
|
||||
public static class ItemHelper
|
||||
{
|
||||
public static ItemBasicType GetType(uint id)
|
||||
public static ItemBasicType GetType(int id)
|
||||
{
|
||||
return (ItemBasicType)(id / 10000);
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ public static class PlayerItemContainerComponentSystem
|
||||
|
||||
#region Add
|
||||
|
||||
public static async FTask Add(this PlayerItemContainerComponent self, Dictionary<uint, int> items)
|
||||
public static async FTask Add(this PlayerItemContainerComponent self, Dictionary<int, int> items)
|
||||
{
|
||||
foreach (var (configId, count) in items)
|
||||
{
|
||||
@@ -105,7 +105,7 @@ public static class PlayerItemContainerComponentSystem
|
||||
await self.Save();
|
||||
}
|
||||
|
||||
public static async FTask Add(this PlayerItemContainerComponent self, uint configId, int count,
|
||||
public static async FTask Add(this PlayerItemContainerComponent self, int configId, int count,
|
||||
bool needSave = true)
|
||||
{
|
||||
var item = ItemFactory.Create(self.Scene, configId, count);
|
||||
|
||||
@@ -158,27 +158,28 @@ public static class PlayerManageComponentSystem
|
||||
player.Exp = 999;
|
||||
player.Head = "xxx.png";
|
||||
|
||||
var list = InitConfig.GetList();
|
||||
// var list = InitConfig.GetList();
|
||||
var list = Configs.Tables.TbInitItemConfig.DataList;
|
||||
|
||||
|
||||
Dictionary<ItemBasicType, Dictionary<uint, int>>
|
||||
addDic = new Dictionary<ItemBasicType, Dictionary<uint, int>>();
|
||||
Dictionary<ItemBasicType, Dictionary<int, int>>
|
||||
addDic = new Dictionary<ItemBasicType, Dictionary<int, int>>();
|
||||
foreach (var initConfig in list)
|
||||
{
|
||||
var itemType = ItemHelper.GetType(initConfig.Id);
|
||||
if (!addDic.TryGetValue(itemType, out var dic))
|
||||
{
|
||||
dic = new Dictionary<uint, int>();
|
||||
dic = new Dictionary<int, int>();
|
||||
addDic.Add(itemType, dic);
|
||||
}
|
||||
|
||||
if (!dic.ContainsKey(initConfig.Id))
|
||||
{
|
||||
dic.Add(initConfig.Id, initConfig.Amount);
|
||||
dic.Add(initConfig.Id, initConfig.Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
dic[initConfig.Id] += initConfig.Amount;
|
||||
dic[initConfig.Id] += initConfig.Count;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ public static class PlayerSystem
|
||||
/// <param name="self"></param>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="items"></param>
|
||||
public static async FTask AddItems(this Player self, Dictionary<uint, int> items)
|
||||
public static async FTask AddItems(this Player self, Dictionary<int, int> items)
|
||||
{
|
||||
|
||||
var itemContainer = self.GetComponent<PlayerItemContainerComponent>();
|
||||
|
||||
@@ -25,7 +25,7 @@ public static class PlayerWalletComponentSystem
|
||||
/// <param name="configId"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <returns></returns>
|
||||
public static bool Have(this PlayerWalletComponent self, uint configId, int count)
|
||||
public static bool Have(this PlayerWalletComponent self, int configId, int count)
|
||||
{
|
||||
if (self.Currency.TryGetValue(configId, out var value))
|
||||
{
|
||||
@@ -38,7 +38,7 @@ public static class PlayerWalletComponentSystem
|
||||
return false;
|
||||
}
|
||||
|
||||
public static async FTask Add(this PlayerWalletComponent self, uint configId, int count)
|
||||
public static async FTask Add(this PlayerWalletComponent self, int configId, int count)
|
||||
{
|
||||
if (count < 1)
|
||||
{
|
||||
@@ -54,7 +54,7 @@ public static class PlayerWalletComponentSystem
|
||||
await self.Save();
|
||||
}
|
||||
|
||||
public static async FTask Sub(this PlayerWalletComponent self, uint configId, int count)
|
||||
public static async FTask Sub(this PlayerWalletComponent self, int configId, int count)
|
||||
{
|
||||
if (count > 0)
|
||||
{
|
||||
|
||||
@@ -12,4 +12,8 @@
|
||||
<ProjectReference Include="..\Entity\Entity.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Social\Chat\Handler\Inner\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -140,8 +140,10 @@ public sealed class OnCreateSceneEvent : AsyncEventSystem<OnCreateScene>
|
||||
Log.Info($"初始化 Social 场景: {scene.Id}");
|
||||
//用于管理玩家的组件
|
||||
scene.AddComponent<SocialUnitManageComponent>();
|
||||
scene.AddComponent<ChatChannelCenterComponent>();
|
||||
scene.AddComponent<MailManageComponent>();
|
||||
//聊天
|
||||
// 聊天频道中控中心组件。
|
||||
scene.AddComponent<ChatChannelCenterComponent>();
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
using System;
|
||||
using Fantasy;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
/// <summary>
|
||||
/// 请求创建频道
|
||||
/// </summary>
|
||||
public class
|
||||
C2S_CreateChannelRequestHandler : AddressRPC<SocialUnit, C2S_CreateChannelRequest, S2C_CreateChannelResponse>
|
||||
{
|
||||
protected override async FTask Run(SocialUnit entity, C2S_CreateChannelRequest request,
|
||||
S2C_CreateChannelResponse response, Action reply)
|
||||
{
|
||||
var channelCenter = entity.Scene.GetComponent<ChatChannelCenterComponent>();
|
||||
if (channelCenter == null)
|
||||
{
|
||||
response.ErrorCode = ErrorCode.ErrServer;
|
||||
return;
|
||||
}
|
||||
|
||||
var channel = await channelCenter.Create(entity);
|
||||
|
||||
response.ChannelId = channel.Id;
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
// using Fantasy;
|
||||
// using Fantasy.Async;
|
||||
// using Fantasy.Network.Interface;
|
||||
//
|
||||
// namespace NB.Chat;
|
||||
//
|
||||
// public class
|
||||
// C2S_GetOfflineMessageRequestHandler : AddressRPC<SocialUnit, C2S_GetOfflineMessageRequest,
|
||||
// S2C_GetOfflineMessageResponse>
|
||||
// {
|
||||
// protected override async FTask Run(SocialUnit entity, C2S_GetOfflineMessageRequest request,
|
||||
// S2C_GetOfflineMessageResponse response,
|
||||
// Action reply)
|
||||
// {
|
||||
// var chatUnitManage = entity.Scene.GetComponent<SocialUnitManageComponent>();
|
||||
// if (chatUnitManage.NotSendMessage.TryGetValue(entity.Id, out var list))
|
||||
// {
|
||||
// response.Message.AddRange(list);
|
||||
// chatUnitManage.NotSendMessage.RemoveByKey(entity.Id);
|
||||
// }
|
||||
//
|
||||
// await FTask.CompletedTask;
|
||||
// }
|
||||
// }
|
||||
@@ -1,61 +0,0 @@
|
||||
using System;
|
||||
using Fantasy;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
/// <summary>
|
||||
/// 请求进入频道
|
||||
/// </summary>
|
||||
public class
|
||||
C2S_JoinChannelRequestHandler : AddressRPC<SocialUnit, C2S_JoinChannelRequest, S2C_JoinChannelResponse>
|
||||
{
|
||||
protected override async FTask Run(SocialUnit entity, C2S_JoinChannelRequest request,
|
||||
S2C_JoinChannelResponse response, Action reply)
|
||||
{
|
||||
if (request.Target < 1)
|
||||
{
|
||||
response.ErrorCode = ErrorCode.ErrArgs;
|
||||
return;
|
||||
}
|
||||
|
||||
var channelCenter = entity.Scene.GetComponent<ChatChannelCenterComponent>();
|
||||
if (channelCenter == null)
|
||||
{
|
||||
response.ErrorCode = ErrorCode.ErrServer;
|
||||
return;
|
||||
}
|
||||
|
||||
var oldChannelId = entity.CurrentChannel;
|
||||
if (oldChannelId > 0)
|
||||
{
|
||||
//退出旧的频道
|
||||
var oldChannel = await channelCenter.Get(oldChannelId);
|
||||
if (oldChannel != null)
|
||||
{
|
||||
oldChannel.Exit(entity);
|
||||
}
|
||||
}
|
||||
|
||||
//加入新频道
|
||||
var newChannel = await channelCenter.Get(request.Target);
|
||||
if (newChannel != null)
|
||||
{
|
||||
if (newChannel.ChannelType == 1)
|
||||
{
|
||||
//工会频道需要再工会才能加入
|
||||
}
|
||||
else if (newChannel.ChannelType == 0)
|
||||
{
|
||||
//地图频道需要判断在这个地图才能加入
|
||||
}
|
||||
|
||||
newChannel.Enter(entity);
|
||||
}
|
||||
else
|
||||
{
|
||||
response.ErrorCode = ErrorCode.ChatNotChannel;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using Fantasy;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Helper;
|
||||
using Fantasy.Network.Interface;
|
||||
using NB.Game;
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
public sealed class
|
||||
C2S_SendMessageRequestHandler : AddressRPC<SocialUnit, C2S_SendMessageRequest, S2C_SendMessageResponse>
|
||||
{
|
||||
protected override async FTask Run(SocialUnit socialUnit, C2S_SendMessageRequest request,
|
||||
S2C_SendMessageResponse response, Action reply)
|
||||
{
|
||||
if (request.Target < 1)
|
||||
{
|
||||
response.ErrorCode = ErrorCode.ErrArgs;
|
||||
return;
|
||||
}
|
||||
|
||||
SocialSceneHelper.BroadcastChannel(socialUnit.Scene, request.Target, new ChatMessageInfo()
|
||||
{
|
||||
SendTime = TimeHelper.Now,
|
||||
Content = request.Message,
|
||||
});
|
||||
// if (request.Type == 0) //频道聊天
|
||||
// {
|
||||
// }
|
||||
// else if (request.Type == 1) //私聊
|
||||
// {
|
||||
// //发送私聊
|
||||
// SocialSceneHelper.PrivateMessage(socialUnit.Scene, socialUnit.Id, request.Target, new ChatMessageInfo()
|
||||
// {
|
||||
// SendTime = TimeHelper.Now,
|
||||
// Content = request.Message,
|
||||
// });
|
||||
// }
|
||||
|
||||
|
||||
// var list = new List<long>()
|
||||
// {
|
||||
// 337951357380329472,
|
||||
// 337951357380329473,
|
||||
// 337951357380329474,
|
||||
// 337951357380329475,
|
||||
// 337951357380329476,
|
||||
// 337951357380329477,
|
||||
// 337951357380329478,
|
||||
// 337951357380329479,
|
||||
// 337951357380329480,
|
||||
// 337951357380329481,
|
||||
// 337951357380329482,
|
||||
// 337951357380329483,
|
||||
// 337951357380329484,
|
||||
// 337951357380329485,
|
||||
// 337951357380329486,
|
||||
// 337951357380329487,
|
||||
// 337951357380329488,
|
||||
// 337951357380329489,
|
||||
// 337951357380329490,
|
||||
// 337951357380329491,
|
||||
// 337951357380329492,
|
||||
// 337951357380329493,
|
||||
// 337951357380329494,
|
||||
// 337951357380329495,
|
||||
// 337951357380329496,
|
||||
// 337951357380329497,
|
||||
// 337951357380329498,
|
||||
// 337951357380329499,
|
||||
// 337951357380329500,
|
||||
// 337951357380329501,
|
||||
// 337951357380329502,
|
||||
// 337951357380329503,
|
||||
// 337951357380329504,
|
||||
// 337951357380329505,
|
||||
// 337951357380329506,
|
||||
// 337951357380329507,
|
||||
// 337951357380329508,
|
||||
// 337951357380329509,
|
||||
// 337951357380329510,
|
||||
// 337951357380329511,
|
||||
// 337951357380329512,
|
||||
// 337951357380329513,
|
||||
// 337951357380329514,
|
||||
// 337951357380329515,
|
||||
// 337951357380329516,
|
||||
// 337951357380329517,
|
||||
// 337951357380329518,
|
||||
// 337951357380329519,
|
||||
// 337951357380329520,
|
||||
// 337951357380329521,
|
||||
// 337951357380329522,
|
||||
// 337951357380329523,
|
||||
// 337951357380329524,
|
||||
// 337951357380329525,
|
||||
// 337951357380329526,
|
||||
// 337951357380329527,
|
||||
// 337951357380329528,
|
||||
// 337951357380329529,
|
||||
// 337951357380329530,
|
||||
// 337951357380329531,
|
||||
// 337951357380329532,
|
||||
// 337951357380329533,
|
||||
// 337951357380329534,
|
||||
// 337951357380329535,
|
||||
// 337951357380329536,
|
||||
// 337951357380329537,
|
||||
// 337951357380329538,
|
||||
// 337951357380329539,
|
||||
// 337951357380329540,
|
||||
// 337951357380329541,
|
||||
// 337951357380329542,
|
||||
// 337951357380329543,
|
||||
// 337951357380329544,
|
||||
// 337951357380329545,
|
||||
// 337951357380329546,
|
||||
// 337951357380329547,
|
||||
// 337951357380329548,
|
||||
// 337951357380329549,
|
||||
// 337951357380329550,
|
||||
// 337951357380329551,
|
||||
// 337951357380329552,
|
||||
// 337951357380329553,
|
||||
// 337951357380329554,
|
||||
// 337951357380329555,
|
||||
// 337951357380329556,
|
||||
// 337951357380329557,
|
||||
// 337951357380329558,
|
||||
// 337951357380329559,
|
||||
// 337951357380329560,
|
||||
// 337951357380329561,
|
||||
// 337951357380329562,
|
||||
// 337951357380329563,
|
||||
// 337951357380329564,
|
||||
// 337951357380329565,
|
||||
// 337951357380329566,
|
||||
// 337951357380329567,
|
||||
// 337951357380329568,
|
||||
// 337951357380329569,
|
||||
// 337951357380329570,
|
||||
// 337951357380329571
|
||||
// };
|
||||
//
|
||||
// Stopwatch stopwatch = new Stopwatch();
|
||||
// stopwatch.Start();
|
||||
// var infoList = await CacheHandler.GetPlayerBasicCacheInfos(socialUnit.Scene,list);
|
||||
// stopwatch.Stop();
|
||||
// Log.Info($"查询数量={infoList.Count} 耗时={stopwatch.ElapsedMilliseconds}");
|
||||
//
|
||||
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// using Fantasy;
|
||||
// using Fantasy.Async;
|
||||
// using Fantasy.Entitas;
|
||||
// using Fantasy.Network.Interface;
|
||||
//
|
||||
// namespace NB.Chat;
|
||||
//
|
||||
// public sealed class G2Chat_LoginRequestHandler : AddressRPC<Scene, G2Chat_LoginRequest, Chat2G_LoginResponse>
|
||||
// {
|
||||
// protected override async FTask Run(Scene scene, G2Chat_LoginRequest request, Chat2G_LoginResponse response, Action reply)
|
||||
// {
|
||||
// var chatUnit = scene.GetComponent<ChatUnitManageComponent>().Add(request.UnitId, request.UserName, request.GateRouteId);
|
||||
// response.ChatRouteId = chatUnit.RunTimeId;
|
||||
// // 这里模拟创建一个频道用于测试用
|
||||
// var chatChannelCenterComponent = scene.GetComponent<ChatChannelCenterComponent>();
|
||||
// var chatChannelComponent = chatChannelCenterComponent.Apply(1);
|
||||
// // 加入到聊天频道
|
||||
// chatChannelComponent.JoinChannel(request.UnitId);
|
||||
// await FTask.CompletedTask;
|
||||
// }
|
||||
// }
|
||||
@@ -0,0 +1,13 @@
|
||||
// using Fantasy.Async;
|
||||
// using Fantasy.Network.Interface;
|
||||
//
|
||||
// namespace NB.Chat;
|
||||
//
|
||||
// public sealed class G2Chat_OfflineRequestHandler : AddressRPC<ChatUnit, G2Chat_OfflineRequest, Chat2G_OfflineResponse>
|
||||
// {
|
||||
// protected override async FTask Run(ChatUnit chatUnit, G2Chat_OfflineRequest request, Chat2G_OfflineResponse response, Action reply)
|
||||
// {
|
||||
// await FTask.CompletedTask;
|
||||
// chatUnit.Scene.GetComponent<ChatUnitManageComponent>().Remove(chatUnit.Id);
|
||||
// }
|
||||
// }
|
||||
@@ -0,0 +1,20 @@
|
||||
using Fantasy;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
public sealed class Other2Chat_ChatMessageHandler : Address<SocialUnit, Other2Chat_ChatMessage>
|
||||
{
|
||||
protected override async FTask Run(SocialUnit chatUnit, Other2Chat_ChatMessage message)
|
||||
{
|
||||
var result = ChatSceneHelper.Distribution(chatUnit, message.ChatInfoTree, false);
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
Log.Warning($"Other2Chat_ChatMessageHandler: Distribution failed, result: {result}");
|
||||
}
|
||||
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using Fantasy;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
public sealed class C2Chat_SendMessageRequestHandler : AddressRPC<SocialUnit, C2Chat_SendMessageRequest, Chat2C_SendMessageResponse>
|
||||
{
|
||||
protected override async FTask Run(SocialUnit chatUnit, C2Chat_SendMessageRequest request, Chat2C_SendMessageResponse response, Action reply)
|
||||
{
|
||||
response.ErrorCode = ChatSceneHelper.Distribution(chatUnit, request.ChatInfoTree);
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
39
Hotfix/Social/Chat/Helper/ChatChannelCenterHelper.cs
Normal file
39
Hotfix/Social/Chat/Helper/ChatChannelCenterHelper.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using Fantasy;
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
public static class ChatChannelCenterHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 申请一个频道
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="channelId"></param>
|
||||
/// <returns></returns>
|
||||
public static ChatChannelComponent Apply(Scene scene, long channelId)
|
||||
{
|
||||
return scene.GetComponent<ChatChannelCenterComponent>().Apply(channelId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试获取一个频道
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="channelId"></param>
|
||||
/// <param name="channel"></param>
|
||||
/// <returns></returns>
|
||||
public static bool TryGet(Scene scene, long channelId, out ChatChannelComponent channel)
|
||||
{
|
||||
return scene.GetComponent<ChatChannelCenterComponent>().TryGet(channelId, out channel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解散一个频道
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="channelId"></param>
|
||||
public static void Disband(Scene scene, long channelId)
|
||||
{
|
||||
scene.GetComponent<ChatChannelCenterComponent>().Disband(channelId);
|
||||
}
|
||||
}
|
||||
30
Hotfix/Social/Chat/Helper/ChatHelper.cs
Normal file
30
Hotfix/Social/Chat/Helper/ChatHelper.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using Fantasy;
|
||||
using Fantasy.Platform.Net;
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
public static class ChatHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 发送一个聊天消息给ChatScene(不能在ChatScene中调用)
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="chatUnitRouteId"></param>
|
||||
/// <param name="tree"></param>
|
||||
public static void SendChatMessage(Scene scene, long chatUnitRouteId, ChatInfoTree tree)
|
||||
{
|
||||
if (scene.SceneType == SceneType.Social)
|
||||
{
|
||||
Log.Warning("ChatHelper.SendChatMessage: scene is not a chat scene.");
|
||||
return;
|
||||
}
|
||||
|
||||
var other2ChatChatMessage = new Other2Chat_ChatMessage()
|
||||
{
|
||||
ChatInfoTree = tree
|
||||
};
|
||||
|
||||
// scene.NetworkMessagingComponent.SendInnerRoute(chatUnitRouteId, other2ChatChatMessage);
|
||||
scene.NetworkMessagingComponent.Send(chatUnitRouteId, other2ChatChatMessage);
|
||||
}
|
||||
}
|
||||
128
Hotfix/Social/Chat/Helper/ChatNodeFactory.cs
Normal file
128
Hotfix/Social/Chat/Helper/ChatNodeFactory.cs
Normal file
@@ -0,0 +1,128 @@
|
||||
// using Fantasy;
|
||||
//
|
||||
// namespace NB.Chat
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// 聊天信息节点
|
||||
// /// </summary>
|
||||
// public static class ChatNodeFactory
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// 添加文本节点
|
||||
// /// </summary>
|
||||
// /// <param name="chatInfoTree"></param>
|
||||
// /// <param name="content"></param>
|
||||
// /// <returns></returns>
|
||||
// public static ChatInfoTree AddendTextNode(this ChatInfoTree chatInfoTree, string content)
|
||||
// {
|
||||
// var chatInfoNode = new ChatInfoNode()
|
||||
// {
|
||||
// ChatNodeType = (int)ChatNodeType.Text,
|
||||
// Content = content
|
||||
// };
|
||||
// chatInfoTree.Node.Add(chatInfoNode);
|
||||
// return chatInfoTree;
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 添加链接节点
|
||||
// /// </summary>
|
||||
// /// <param name="chatInfoTree"></param>
|
||||
// /// <param name="content"></param>
|
||||
// /// <param name="link"></param>
|
||||
// /// <returns></returns>
|
||||
// public static ChatInfoTree AddendLinkNode(this ChatInfoTree chatInfoTree, string content, string link)
|
||||
// {
|
||||
// var chatLinkNode = new ChatLinkNode()
|
||||
// {
|
||||
// Link = link
|
||||
// };
|
||||
// var serializerComponent = chatInfoTree.Scene.GetComponent<SerializerComponent>();
|
||||
// var chatInfoNode = new ChatInfoNode()
|
||||
// {
|
||||
// ChatNodeType = (int)ChatNodeType.Link,
|
||||
// ChatNodeEvent = (int)ChatNodeEvent.OpenLink,
|
||||
// Content = content,
|
||||
// Data = serializerComponent.Serialize(chatLinkNode)
|
||||
// };
|
||||
// chatInfoTree.Node.Add(chatInfoNode);
|
||||
// return chatInfoTree;
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 添加图片节点
|
||||
// /// </summary>
|
||||
// /// <param name="chatInfoTree"></param>
|
||||
// /// <param name="content"></param>
|
||||
// /// <returns></returns>
|
||||
// public static ChatInfoTree AddendImageNode(this ChatInfoTree chatInfoTree, string content)
|
||||
// {
|
||||
// var chatInfoNode = new ChatInfoNode()
|
||||
// {
|
||||
// ChatNodeType = (int)ChatNodeType.Image,
|
||||
// Content = content
|
||||
// };
|
||||
// chatInfoTree.Node.Add(chatInfoNode);
|
||||
// return chatInfoTree;
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 添加打开UI节点
|
||||
// /// </summary>
|
||||
// /// <param name="chatInfoTree"></param>
|
||||
// /// <param name="content"></param>
|
||||
// /// <param name="uiName"></param>
|
||||
// /// <returns></returns>
|
||||
// public static ChatInfoTree AddendOpenUINode(this ChatInfoTree chatInfoTree, string content, string uiName)
|
||||
// {
|
||||
// var chatOpenUINode = new ChatOpenUINode()
|
||||
// {
|
||||
// UIName = uiName
|
||||
// };
|
||||
// var serializerComponent = chatInfoTree.Scene.GetComponent<SerializerComponent>();
|
||||
// var chatInfoNode = new ChatInfoNode()
|
||||
// {
|
||||
// ChatNodeType = (int)ChatNodeType.OpenUI,
|
||||
// ChatNodeEvent = (int)ChatNodeEvent.OpenUI,
|
||||
// Content = content,
|
||||
// Data = serializerComponent.Serialize(chatOpenUINode)
|
||||
// };
|
||||
// chatInfoTree.Node.Add(chatInfoNode);
|
||||
// return chatInfoTree;
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 添加位置节点
|
||||
// /// </summary>
|
||||
// /// <param name="chatInfoTree"></param>
|
||||
// /// <param name="content"></param>
|
||||
// /// <param name="mapName"></param>
|
||||
// /// <param name="mapX"></param>
|
||||
// /// <param name="mapY"></param>
|
||||
// /// <param name="mapZ"></param>
|
||||
// /// <returns></returns>
|
||||
// public static ChatInfoTree AddendPositionNode(this ChatInfoTree chatInfoTree, string content, string mapName,
|
||||
// float mapX, float mapY, float mapZ)
|
||||
// {
|
||||
// var chatPositionNode = new ChatPositionNode()
|
||||
// {
|
||||
// MapName = mapName,
|
||||
// PosX = mapX,
|
||||
// PosY = mapY,
|
||||
// PosZ = mapZ,
|
||||
// };
|
||||
//
|
||||
// var serializerComponent = chatInfoTree.Scene.GetComponent<SerializerComponent>();
|
||||
// var chatInfoNode = new ChatInfoNode()
|
||||
// {
|
||||
// ChatNodeType = (int)ChatNodeType.Position,
|
||||
// ChatNodeEvent = (int)ChatNodeEvent.Position,
|
||||
// Content = content,
|
||||
// Data = serializerComponent.Serialize(chatPositionNode)
|
||||
// };
|
||||
//
|
||||
// chatInfoTree.Node.Add(chatInfoNode);
|
||||
// return chatInfoTree;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
258
Hotfix/Social/Chat/Helper/ChatSceneHelper.cs
Normal file
258
Hotfix/Social/Chat/Helper/ChatSceneHelper.cs
Normal file
@@ -0,0 +1,258 @@
|
||||
using System.Threading.Channels;
|
||||
using Fantasy;
|
||||
using Fantasy.Helper;
|
||||
using Fantasy.Platform.Net;
|
||||
using NBF.Social;
|
||||
|
||||
// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
public static class ChatSceneHelper
|
||||
{
|
||||
private const int ChatCD = 1000;
|
||||
private const int MaxTextLength = 10;
|
||||
private const int MaxShowItemCount = 2;
|
||||
|
||||
/// <summary>
|
||||
/// 聊天消息分发入口
|
||||
/// </summary>
|
||||
/// <param name="chatUnit"></param>
|
||||
/// <param name="tree"></param>
|
||||
/// <param name="isCheckSendTime"></param>
|
||||
/// <returns></returns>
|
||||
public static uint Distribution(SocialUnit chatUnit, ChatInfoTree tree, bool isCheckSendTime = true)
|
||||
{
|
||||
var result = Condition(chatUnit, tree, isCheckSendTime);
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
switch ((ChatChannelType)tree.ChatChannelType)
|
||||
{
|
||||
case ChatChannelType.Broadcast:
|
||||
{
|
||||
Broadcast(chatUnit.Scene, tree);
|
||||
return 0;
|
||||
}
|
||||
case ChatChannelType.Team:
|
||||
{
|
||||
return Channel(chatUnit, tree);
|
||||
}
|
||||
case ChatChannelType.Private:
|
||||
{
|
||||
return Private(chatUnit, tree);
|
||||
}
|
||||
default:
|
||||
{
|
||||
// 这个1代表当前频道不存在。
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 聊天消息条件判断
|
||||
/// </summary>
|
||||
/// <param name="chatUnit"></param>
|
||||
/// <param name="tree"></param>
|
||||
/// <param name="isCheckSendTime"></param>
|
||||
/// <returns></returns>
|
||||
private static uint Condition(SocialUnit chatUnit, ChatInfoTree tree, bool isCheckSendTime = true)
|
||||
{
|
||||
// 每个频道可能聊天的间隔都不一样。
|
||||
// 这里的条件判断,是根据频道的类型,来判断是否到达了聊天的间隔。
|
||||
var now = TimeHelper.Now;
|
||||
|
||||
if (isCheckSendTime)
|
||||
{
|
||||
// 这里的间隔时间,是根据频道的类型,来获取的。
|
||||
chatUnit.SendTime.TryGetValue(tree.ChatChannelType, out var sendTime);
|
||||
// 判定聊天间隔是否到达
|
||||
// 其实的话,这个ChatCD应该是根据频道的类型,来获取的。
|
||||
// 一般的话都是做一个配置表,通过配置表来获取不同频道的时间间隔。
|
||||
if (now - sendTime < ChatCD)
|
||||
{
|
||||
// 这个1代表当前频道聊天的间隔过短
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 判定聊天内容是否超长
|
||||
|
||||
var itemCount = 0;
|
||||
var chatTextSize = 0;
|
||||
|
||||
foreach (var chatInfoNode in tree.Node)
|
||||
{
|
||||
switch ((ChatNodeType)chatInfoNode.ChatNodeType)
|
||||
{
|
||||
case ChatNodeType.Text:
|
||||
{
|
||||
chatTextSize += chatInfoNode.Content.Length;
|
||||
break;
|
||||
}
|
||||
case ChatNodeType.Image:
|
||||
{
|
||||
// 规定图片占聊天消息的5个字符长度
|
||||
chatTextSize += 5;
|
||||
break;
|
||||
}
|
||||
case ChatNodeType.OpenUI:
|
||||
{
|
||||
// 规定OpenUI占聊天消息的10个字符长度
|
||||
chatTextSize += 10;
|
||||
break;
|
||||
}
|
||||
case ChatNodeType.Item:
|
||||
{
|
||||
itemCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (chatTextSize > MaxTextLength)
|
||||
{
|
||||
// 这个2代表当前频道聊天内容超长
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (itemCount > MaxShowItemCount)
|
||||
{
|
||||
// 这个3代表当前频道聊天里道具数量过多
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (isCheckSendTime)
|
||||
{
|
||||
// 更新当前频道的发送时间
|
||||
chatUnit.SendTime[tree.ChatChannelType] = now;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#region 不同聊天频道的实现
|
||||
|
||||
/// <summary>
|
||||
/// 广播消息
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="tree"></param>
|
||||
private static void Broadcast(Scene scene, ChatInfoTree tree)
|
||||
{
|
||||
var networkMessagingComponent = scene.NetworkMessagingComponent;
|
||||
var chatMessage = new Chat2G_ChatMessage()
|
||||
{
|
||||
ChatInfoTree = tree
|
||||
};
|
||||
|
||||
if (tree.Target.Count > 0)
|
||||
{
|
||||
var chatUnitManageComponent = scene.GetComponent<SocialUnitManageComponent>();
|
||||
// 给一部分人广播消息
|
||||
foreach (var chatUnitId in tree.Target)
|
||||
{
|
||||
if (!chatUnitManageComponent.TryGet(chatUnitId, out var chatUnit))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// networkMessagingComponent.SendInnerRoute(chatUnit.GateRouteId, chatMessage);
|
||||
networkMessagingComponent.Send(chatUnit.GateRouteId, chatMessage);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 发送给所有Gate服务器,让Gate服务器转发给其他客户端
|
||||
var gateConfigs = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Gate);
|
||||
foreach (var gateSceneConfig in gateConfigs)
|
||||
{
|
||||
// 这里是要发送一个消息给Gate服务器,Gate服务器再转发给其他客户端
|
||||
// networkMessagingComponent.SendInnerRoute(gateSceneConfig.RouteId, chatMessage);
|
||||
networkMessagingComponent.Send(gateSceneConfig.Address, chatMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送频道消息
|
||||
/// </summary>
|
||||
/// <param name="chatUnit"></param>
|
||||
/// <param name="tree"></param>
|
||||
private static uint Channel(SocialUnit chatUnit, ChatInfoTree tree)
|
||||
{
|
||||
// 那组队,公会、地图、等这个的聊天,如何使用频道呢?
|
||||
// 这里的频道,是指一个频道,比如一个公会的频道,一个队伍的频道,一个地图的频道。
|
||||
// 1、一般组队工会、地图等,都是有一个创建的一个逻辑,咱们个在这个创建的逻辑中,根据队伍、公会、地图的ID
|
||||
// 把这些ID当做频道ID,然后发送到Chat服务器,先申请一个频道,把这个频道ID返回给创建公会队伍的逻辑。
|
||||
// 这时候,队伍公会、发送聊天消息的时候,就会根据这个ID来进行发送。
|
||||
// 2、地图同样道理,创建地图的时候,也会有一个创建的逻辑,这个逻辑会返回一个地图的ID,这个ID就是地图的频道ID。
|
||||
// 3、这这些ID根据频道类型,发送给客户端,客户端发送的时候,根据频道不同,拿不同的ID来发送。
|
||||
|
||||
// 课外:
|
||||
// 客户端创建一个频道、拿到这个频道号,告诉其他人,其他人通过这个频道ID加入到这个频道。
|
||||
// 客户端创建一个频道,邀请其他人加入到这个频道,其他人可能客户端会接收一个协议,就是邀请你加入到这个频道,如果同意,
|
||||
// 你就加入到这个频道(你点同意后,会发送一个消息给聊天服务器,聊天服务器会把你加入到这个频道)。
|
||||
|
||||
if (!chatUnit.Channels.TryGetValue(tree.ChatChannelId, out var channel))
|
||||
{
|
||||
// 这个1代表当前频道不存在。
|
||||
return 1;
|
||||
}
|
||||
|
||||
channel.Send(tree);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送私聊消息
|
||||
/// </summary>
|
||||
/// <param name="chatUnit"></param>
|
||||
/// <param name="tree"></param>
|
||||
/// <returns></returns>
|
||||
private static uint Private(SocialUnit chatUnit, ChatInfoTree tree)
|
||||
{
|
||||
// 私聊,就是两个玩家之间,直接聊天。
|
||||
// 1、首先,客户端需要知道对方的ID,这个ID是通过什么方式获取的呢?
|
||||
// 2、客户端需要发送一个私聊消息给聊天服务器,聊天服务器需要把这个消息转发给对方。
|
||||
// 3、对方收到消息后,需要显示出来。
|
||||
// 4、聊天服务器需要记录这个私聊消息,并把这个消息转发给两个玩家。
|
||||
// 5、两个玩家收到消息后,需要显示出来。
|
||||
|
||||
if (tree.Target == null || tree.Target.Count <= 0)
|
||||
{
|
||||
// 这个1代表对方ID不的合法的。
|
||||
return 1;
|
||||
}
|
||||
|
||||
var targetChatUnitId = tree.Target[0];
|
||||
var scene = chatUnit.Scene;
|
||||
if (!scene.GetComponent<SocialUnitManageComponent>().TryGet(targetChatUnitId, out var targetChatUnit))
|
||||
{
|
||||
// 这个2代表对方不在线。
|
||||
return 2;
|
||||
}
|
||||
|
||||
var networkMessagingComponent = scene.NetworkMessagingComponent;
|
||||
var chatMessage = new Chat2C_Message()
|
||||
{
|
||||
ChatInfoTree = tree
|
||||
};
|
||||
|
||||
// // 先给自己发送一个聊天消息。
|
||||
// networkMessagingComponent.SendInnerRoute(chatUnit.GateRouteId, chatMessage);
|
||||
// // 然后再给对方发送一个聊天消息。
|
||||
// networkMessagingComponent.SendInnerRoute(targetChatUnit.GateRouteId, chatMessage);
|
||||
|
||||
// 先给自己发送一个聊天消息。
|
||||
networkMessagingComponent.Send(chatUnit.GateRouteId, chatMessage);
|
||||
// 然后再给对方发送一个聊天消息。
|
||||
networkMessagingComponent.Send(targetChatUnit.GateRouteId, chatMessage);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
121
Hotfix/Social/Chat/Helper/ChatTreeFactory.cs
Normal file
121
Hotfix/Social/Chat/Helper/ChatTreeFactory.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
using Fantasy;
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
/// <summary>
|
||||
/// 创建聊天树的总入口
|
||||
/// </summary>
|
||||
public static class ChatTreeFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建世界聊天树
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <returns></returns>
|
||||
public static ChatInfoTree World(Scene scene)
|
||||
{
|
||||
return new ChatInfoTree()
|
||||
{
|
||||
Scene = scene,
|
||||
ChatChannelType = (int)ChatChannelType.World,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建私聊聊天树
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <returns></returns>
|
||||
public static ChatInfoTree Private(Scene scene)
|
||||
{
|
||||
return new ChatInfoTree()
|
||||
{
|
||||
Scene = scene,
|
||||
ChatChannelType = (int)ChatChannelType.Private,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建系统聊天树
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <returns></returns>
|
||||
public static ChatInfoTree System(Scene scene)
|
||||
{
|
||||
return new ChatInfoTree()
|
||||
{
|
||||
Scene = scene,
|
||||
ChatChannelType = (int)ChatChannelType.System,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建公广播聊天树
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <returns></returns>
|
||||
public static ChatInfoTree Broadcast(Scene scene)
|
||||
{
|
||||
return new ChatInfoTree()
|
||||
{
|
||||
Scene = scene,
|
||||
ChatChannelType = (int)ChatChannelType.Broadcast,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建公告聊天树
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <returns></returns>
|
||||
public static ChatInfoTree Notice(Scene scene)
|
||||
{
|
||||
return new ChatInfoTree()
|
||||
{
|
||||
Scene = scene,
|
||||
ChatChannelType = (int)ChatChannelType.Notice,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建队伍聊天树
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <returns></returns>
|
||||
public static ChatInfoTree Team(Scene scene)
|
||||
{
|
||||
return new ChatInfoTree()
|
||||
{
|
||||
Scene = scene,
|
||||
ChatChannelType = (int)ChatChannelType.Team,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建附近人聊天树
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <returns></returns>
|
||||
public static ChatInfoTree Near(Scene scene)
|
||||
{
|
||||
return new ChatInfoTree()
|
||||
{
|
||||
Scene = scene,
|
||||
ChatChannelType = (int)ChatChannelType.Near,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建当前地图聊天树
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <returns></returns>
|
||||
public static ChatInfoTree CurrentMap(Scene scene)
|
||||
{
|
||||
return new ChatInfoTree()
|
||||
{
|
||||
Scene = scene,
|
||||
ChatChannelType = (int)ChatChannelType.CurrentMap,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using Fantasy;
|
||||
using Fantasy.Entitas;
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
public static class ChatUnitFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建一个新的Player
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="aId">ToKen令牌传递过来的aId</param>
|
||||
/// <param name="isSaveDataBase">是否在创建的过程中保存到数据库</param>
|
||||
/// <returns></returns>
|
||||
public static SocialUnit Create(Scene scene, long aId)
|
||||
{
|
||||
var player = Entity.Create<SocialUnit>(scene, aId, true, true);
|
||||
return player;
|
||||
}
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Fantasy;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Platform.Net;
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
public static class SocialSceneHelper
|
||||
{
|
||||
#region 消息发送
|
||||
|
||||
/// <summary>
|
||||
/// 发送一条私聊
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="selfId"></param>
|
||||
/// <param name="targetId"></param>
|
||||
/// <param name="message"></param>
|
||||
public static void PrivateMessage(Scene scene, long selfId, long targetId, ChatMessageInfo message)
|
||||
{
|
||||
var chatUnitManage = scene.GetComponent<SocialUnitManageComponent>();
|
||||
if (chatUnitManage == null) return;
|
||||
var chatUnit = chatUnitManage.Get(targetId);
|
||||
message.Type = 1;
|
||||
message.Source = selfId;
|
||||
if (chatUnit != null)
|
||||
{
|
||||
//对方在线
|
||||
BroadcastAll(scene, message, [targetId]);
|
||||
}
|
||||
else
|
||||
{
|
||||
//对方不在线,存入待领取列表,等待玩家下次登录领取
|
||||
chatUnitManage.SaveOfflineMessage(targetId, message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送一条地图消息
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="mapId"></param>
|
||||
/// <param name="message"></param>
|
||||
public static void BroadcastMap(Scene scene, long mapId, ChatMessageInfo message)
|
||||
{
|
||||
var chatUnitManage = scene.GetComponent<SocialUnitManageComponent>();
|
||||
if (chatUnitManage == null) return;
|
||||
HashSet<long> targets = new HashSet<long>();
|
||||
foreach (var (_, chatUnit) in chatUnitManage.Units)
|
||||
{
|
||||
if (chatUnit.MapId == mapId)
|
||||
{
|
||||
targets.Add(chatUnit.Id);
|
||||
}
|
||||
}
|
||||
|
||||
if (targets.Count < 1)
|
||||
{
|
||||
Log.Info("地图在线人数为0,群发取消");
|
||||
return;
|
||||
}
|
||||
|
||||
BroadcastAll(scene, message, targets);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送一条频道消息
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="channelId"></param>
|
||||
/// <param name="message"></param>
|
||||
public static void BroadcastChannel(Scene scene, long channelId, ChatMessageInfo message)
|
||||
{
|
||||
var chatUnitManage = scene.GetComponent<SocialUnitManageComponent>();
|
||||
if (chatUnitManage == null) return;
|
||||
HashSet<long> targets = new HashSet<long>();
|
||||
foreach (var (_, chatUnit) in chatUnitManage.Units)
|
||||
{
|
||||
if (chatUnit.CurrentChannel == channelId)
|
||||
{
|
||||
targets.Add(chatUnit.Id);
|
||||
}
|
||||
}
|
||||
|
||||
if (targets.Count < 1)
|
||||
{
|
||||
Log.Info("频道在线人数为0,群发取消");
|
||||
return;
|
||||
}
|
||||
|
||||
BroadcastAll(scene, message, targets);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 广播消息给所有人
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="targets"></param>
|
||||
public static void BroadcastAll(Scene scene, ChatMessageInfo message, HashSet<long>? targets = null)
|
||||
{
|
||||
//发送给所有Gate服务器,让Gate转发给其他客户端
|
||||
var gateConfigs = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Gate);
|
||||
var sendMessage = new S2G_ChatMessage()
|
||||
{
|
||||
Message = message,
|
||||
};
|
||||
if (targets != null && targets.Count > 0)
|
||||
{
|
||||
sendMessage.IdList.AddRange(targets);
|
||||
}
|
||||
|
||||
var networkMessagingComponent = scene.NetworkMessagingComponent;
|
||||
foreach (var config in gateConfigs)
|
||||
{
|
||||
//发送给Gate服务器转发消息
|
||||
networkMessagingComponent.Send(config.Address, sendMessage);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 上线下线
|
||||
|
||||
// public static async FTask<(long, long)> Online(Scene scene, RoleSimpleInfo roleSimple, long gateRuntimeId)
|
||||
// {
|
||||
// var gameSceneConfig = GetSceneConfig();
|
||||
// var gameRouteId = gameSceneConfig.RouteId;
|
||||
// //连接到游戏中心服
|
||||
// var gameResponse = (S2G_EnterResponse)await scene.NetworkMessagingComponent.CallInnerRoute(
|
||||
// gameRouteId, new G2S_EnterRequest()
|
||||
// {
|
||||
// Role = roleSimple,
|
||||
// GateRouteId = gateRuntimeId
|
||||
// });
|
||||
//
|
||||
// if (gameResponse.ErrorCode != 0)
|
||||
// {
|
||||
// return (0, 0);
|
||||
// }
|
||||
//
|
||||
// return (gameResponse.RoleRouteId, gameRouteId);
|
||||
// }
|
||||
//
|
||||
// public static async FTask Offline(Scene scene, long accountId, long gateRuntimeId, long sceneRouteId)
|
||||
// {
|
||||
// for (int i = 0; i < 10; i++)
|
||||
// {
|
||||
// var gameResponse = (S2G_ExitResponse)await scene.NetworkMessagingComponent.CallInnerRoute(
|
||||
// sceneRouteId, new G2S_ExitRequest()
|
||||
// {
|
||||
// AccountId = accountId,
|
||||
// GateRouteId = gateRuntimeId
|
||||
// });
|
||||
// if (gameResponse.ErrorCode == 0)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Log.Error("重试多次还是退出失败,需检查");
|
||||
// }
|
||||
//
|
||||
// private static SceneConfig GetSceneConfig()
|
||||
// {
|
||||
// var gameSceneConfigs = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Social);
|
||||
//
|
||||
// return gameSceneConfigs.First();
|
||||
// }
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -1,74 +1,42 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Entitas.Interface;
|
||||
using Fantasy.Helper;
|
||||
|
||||
#pragma warning disable CS8602 // Dereference of a possibly null reference.
|
||||
#pragma warning disable CS8601 // Possible null reference assignment.
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
public class ChatChannelCenterComponentAwakeSystem : AwakeSystem<ChatChannelCenterComponent>
|
||||
{
|
||||
protected override void Awake(ChatChannelCenterComponent self)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class ChatChannelCenterComponentDestroySystem : DestroySystem<ChatChannelCenterComponent>
|
||||
public sealed class ChatChannelCenterComponentDestroySystem : DestroySystem<ChatChannelCenterComponent>
|
||||
{
|
||||
protected override void Destroy(ChatChannelCenterComponent self)
|
||||
{
|
||||
foreach (var chatChannelComponent in self.Channels.Values.ToArray())
|
||||
{
|
||||
chatChannelComponent.Dispose();
|
||||
}
|
||||
self.Channels.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ChatChannelCenterComponentSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取一个频道
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
/// <param name="channelId"></param>
|
||||
/// <returns></returns>
|
||||
public static async FTask<ChatChannel?> Get(this ChatChannelCenterComponent self, long channelId)
|
||||
public static ChatChannelComponent Apply(this ChatChannelCenterComponent self, long channelId)
|
||||
{
|
||||
if (self.Channels.TryGetValue(channelId, out var channel))
|
||||
{
|
||||
return channel;
|
||||
}
|
||||
|
||||
//查数据库
|
||||
channel = await self.Scene.World.Database.Query<ChatChannel>(channelId, true);
|
||||
if (channel != null)
|
||||
{
|
||||
self.Channels.Add(channel.Id, channel);
|
||||
}
|
||||
|
||||
channel = Entity.Create<ChatChannelComponent>(self.Scene, channelId, true, true);
|
||||
self.Channels.Add(channelId, channel);
|
||||
return channel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 申请创建一个频道
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
/// <param name="unit"></param>
|
||||
/// <returns></returns>
|
||||
public static async FTask<ChatChannel> Create(this ChatChannelCenterComponent self, SocialUnit unit)
|
||||
public static bool TryGet(this ChatChannelCenterComponent self, long channelId, out ChatChannelComponent channel)
|
||||
{
|
||||
var channel = Entity.Create<ChatChannel>(self.Scene, true, true);
|
||||
channel.Creator = unit.Role.RoleId;
|
||||
channel.CreateTime = TimeHelper.Now;
|
||||
self.Channels.Add(channel.Id, channel);
|
||||
//保存到数据库
|
||||
await self.Scene.World.Database.Save(channel);
|
||||
|
||||
return channel;
|
||||
return self.Channels.TryGetValue(channelId, out channel);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 解散
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
/// <param name="channelId"></param>
|
||||
public static void Disband(this ChatChannelCenterComponent self, long channelId)
|
||||
{
|
||||
if (self.Channels.Remove(channelId, out var channel))
|
||||
@@ -76,6 +44,6 @@ public static class ChatChannelCenterComponentSystem
|
||||
return;
|
||||
}
|
||||
|
||||
channel?.Dispose();
|
||||
channel.Dispose();
|
||||
}
|
||||
}
|
||||
89
Hotfix/Social/Chat/System/ChatChannelComponentSystem.cs
Normal file
89
Hotfix/Social/Chat/System/ChatChannelComponentSystem.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using Fantasy;
|
||||
using Fantasy.Entitas;
|
||||
using NBF.Social;
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
public class MemoryEntity : Entity
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class ChatChannelComponentSystem
|
||||
{
|
||||
public static void Send(this ChatChannelComponent self, ChatInfoTree tree)
|
||||
{
|
||||
var chatUnitManageComponent = self.Scene.GetComponent<SocialUnitManageComponent>();
|
||||
var networkMessagingComponent = self.Scene.NetworkMessagingComponent;
|
||||
var chatMessage = new Chat2C_Message()
|
||||
{
|
||||
ChatInfoTree = tree
|
||||
};
|
||||
|
||||
foreach (var unitId in self.Units)
|
||||
{
|
||||
if (!chatUnitManageComponent.Units.TryGetValue(unitId, out var chatUnit))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// networkMessagingComponent.SendInnerRoute(chatUnit.GateRouteId, chatMessage);
|
||||
networkMessagingComponent.Send(chatUnit.GateRouteId, chatMessage);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool JoinChannel(this ChatChannelComponent self, long chatUnitId)
|
||||
{
|
||||
var chatUnitManageComponent = self.Scene.GetComponent<SocialUnitManageComponent>();
|
||||
|
||||
if (!chatUnitManageComponent.TryGet(chatUnitId, out var chatUnit))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 将当前频道中加入该用户。
|
||||
self.Units.Add(chatUnitId);
|
||||
// 给用户添加频道。
|
||||
if (!chatUnit.Channels.ContainsKey(self.Id))
|
||||
{
|
||||
chatUnit.Channels.Add(self.Id, self);
|
||||
}
|
||||
// 可以在这里给客户端发送一个加入频道成功的消息。
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool IsJoinedChannel(this ChatChannelComponent self, long chatUnitId)
|
||||
{
|
||||
return self.Units.Contains(chatUnitId);
|
||||
}
|
||||
|
||||
public static void ExitChannel(this ChatChannelComponent self, long chatUnitId, bool isRemoveUnitChannel = true)
|
||||
{
|
||||
if (!self.Units.Contains(chatUnitId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var chatUnitManageComponent = self.Scene.GetComponent<SocialUnitManageComponent>();
|
||||
|
||||
if (!chatUnitManageComponent.TryGet(chatUnitId, out var chatUnit))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (isRemoveUnitChannel)
|
||||
{
|
||||
// 给用户移除频道。
|
||||
chatUnit.Channels.Remove(self.Id);
|
||||
}
|
||||
|
||||
// 在当前频道中移除该用户。
|
||||
self.Units.Remove(chatUnitId);
|
||||
// 如果当前频道中没有用户了,则销毁该频道。
|
||||
if (self.Units.Count == 0)
|
||||
{
|
||||
self.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
using Fantasy;
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
public static class ChatChannelSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// 进入频道
|
||||
/// </summary>
|
||||
/// <param name="channel"></param>
|
||||
/// <param name="unit"></param>
|
||||
public static void Enter(this ChatChannel channel, SocialUnit unit)
|
||||
{
|
||||
channel.Units.Add(unit.Id);
|
||||
unit.CurrentChannel = channel.Id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 离开频道
|
||||
/// </summary>
|
||||
/// <param name="channel"></param>
|
||||
/// <param name="unit"></param>
|
||||
public static void Exit(this ChatChannel channel, SocialUnit unit)
|
||||
{
|
||||
channel.Units.Remove(unit.Id);
|
||||
unit.CurrentChannel = 0;
|
||||
}
|
||||
}
|
||||
@@ -1,132 +1,70 @@
|
||||
using System.Collections.Generic;
|
||||
using Fantasy;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Entitas;
|
||||
using NB.Game;
|
||||
// using Fantasy;
|
||||
// using Fantasy.Entitas;
|
||||
// using Fantasy.Entitas.Interface;
|
||||
//
|
||||
// #pragma warning disable CS8601 // Possible null reference assignment.
|
||||
//
|
||||
// namespace NB.Chat;
|
||||
//
|
||||
// public sealed class ChatUnitManageComponentDestroySystem : DestroySystem<ChatUnitManageComponent>
|
||||
// {
|
||||
// protected override void Destroy(ChatUnitManageComponent self)
|
||||
// {
|
||||
// foreach (var chatUnit in self.Units.Values.ToArray())
|
||||
// {
|
||||
// chatUnit.Dispose();
|
||||
// }
|
||||
//
|
||||
// self.Units.Clear();
|
||||
// }
|
||||
// }
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
public static class ChatUnitManageComponentSystem
|
||||
{
|
||||
#region 消息缓存
|
||||
|
||||
/// <summary>
|
||||
/// 离线消息,进入待领取队列
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
/// <param name="targetId"></param>
|
||||
/// <param name="message"></param>
|
||||
public static void SaveOfflineMessage(this SocialUnitManageComponent self, long targetId, ChatMessageInfo message)
|
||||
{
|
||||
// self.NotSendMessage.Add(targetId, message);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 上线下线
|
||||
|
||||
/// <summary>
|
||||
/// 玩家上线
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="accountId"></param>
|
||||
/// <param name="gateRouteId"></param>
|
||||
public static async FTask<SocialUnit?> Online(this SocialUnitManageComponent self, Scene scene,
|
||||
long accountId,
|
||||
long gateRouteId)
|
||||
{
|
||||
// var accountId = roleSimpleInfo.RoleId;
|
||||
if (!self.TryGet(accountId, out var account))
|
||||
{
|
||||
account = ChatUnitFactory.Create(scene, accountId);
|
||||
self.Add(account);
|
||||
}
|
||||
|
||||
if (account != null)
|
||||
{
|
||||
await account.TryComponent<MailComponent>();
|
||||
account.GateRouteId = gateRouteId;
|
||||
// account.Role = roleSimpleInfo;
|
||||
}
|
||||
|
||||
await FTask.CompletedTask;
|
||||
return account;
|
||||
}
|
||||
|
||||
public static async FTask Offline(this SocialUnitManageComponent self, Scene scene, long accountId, long gateRouteId)
|
||||
{
|
||||
if (self.TryGet(accountId, out var unit) && unit != null)
|
||||
{
|
||||
if (unit.GateRouteId == gateRouteId)
|
||||
{
|
||||
Log.Info("退出当前聊天服==");
|
||||
self.Remove(accountId); //如果当前网关和下线的网关一致
|
||||
}
|
||||
}
|
||||
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 获取&移除
|
||||
|
||||
public static void Add(this SocialUnitManageComponent self, SocialUnit account)
|
||||
{
|
||||
self.Units.Add(account.Id, account);
|
||||
}
|
||||
|
||||
public static SocialUnit? Get(this SocialUnitManageComponent self, long accountId)
|
||||
{
|
||||
return self.Units.GetValueOrDefault(accountId);
|
||||
}
|
||||
|
||||
public static bool TryGet(this SocialUnitManageComponent self, long accountId, out SocialUnit? account)
|
||||
{
|
||||
return self.Units.TryGetValue(accountId, out account);
|
||||
}
|
||||
|
||||
public static void Remove(this SocialUnitManageComponent self, long accountId, bool isDispose = true)
|
||||
{
|
||||
if (!self.Units.Remove(accountId, out var account))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isDispose)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
account.Dispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 组件
|
||||
|
||||
/// <summary>
|
||||
/// 尝试给增加相关组件
|
||||
/// </summary>
|
||||
/// <param name="socialUnit"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static async FTask TryComponent<T>(this SocialUnit socialUnit) where T : Entity, new()
|
||||
{
|
||||
if (socialUnit.GetComponent<T>() == null)
|
||||
{
|
||||
var mailComponent = await socialUnit.Scene.World.Database.Query<T>(socialUnit.Id, true);
|
||||
if (mailComponent == null)
|
||||
{
|
||||
//如果没有邮件组件
|
||||
socialUnit.AddComponent<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
socialUnit.AddComponent(mailComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
// public static class ChatUnitManageComponentSystem
|
||||
// {
|
||||
// public static ChatUnit Add(this ChatUnitManageComponent self, long unitId, string userName, long gateRouteId)
|
||||
// {
|
||||
// if (!self.Units.TryGetValue(unitId, out var chatUnit))
|
||||
// {
|
||||
// chatUnit = Entity.Create<ChatUnit>(self.Scene, unitId, true, true);
|
||||
// self.Units.Add(unitId, chatUnit);
|
||||
// Log.Debug(
|
||||
// $"Add ChatUnit Count: {self.Units.Count} UnitId: {unitId} UserName: {userName} GateRouteId: {gateRouteId}");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Log.Debug($"ChatUnit: {chatUnit.UserName}({chatUnit.GateRouteId})");
|
||||
// }
|
||||
//
|
||||
// chatUnit.UserName = userName;
|
||||
// chatUnit.GateRouteId = gateRouteId;
|
||||
// return chatUnit;
|
||||
// }
|
||||
//
|
||||
// public static ChatUnit? Get(this ChatUnitManageComponent self, long unitId)
|
||||
// {
|
||||
// return self.Units.GetValueOrDefault(unitId);
|
||||
// }
|
||||
//
|
||||
// public static bool TryGet(this ChatUnitManageComponent self, long unitId, out ChatUnit chatUnit)
|
||||
// {
|
||||
// return self.Units.TryGetValue(unitId, out chatUnit);
|
||||
// }
|
||||
//
|
||||
// public static void Remove(this ChatUnitManageComponent self, long unitId, bool isDispose = true)
|
||||
// {
|
||||
// // 由于退出频道的时候,也会检查该玩家是否在ChatUnitManageComponent中,所以这里不做移除操作。
|
||||
// if (!self.Units.TryGetValue(unitId, out var chatUnit))
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (isDispose)
|
||||
// {
|
||||
// chatUnit.Dispose();
|
||||
// }
|
||||
//
|
||||
// // 因为玩家已经执行了退出频道的操作了,所以要清除一下这个数据。
|
||||
// self.Units.Remove(unitId);
|
||||
// Log.Debug($"Remove ChatUnit: {chatUnit.UserName}({chatUnit.GateRouteId}) Count: {self.Units.Count}");
|
||||
// }
|
||||
// }
|
||||
@@ -1,11 +0,0 @@
|
||||
using Fantasy.Entitas.Interface;
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
public class ChatUnitSystem : AwakeSystem<SocialUnit>
|
||||
{
|
||||
protected override void Awake(SocialUnit self)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -58,12 +58,12 @@ public class C2S_SendMailRequestHandler : AddressRPC<SocialUnit, C2S_SendMailReq
|
||||
//同步客户端
|
||||
entity.Scene.NetworkMessagingComponent.Send(entity.GateRouteId, res);
|
||||
|
||||
var chatUnit = chatUnitManage.Get(request.Target);
|
||||
|
||||
if (chatUnit != null)
|
||||
{
|
||||
//对方在线
|
||||
entity.Scene.NetworkMessagingComponent.Send(chatUnit.GateRouteId, res);
|
||||
}
|
||||
// var chatUnit = chatUnitManage.Get(request.Target);
|
||||
//
|
||||
// if (chatUnit != null)
|
||||
// {
|
||||
// //对方在线
|
||||
// entity.Scene.NetworkMessagingComponent.Send(chatUnit.GateRouteId, res);
|
||||
// }
|
||||
}
|
||||
}
|
||||
146
Hotfix/Social/SocialUnitManageComponentSystem.cs
Normal file
146
Hotfix/Social/SocialUnitManageComponentSystem.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
using Fantasy;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Entitas.Interface;
|
||||
using NB.Chat;
|
||||
|
||||
namespace NBF.Social;
|
||||
|
||||
public sealed class ChatUnitManageComponentDestroySystem : DestroySystem<SocialUnitManageComponent>
|
||||
{
|
||||
protected override void Destroy(SocialUnitManageComponent self)
|
||||
{
|
||||
foreach (var chatUnit in self.Units.Values.ToArray())
|
||||
{
|
||||
chatUnit.Dispose();
|
||||
}
|
||||
|
||||
self.Units.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static class SocialUnitManageComponentSystem
|
||||
{
|
||||
#region 消息缓存
|
||||
|
||||
/// <summary>
|
||||
/// 离线消息,进入待领取队列
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
/// <param name="targetId"></param>
|
||||
/// <param name="message"></param>
|
||||
public static void SaveOfflineMessage(this SocialUnitManageComponent self, long targetId, ChatMessageInfo message)
|
||||
{
|
||||
// self.NotSendMessage.Add(targetId, message);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 上线下线
|
||||
|
||||
/// <summary>
|
||||
/// 玩家上线
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="accountId"></param>
|
||||
/// <param name="gateRouteId"></param>
|
||||
public static async FTask<SocialUnit?> Online(this SocialUnitManageComponent self, Scene scene,
|
||||
long accountId,
|
||||
long gateRouteId)
|
||||
{
|
||||
// var accountId = roleSimpleInfo.RoleId;
|
||||
if (!self.TryGet(accountId, out var account))
|
||||
{
|
||||
account = Entity.Create<SocialUnit>(scene, accountId, true, true);
|
||||
self.Add(account);
|
||||
}
|
||||
|
||||
if (account != null)
|
||||
{
|
||||
await account.TryComponent<MailComponent>();
|
||||
account.GateRouteId = gateRouteId;
|
||||
// account.Role = roleSimpleInfo;
|
||||
}
|
||||
|
||||
await FTask.CompletedTask;
|
||||
return account;
|
||||
}
|
||||
|
||||
public static async FTask Offline(this SocialUnitManageComponent self, Scene scene, long accountId,
|
||||
long gateRouteId)
|
||||
{
|
||||
if (self.TryGet(accountId, out var unit) && unit != null)
|
||||
{
|
||||
if (unit.GateRouteId == gateRouteId)
|
||||
{
|
||||
Log.Info("退出当前聊天服==");
|
||||
self.Remove(accountId); //如果当前网关和下线的网关一致
|
||||
}
|
||||
}
|
||||
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 获取&移除
|
||||
|
||||
public static void Add(this SocialUnitManageComponent self, SocialUnit account)
|
||||
{
|
||||
self.Units.Add(account.Id, account);
|
||||
}
|
||||
|
||||
public static SocialUnit? Get(this SocialUnitManageComponent self, long accountId)
|
||||
{
|
||||
return self.Units.GetValueOrDefault(accountId);
|
||||
}
|
||||
|
||||
public static bool TryGet(this SocialUnitManageComponent self, long accountId, out SocialUnit? account)
|
||||
{
|
||||
return self.Units.TryGetValue(accountId, out account);
|
||||
}
|
||||
|
||||
public static void Remove(this SocialUnitManageComponent self, long accountId, bool isDispose = true)
|
||||
{
|
||||
if (!self.Units.Remove(accountId, out var account))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isDispose)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
account.Dispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 组件
|
||||
|
||||
/// <summary>
|
||||
/// 尝试给增加相关组件
|
||||
/// </summary>
|
||||
/// <param name="socialUnit"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static async FTask TryComponent<T>(this SocialUnit socialUnit) where T : Entity, new()
|
||||
{
|
||||
if (socialUnit.GetComponent<T>() == null)
|
||||
{
|
||||
var mailComponent = await socialUnit.Scene.World.Database.Query<T>(socialUnit.Id, true);
|
||||
if (mailComponent == null)
|
||||
{
|
||||
//如果没有邮件组件
|
||||
socialUnit.AddComponent<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
socialUnit.AddComponent(mailComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
22
Hotfix/Social/SocialUnitSystem.cs
Normal file
22
Hotfix/Social/SocialUnitSystem.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Fantasy.Entitas.Interface;
|
||||
#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
public sealed class SocialUnitDestroySystem : DestroySystem<SocialUnit>
|
||||
{
|
||||
protected override void Destroy(SocialUnit self)
|
||||
{
|
||||
self.Role.Return();
|
||||
self.Role = null;
|
||||
self.GateRouteId = 0;
|
||||
// 退出当前ChatUnit拥有的所有频道
|
||||
foreach (var (_,chatChannelComponent) in self.Channels)
|
||||
{
|
||||
chatChannelComponent.ExitChannel(self.Id, false);
|
||||
}
|
||||
// 理论情况下,这个self.Channels不会存在因为数据的,因为上面已经给清空掉了。
|
||||
// 但是self.Channels.Clear();还是加上吧,防止以后忘记了。
|
||||
self.Channels.Clear();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user