饭太稀

This commit is contained in:
bob
2025-06-30 10:51:37 +08:00
commit 8e45469c83
753 changed files with 87652 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
using System;
using Fantasy.Async;
using Fantasy.Network;
using Fantasy.Network.Interface;
using Fantasy.Network.Route;
using Fantasy.Platform.Net;
namespace Fantasy;
public sealed class C2G_CreateAddressableRequestHandler : MessageRPC<C2G_CreateAddressableRequest, G2C_CreateAddressableResponse>
{
protected override async FTask Run(Session session, C2G_CreateAddressableRequest request, G2C_CreateAddressableResponse response, Action reply)
{
var scene = session.Scene;
// 1、首先要通过SceneConfig配置文件拿到进行注册Addressable协议的服务器
// 实际开发的时候可能会根据一些规则来选择不同的Map服务器。
// 演示的例子里只有一个MapScene所以我就拿第一个Map服务器进行通讯了。
// 我这里仅是演示功能不是一定要这样拿Map
var sceneConfig = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Map)[0];
// 2、使用Scene.NetworkMessagingComponent.CallInnerRoute方法跟Gate服务器进行通讯。
// CallInnerRoute方法跟Gate服务器进行通讯需要提供一个runTimeId这个Id在sceneConfig.RouteId可以获取到。
// 第二个参数是需要发送网络协议这个协议在Fantasy/Examples/Config/ProtoBuf里的InnerBson或Inner文件定义。
var responseAddressableId = (M2G_ResponseAddressableId)await scene.NetworkMessagingComponent.CallInnerRoute(sceneConfig.RouteId, new G2M_RequestAddressableId());
// 3、给session添加一个AddressableRouteComponent组件这个组件很重要、能否转发Addressable协议主要是通过这个。
var addressableRouteComponent = session.AddComponent<AddressableRouteComponent>();
// 4、拿到MapScene返回的AddressableId赋值给addressableRouteComponent.AddressableId。
addressableRouteComponent.AddressableId = responseAddressableId.AddressableId;
}
}

View File

@@ -0,0 +1,28 @@
using Fantasy.Async;
using Fantasy.Network;
using Fantasy.Network.Interface;
using Fantasy.Network.Route;
// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
namespace Fantasy;
public sealed class C2G_SendAddressableToMapHandler : Message<C2G_SendAddressableToMap>
{
protected override async FTask Run(Session session, C2G_SendAddressableToMap message)
{
var addressableRouteComponent = session.GetComponent<AddressableRouteComponent>();
if (addressableRouteComponent == null)
{
return;
}
// Gate发送一个Addressable消息给MAP
await session.Scene.NetworkMessagingComponent.SendAddressable(addressableRouteComponent.AddressableId,
new G2M_SendAddressableMessage()
{
Tag = message.Tag
});
}
}

View File

@@ -0,0 +1,40 @@
using System;
using Fantasy.Async;
using Fantasy.Entitas;
using Fantasy.Entitas.Interface;
using Fantasy.Network.Interface;
using Fantasy.Network.Route;
using Fantasy.Platform.Net;
using Fantasy.Serialize;
namespace Fantasy;
public class C2M_MoveToMapRequestHandler : AddressableRPC<Unit, C2M_MoveToMapRequest, M2C_MoveToMapResponse>
{
protected override async FTask Run(Unit unit, C2M_MoveToMapRequest request, M2C_MoveToMapResponse response, Action reply)
{
// 1、首先要通过SceneConfig配置文件拿到MapScene的配置文件。
// 这里Map[1]就是要发送的服务器,因为Map[0]是当前的Scene。
var scene = unit.Scene;
var mapSceneConfig = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Map)[1];
// 2、锁定Addressable防止在转移期间有消息发送过来。
// LockAndRelease方法是先锁定Addressable消息后再销毁这个组件。
// 注意:只有这个方法的销毁组件不会去Addressable里删除自己的位置信息。
// 其他的任何销毁这个AddressableMessageComponent方法都会去Addressable里删除自己的位置信息。
await unit.GetComponent<AddressableMessageComponent>().LockAndRelease();
// 3、通过NetworkMessagingComponent发送内部消息给Map的Scene。
var sendResponse = await scene.NetworkMessagingComponent.CallInnerRoute(mapSceneConfig.RouteId,
new M2M_SendUnitRequest()
{
Unit = unit
});
if (sendResponse.ErrorCode != 0)
{
Log.Error($"转移Unit到目标Map服务器失败 ErrorCode={sendResponse.ErrorCode}");
return;
}
// 这个Unit已经转移到另外的Map服务器了所以就不需要这个组件了。
unit.Dispose();
Log.Debug("转移Unit到目标Map服务器成功");
}
}

View File

@@ -0,0 +1,13 @@
using Fantasy.Async;
using Fantasy.Network.Interface;
namespace Fantasy;
public sealed class C2M_TestMessageHandler : Addressable<Unit, C2M_TestMessage>
{
protected override async FTask Run(Unit unit, C2M_TestMessage message)
{
Log.Debug($"C2M_TestMessageHandler = {message.Tag} Scene:{unit.Scene.Scene.SceneConfigId}");
await FTask.CompletedTask;
}
}

View File

@@ -0,0 +1,15 @@
using System;
using Fantasy.Async;
using Fantasy.Network.Interface;
namespace Fantasy;
public sealed class C2M_TestRequestHandler : AddressableRPC<Unit, C2M_TestRequest, M2C_TestResponse>
{
protected override async FTask Run(Unit unit, C2M_TestRequest request, M2C_TestResponse response, Action reply)
{
Log.Debug($"Receive C2M_TestRequest Tag = {request.Tag}");
response.Tag = "Hello M2C_TestResponse";
await FTask.CompletedTask;
}
}

View File

@@ -0,0 +1,13 @@
using Fantasy.Async;
using Fantasy.Network.Interface;
namespace Fantasy;
public sealed class G2M_SendAddressableMessageHandler : Addressable<Unit, G2M_SendAddressableMessage>
{
protected override async FTask Run(Unit unit, G2M_SendAddressableMessage message)
{
Log.Debug($"收到Gate发送来的Addressable消息 message:{message.Tag}");
await FTask.CompletedTask;
}
}

View File

@@ -0,0 +1,21 @@
using System;
using Fantasy.Async;
using Fantasy.Network.Interface;
using Fantasy.Network.Route;
namespace Fantasy;
public class M2M_SendUnitRequestHandler : RouteRPC<Scene, M2M_SendUnitRequest, M2M_SendUnitResponse>
{
protected override async FTask Run(Scene scene, M2M_SendUnitRequest request, M2M_SendUnitResponse response, Action reply)
{
var requestUnit = request.Unit;
// 反序列化Unit把Unit注册到框架中
requestUnit.Deserialize(scene);
// 解锁这个Unit的Addressable消息解锁后Gate上缓存的消息会发送到这里。
// 由于AddressableMessageComponent不支持存数据库所以在发送Unit的时候会自动把这个给忽略掉。
// 所以需要再次手动的添加下才可以。
await requestUnit.AddComponent<AddressableMessageComponent>().UnLock("M2M_SendUnitRequestHandler");
Log.Debug($"传送完成 {scene.SceneConfigId}");
}
}