mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
[+] 接入ET8服务端
[+] 接入ET8服务端
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4f713fa291a92de45b5676bf54630e83
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4486ddc371c9d0d4489f7826dbe00eff
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8679dc7d3ea6fe4478111d3d3948d6cc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ca25ecd7aaadcc449a2f8417afa3db67
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b5df8fb8c84869f4ea1310d4a0839013
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc5df5d6f1eb16d4fb5aed2972a96bb6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: abf1c389d130cf6409d8d6a79f11d324
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8d62222c52da1d43975f204b0d24b07
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 140ad5927b1206842a0d4eb4024ec059
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3eed1c782eb930d41aa33b6967a6b344
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a24713aa9a3f4eb47ab569ba6919599c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c6ffc219f113f5d4e9b93e02d18e6cee
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user