[+] 接入ET8服务端

[+] 接入ET8服务端
This commit is contained in:
ALEXTANG
2023-07-13 12:23:48 +08:00
parent e0be062006
commit 336d4b2eb9
1316 changed files with 130657 additions and 626 deletions

View File

@@ -0,0 +1,26 @@
namespace ET.Server
{
[MessageHandler(SceneType.Gate)]
public class C2G_EnterMapHandler : MessageHandler<C2G_EnterMap, G2C_EnterMap>
{
protected override async ETTask Run(Session session, C2G_EnterMap request, G2C_EnterMap response)
{
Player player = session.GetComponent<SessionPlayerComponent>().Player;
// 在Gate上动态创建一个Map Scene把Unit从DB中加载放进来然后传送到真正的Map中这样登陆跟传送的逻辑就完全一样了
GateMapComponent gateMapComponent = player.AddComponent<GateMapComponent>();
gateMapComponent.Scene = await GateMapFactory.Create(gateMapComponent, player.Id, session.Fiber().IdGenerater.GenerateInstanceId(), "GateMap");
Scene scene = gateMapComponent.Scene;
// 这里可以从DB中加载Unit
Unit unit = UnitFactory.Create(scene, player.Id, UnitType.Player);
StartSceneConfig startSceneConfig = StartSceneConfigCategory.Instance.GetBySceneName(session.Zone(), "Map1");
response.MyId = player.Id;
// 等到一帧的最后面再传送先让G2C_EnterMap返回否则传送消息可能比G2C_EnterMap还早
TransferHelper.TransferAtFrameFinish(unit, startSceneConfig.ActorId, startSceneConfig.Name).Coroutine();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4f713fa291a92de45b5676bf54630e83
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,73 @@
using System;
namespace ET.Server
{
[MessageHandler(SceneType.Gate)]
public class C2G_LoginGateHandler : MessageHandler<C2G_LoginGate, G2C_LoginGate>
{
protected override async ETTask Run(Session session, C2G_LoginGate request, G2C_LoginGate response)
{
Scene root = session.Root();
string account = root.GetComponent<GateSessionKeyComponent>().Get(request.Key);
if (account == null)
{
response.Error = ErrorCore.ERR_ConnectGateKeyError;
response.Message = "Gate key验证失败!";
return;
}
session.RemoveComponent<SessionAcceptTimeoutComponent>();
PlayerComponent playerComponent = root.GetComponent<PlayerComponent>();
Player player = playerComponent.GetByAccount(account);
if (player == null)
{
player = playerComponent.AddChild<Player, string>(account);
playerComponent.Add(player);
PlayerSessionComponent playerSessionComponent = player.AddComponent<PlayerSessionComponent>();
playerSessionComponent.AddComponent<MailBoxComponent, MailBoxType>(MailBoxType.GateSession);
await playerSessionComponent.AddLocation(LocationType.GateSession);
player.AddComponent<MailBoxComponent, MailBoxType>(MailBoxType.UnOrderedMessage);
await player.AddLocation(LocationType.Player);
session.AddComponent<SessionPlayerComponent>().Player = player;
playerSessionComponent.Session = session;
}
else
{
// 判断是否在战斗
PlayerRoomComponent playerRoomComponent = player.GetComponent<PlayerRoomComponent>();
if (playerRoomComponent.RoomActorId != default)
{
CheckRoom(player, session).Coroutine();
}
else
{
PlayerSessionComponent playerSessionComponent = player.GetComponent<PlayerSessionComponent>();
playerSessionComponent.Session = session;
}
}
response.PlayerId = player.Id;
await ETTask.CompletedTask;
}
private static async ETTask CheckRoom(Player player, Session session)
{
Fiber fiber = player.Fiber();
await fiber.WaitFrameFinish();
using Room2G_Reconnect room2GateReconnect = await fiber.Root.GetComponent<ActorSenderComponent>().Call(
player.GetComponent<PlayerRoomComponent>().RoomActorId,
new G2Room_Reconnect() { PlayerId = player.Id }) as Room2G_Reconnect;
G2C_Reconnect g2CReconnect = new() { StartTime = room2GateReconnect.StartTime, Frame = room2GateReconnect.Frame };
g2CReconnect.UnitInfos.AddRange(room2GateReconnect.UnitInfos);
session.Send(g2CReconnect);
session.AddComponent<SessionPlayerComponent>().Player = player;
player.GetComponent<PlayerSessionComponent>().Session = session;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4486ddc371c9d0d4489f7826dbe00eff
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,15 @@
using System;
namespace ET.Server
{
[MessageHandler(SceneType.Gate)]
public class C2G_PingHandler : MessageHandler<C2G_Ping, G2C_Ping>
{
protected override async ETTask Run(Session session, C2G_Ping request, G2C_Ping response)
{
response.Time = session.Fiber().TimeInfo.ServerNow();
await ETTask.CompletedTask;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8679dc7d3ea6fe4478111d3d3948d6cc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,26 @@
using System.Net;
namespace ET.Server
{
[Invoke((long)SceneType.Gate)]
public class FiberInit_Gate: AInvokeHandler<FiberInit, ETTask>
{
public override async ETTask Handle(FiberInit fiberInit)
{
Scene root = fiberInit.Fiber.Root;
root.AddComponent<MailBoxComponent, MailBoxType>(MailBoxType.UnOrderedMessage);
root.AddComponent<TimerComponent>();
root.AddComponent<CoroutineLockComponent>();
root.AddComponent<ActorInnerComponent>();
root.AddComponent<ActorSenderComponent>();
root.AddComponent<PlayerComponent>();
root.AddComponent<GateSessionKeyComponent>();
root.AddComponent<LocationProxyComponent>();
root.AddComponent<ActorLocationSenderComponent>();
StartSceneConfig startSceneConfig = StartSceneConfigCategory.Instance.Get((int)root.Id);
root.AddComponent<NetServerComponent, IPEndPoint>(startSceneConfig.InnerIPPort);
await ETTask.CompletedTask;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ca25ecd7aaadcc449a2f8417afa3db67
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,20 @@
namespace ET.Server
{
public static class GateMapFactory
{
public static async ETTask<Scene> Create(Entity parent, long id, long instanceId, string name)
{
await ETTask.CompletedTask;
Scene scene = EntitySceneFactory.CreateScene(parent, id, instanceId, SceneType.Map, name);
scene.AddComponent<UnitComponent>();
scene.AddComponent<AOIManagerComponent>();
scene.AddComponent<RoomManagerComponent>();
scene.AddComponent<MailBoxComponent, MailBoxType>(MailBoxType.UnOrderedMessage);
return scene;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b5df8fb8c84869f4ea1310d4a0839013
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,30 @@
namespace ET.Server
{
[FriendOf(typeof(GateSessionKeyComponent))]
public static partial class GateSessionKeyComponentSystem
{
public static void Add(this GateSessionKeyComponent self, long key, string account)
{
self.sessionKey.Add(key, account);
self.TimeoutRemoveKey(key).Coroutine();
}
public static string Get(this GateSessionKeyComponent self, long key)
{
string account = null;
self.sessionKey.TryGetValue(key, out account);
return account;
}
public static void Remove(this GateSessionKeyComponent self, long key)
{
self.sessionKey.Remove(key);
}
private static async ETTask TimeoutRemoveKey(this GateSessionKeyComponent self, long key)
{
await self.Fiber().TimerComponent.WaitAsync(20000);
self.sessionKey.Remove(key);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fc5df5d6f1eb16d4fb5aed2972a96bb6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,19 @@
namespace ET.Server
{
[Invoke((long)MailBoxType.GateSession)]
public class MailBoxType_GateSessionHandler: AInvokeHandler<MailBoxInvoker>
{
public override void Handle(MailBoxInvoker args)
{
MailBoxComponent mailBoxComponent = args.MailBoxComponent;
// 这里messageObject要发送出去不能回收
MessageObject messageObject = args.MessageObject;
if (mailBoxComponent.Parent is PlayerSessionComponent playerSessionComponent)
{
playerSessionComponent.Session?.Send(messageObject);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: abf1c389d130cf6409d8d6a79f11d324
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,75 @@
namespace ET.Server
{
[Event(SceneType.Realm | SceneType.Gate)]
public class NetServerComponentOnReadEvent: AEvent<Scene, NetServerComponentOnRead>
{
protected override async ETTask Run(Scene scene, NetServerComponentOnRead args)
{
Session session = args.Session;
object message = args.Message;
Scene root = scene.Root();
if (message is IResponse response)
{
session.OnResponse(response);
return;
}
// 根据消息接口判断是不是Actor消息不同的接口做不同的处理,比如需要转发给Chat Scene可以做一个IChatMessage接口
switch (message)
{
case FrameMessage frameMessage:
{
Player player = session.GetComponent<SessionPlayerComponent>().Player;
ActorId roomActorId = player.GetComponent<PlayerRoomComponent>().RoomActorId;
frameMessage.PlayerId = player.Id;
root.GetComponent<ActorSenderComponent>().Send(roomActorId, frameMessage);
break;
}
case IActorRoom actorRoom:
{
Player player = session.GetComponent<SessionPlayerComponent>().Player;
ActorId roomActorId = player.GetComponent<PlayerRoomComponent>().RoomActorId;
actorRoom.PlayerId = player.Id;
root.GetComponent<ActorSenderComponent>().Send(roomActorId, actorRoom);
break;
}
case IActorLocationMessage actorLocationMessage:
{
long unitId = session.GetComponent<SessionPlayerComponent>().Player.Id;
root.GetComponent<ActorLocationSenderComponent>().Get(LocationType.Unit).Send(unitId, actorLocationMessage);
break;
}
case IActorLocationRequest actorLocationRequest: // gate session收到actor rpc消息先向actor 发送rpc请求再将请求结果返回客户端
{
long unitId = session.GetComponent<SessionPlayerComponent>().Player.Id;
int rpcId = actorLocationRequest.RpcId; // 这里要保存客户端的rpcId
long instanceId = session.InstanceId;
IResponse iResponse = await root.GetComponent<ActorLocationSenderComponent>().Get(LocationType.Unit).Call(unitId, actorLocationRequest);
iResponse.RpcId = rpcId;
// session可能已经断开了所以这里需要判断
if (session.InstanceId == instanceId)
{
session.Send(iResponse);
}
break;
}
case IActorRequest actorRequest: // 分发IActorRequest消息目前没有用到需要的自己添加
{
break;
}
case IActorMessage actorMessage: // 分发IActorMessage消息目前没有用到需要的自己添加
{
break;
}
default:
{
// 非Actor消息
MessageDispatcherComponent.Instance.Handle(session, message);
break;
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d8d62222c52da1d43975f204b0d24b07
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,25 @@
using System.Linq;
namespace ET.Server
{
[FriendOf(typeof(PlayerComponent))]
public static partial class PlayerComponentSystem
{
public static void Add(this PlayerComponent self, Player player)
{
self.dictionary.Add(player.Account, player);
}
public static void Remove(this PlayerComponent self, Player player)
{
self.dictionary.Remove(player.Account);
player.Dispose();
}
public static Player GetByAccount(this PlayerComponent self, string account)
{
self.dictionary.TryGetValue(account, out Player player);
return player;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 140ad5927b1206842a0d4eb4024ec059
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,13 @@
namespace ET.Server
{
[EntitySystemOf(typeof(Player))]
[FriendOf(typeof(Player))]
public static partial class PlayerSystem
{
[EntitySystem]
private static void Awake(this Player self, string a)
{
self.Account = a;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3eed1c782eb930d41aa33b6967a6b344
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
using System;
namespace ET.Server
{
[ActorMessageHandler(SceneType.Gate)]
public class R2G_GetLoginKeyHandler : ActorMessageHandler<Scene, R2G_GetLoginKey, G2R_GetLoginKey>
{
protected override async ETTask Run(Scene scene, R2G_GetLoginKey request, G2R_GetLoginKey response)
{
long key = RandomGenerator.RandInt64();
scene.GetComponent<GateSessionKeyComponent>().Add(key, request.Account);
response.Key = key;
response.GateId = scene.Id;
await ETTask.CompletedTask;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a24713aa9a3f4eb47ab569ba6919599c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,24 @@
namespace ET.Server
{
[EntitySystemOf(typeof(SessionPlayerComponent))]
public static partial class SessionPlayerComponentSystem
{
[EntitySystem]
private static void Destroy(this SessionPlayerComponent self)
{
Scene root = self.Root();
if (root.IsDisposed)
{
return;
}
// 发送断线消息
root.GetComponent<ActorLocationSenderComponent>().Get(LocationType.Unit).Send(self.Player.Id, new G2M_SessionDisconnect());
}
[EntitySystem]
private static void Awake(this SessionPlayerComponent self)
{
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c6ffc219f113f5d4e9b93e02d18e6cee
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: