提交示例代码
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Entitas.Interface;
|
||||
// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
|
||||
#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class GateAccountFlagComponentSystem : DestroySystem<GateAccountFlagComponent>
|
||||
{
|
||||
protected override void Destroy(GateAccountFlagComponent self)
|
||||
{
|
||||
// DestroyAsync(self).Coroutine();
|
||||
|
||||
var selfAccount = self.Account;
|
||||
if (selfAccount == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var selfAccountMailRouteId = selfAccount.MailRouteId;
|
||||
GateLoginHelper.Offline(self.Scene, selfAccountMailRouteId).Coroutine();
|
||||
self.Account = null;
|
||||
selfAccount.Dispose();
|
||||
}
|
||||
|
||||
// private async FTask DestroyAsync(GateAccountFlagComponent self)
|
||||
// {
|
||||
// var selfAccount = self.Account;
|
||||
// if (selfAccount == null)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// await GateLoginHelper.Offline(self.Scene,selfAccount.MailRouteId)
|
||||
// self.Account = null;
|
||||
// selfAccount.Dispose();
|
||||
// }
|
||||
}
|
||||
23
邮件系统课程完整代码/Server/Hotfix/Gate/Handler/C2G_ExitHandler.cs
Normal file
23
邮件系统课程完整代码/Server/Hotfix/Gate/Handler/C2G_ExitHandler.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Network.Interface;
|
||||
// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class C2G_ExitHandler : Message<C2G_Exit>
|
||||
{
|
||||
protected override async FTask Run(Session session, C2G_Exit message)
|
||||
{
|
||||
var gateAccountFlagComponent = session.GetComponent<GateAccountFlagComponent>();
|
||||
if (gateAccountFlagComponent == null)
|
||||
{
|
||||
Log.Warning($"有用户不是通过正常途径访问到这个接口,IP:{session.RemoteEndPoint.ToString()}");
|
||||
return;
|
||||
}
|
||||
Log.Debug($"用户名:{gateAccountFlagComponent.Account.Name} 退出游戏的协议。");
|
||||
// 如果执行了这个session.Dispose,就会断开这个连接,这样的情况下,客户端也会断开。
|
||||
session.Dispose();
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Helper;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Network.Interface;
|
||||
#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type.
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class C2G_LoginRequestHandler : MessageRPC<C2G_LoginRequest, G2C_LoginResponse>
|
||||
{
|
||||
protected override async FTask Run(Session session, C2G_LoginRequest request, G2C_LoginResponse response, Action reply)
|
||||
{
|
||||
var scene = session.Scene;
|
||||
if (string.IsNullOrEmpty(request.Name))
|
||||
{
|
||||
// 返回的1代表的用户名为空。
|
||||
response.ErrorCode = 1;
|
||||
return;
|
||||
}
|
||||
Log.Debug($"登陆的用户名为:{request.Name}");
|
||||
// 检查用户是否存在
|
||||
Account account = null;
|
||||
var worldDataBase = scene.World.DataBase;
|
||||
// 用协程锁来处理,异步逻辑的原子问题。
|
||||
using (await scene.CoroutineLockComponent.Wait(CoroutineLockConst.LoginKey, request.Name.GetHashCode()))
|
||||
{
|
||||
account = await worldDataBase.First<Account>(d => d.Name == request.Name, true);
|
||||
// 如果用户不存在,则创建一个用户。并且保存到数据库中.
|
||||
if (account == null)
|
||||
{
|
||||
account = Entity.Create<Account>(scene, true, true);
|
||||
account.Name = request.Name;
|
||||
account.CreateTime = TimeHelper.Now;
|
||||
await worldDataBase.Save(account);
|
||||
Log.Debug($"当前账号:{request.Name} 不存在,所以创建了一个新的账号。");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Debug($"当前账号:{request.Name} 已经存在,直接登陆。");
|
||||
}
|
||||
}
|
||||
// 跟Session关联上Account,下次发送消息,直接可以通过GateAccountFlagComponent来获取Account。
|
||||
session.AddComponent<GateAccountFlagComponent>().Account = account;
|
||||
// 登陆到其他服务器。
|
||||
var result = await GateLoginHelper.Online(session, account);
|
||||
if (result != 0)
|
||||
{
|
||||
response.ErrorCode = result;
|
||||
Log.Error($"登陆到其他服务器失败,ErrorCode:{result}");
|
||||
return;
|
||||
}
|
||||
Log.Debug($"登陆成功 Name:{account.Name}");
|
||||
// 用这个方法来暂时消除async的黄色波浪线。这个只是为了消除黄色的波浪线,如果有await这个就可以不用。
|
||||
// await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
69
邮件系统课程完整代码/Server/Hotfix/Gate/Helper/GateLoginHelper.cs
Normal file
69
邮件系统课程完整代码/Server/Hotfix/Gate/Helper/GateLoginHelper.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Platform.Net;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public static class GateLoginHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Gate服务器登陆到其他服务器接口
|
||||
/// </summary>
|
||||
/// <param name="session"></param>
|
||||
/// <param name="account"></param>
|
||||
/// <returns></returns>
|
||||
public static async FTask<uint> Online(Session session, Account account)
|
||||
{
|
||||
// 这里应该编写登陆到其他服务器的逻辑,现在没有暂时空着.
|
||||
// 1、如何得到Mail服务器的地址。✅
|
||||
// 2、如何做到发送到Gate服务器自动中间消息给Mail。
|
||||
// 3、就算是Gate可以中间Mail消息到Mail服务器了,那Mail如何发送消息给Gate再让Gate自动的发送消息给客户端呢。
|
||||
var scene = session.Scene;
|
||||
|
||||
var mailConfig = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Mail)[0];
|
||||
// 挂载自定义路由协议组件,挂载了这个组件后,就可以自动转发Route协议了。
|
||||
var routeComponent = session.GetOrAddComponent<RouteComponent>();
|
||||
// var mailAddress = "127.0.0.1" + mailConfig.InnerPort;
|
||||
//mailConfig.RouteId 423423445678974
|
||||
// 发送服务器之间的消息,需要通过当前Scene的NetworkMessagingComponent组件来进行发送。
|
||||
var response = (Mail2G_LoginResponse)await scene.NetworkMessagingComponent.CallInnerRoute(mailConfig.RouteId, new G2Mail_LoginRequest()
|
||||
{
|
||||
AccountId = account.Id,
|
||||
Name = account.Name,
|
||||
CreateTime = account.CreateTime,
|
||||
GateRouteId = session.RuntimeId
|
||||
});
|
||||
if (response.ErrorCode != 0)
|
||||
{
|
||||
return response.ErrorCode;
|
||||
}
|
||||
// 保存这个MailUnitRouteId,用于后续的下线等操作。
|
||||
account.MailRouteId = response.MailUnitRouteId;
|
||||
// 添加自定义路由协议地址。
|
||||
routeComponent.AddAddress(RouteType.MailRoute, response.MailUnitRouteId);
|
||||
// // Gate服务器发送一个消息给Mail服务器
|
||||
// scene.NetworkMessagingComponent.SendInnerRoute(response.MailUnitRouteId,new G2Mail_TestMessage()
|
||||
// {
|
||||
// Tag = "666"
|
||||
// });
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gate服务器下线其他服务器接口
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="mailRouteId"></param>
|
||||
/// <returns></returns>
|
||||
public static async FTask<uint> Offline(Scene scene, long mailRouteId)
|
||||
{
|
||||
// 给Mail服务器发送下线消息
|
||||
var mailResponse = (Mail2G_ExitResponse)await scene.NetworkMessagingComponent.CallInnerRoute(mailRouteId, new G2Mail_ExitRequest());
|
||||
if (mailResponse.ErrorCode != 0)
|
||||
{
|
||||
Log.Error($"Mail服务器无法正常下线 ErrorCode:{mailResponse.ErrorCode}");
|
||||
return mailResponse.ErrorCode;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user