using IceInternal; using System; using System.Collections.Generic; using System.Text.Json; using Unity.Mathematics; namespace ET.Server { [MessageHandler(SceneType.Gate)] [FriendOfAttribute(typeof(ET.Server.BattleIceAgentComponent))] public class C2G_EnterMapHandler : AMRpcHandler<C2G_EnterMap, G2C_EnterMap> { protected override async ETTask Run(Session session, C2G_EnterMap request, G2C_EnterMap response, Action reply) { if(BattleIceAgentComponent.Instance == null) { Log.Error("Battle ice is null"); response.Error = (int)ErrorCode.EnterMap.BattleSvrErr; reply(); return; } StartSceneConfig startSceneConfig = StartSceneConfigCategory.Instance.GetBySceneName(session.DomainZone(), request.MapName); if (startSceneConfig == null) { response.Error = (int)ErrorCode.EnterMap.MapNotExist; reply(); return; } Player player = session.GetComponent<SessionPlayerComponent>().GetMyPlayer(); var gatemap = player.GetComponent<GateMapComponent>(); if (gatemap != null) { player.RemoveComponent<GateMapComponent>(); } GateMapComponent gateMapComponent = player.AddComponent<GateMapComponent>(); //TODO: 先从所有map scene中查找是不是已经存在 //TODO: 判断找到的scene人数是否已满等限制,如果人数超过限制,则需要传送到不同的战斗服 // 在Gate上动态创建一个Map Scene,把Unit从DB中加载放进来,然后传送到真正的Map中,这样登陆跟传送的逻辑就完全一样了 var scene = await SceneFactory.CreateServerScene(gateMapComponent, player.Id, IdGenerater.Instance.GenerateInstanceId(), gateMapComponent.DomainZone(), "GateMap", SceneType.Map); var scnInstance = scene.InstanceId.ToString(); gateMapComponent.Scene = scene; //TODO: DELETE UnitComponent unitComponent = scene.GetComponent<UnitComponent>(); Unit unit = unitComponent.AddChildWithId<Unit, int>(player.Id, 1001); unit.AddComponent<MoveComponent>(); unit.Position = new float3(-10, 0, -10); NumericComponent numericComponent = unit.AddComponent<NumericComponent>(); numericComponent.Set(NumericType.Speed, 6f); // 速度是6米每秒 numericComponent.Set(NumericType.AOI, 15000); // 视野15米 //unit.AddComponent<AOIEntity, int, float3>(9 * 1000, unit.Position); unit.AddComponent<UnitGateComponent, long>(session.InstanceId); //TODO: m2m transfer unit之后,此unit会dispose,就有bug了 //战斗服=================== //通知战斗服创建副本 var IceZone = BattleIceAgentComponent.Instance.IceZoneManager; var ret = IceZone.createZoneRequest("", Global.GameServerId.ToString(), startSceneConfig.TemplateId, scnInstance, false, toJSON4CreateZone()); Log.Info($"Battle ice createZoneRequest ret: {ret}"); //player进入副本,把player基本信息上报给战斗服 IceZone.begin_playerEnterRequest(unit.Id.ToString(), scnInstance, toJSON4EnterScene(ref unit)).whenCompleted(() => { response.SceneId = scene.InstanceId; reply(); WaitPlayerReady(session.DomainScene(), player.Id).Coroutine(); //TODO:DELETE, 只是将player置入到游戏服的场景管理数据中,并无实际transfer动作。 //TODO:删除Map服,战斗服取代了map服地位 //TransferHelper.Transfer(unit, startSceneConfig.InstanceId, startSceneConfig.Name).Coroutine(); }, (Ice.Exception ex) => { if (ex != null) { Log.Error(ex.Message); //TODO:进入场景失败ErrCode response.Error = -1; response.Message = ex.Message; reply(); return; } }); } private async ETTask WaitPlayerReady(Scene scn, long playerid) { //等待client ready消息 await scn.GetComponent<ObjectWait>().Wait<Wait_PlayerReady>(); //告诉战斗服 i am ready //设置ice战斗服中player状态为ready var IceXmds = BattleIceAgentComponent.Instance.IceXmdsManager; IceXmds.playerReady(playerid.ToString()); } //TODO:按照hotfix--model框架,这段逻辑应该放到modelComponet对应的ComponetSystem中 private string toJSON4CreateZone() { //TODO:从配置中读取副本数据 var json = new { monsterHard = "", calPKValue = false, allowAutoGuard = 1, usespaceDiv = false, sceneType = 1, areaType = 0, canRiding = false, killInterval = 5000, killFullNum = 0, killFullCollSec = 0, averageLevel = 0, }; return System.Text.Json.JsonSerializer.Serialize(json); } //TODO:按照hotfix--model框架,这段逻辑应该放到modelComponet对应的ComponetSystem中 //对应WNPlayer.java/toJSON4EnterScene private string toJSON4EnterScene(ref Unit info) { var json = new { effects = new { MaxHP = 666, HPPer = 1, HP = 233, Attack = 5, AttackPer = 1, }, effectsExt = new { }, skills = new List<SkillInfo>(){ new SkillInfo {id = 110000, level = 1, type = 1, skillTime = 10000, cdTime = 5000, flag = 0 }, new SkillInfo { id = 310000, level = 1, type = 1, skillTime = 10000, cdTime = 5000, flag = 0}, }, tasks = new { }, flags = new { }, playerEntered = false, avatars = new { }, basic = new { name = "nickname", alliesForce = 0, force = 0, pro = 1, serverId = 101, titleId = 0, level = 1, vip = 0, upLevel = 1, beReward = 0, logicServerId = Global.GameServerId, sex = 0, uuid = info.Id.ToString(), potionAddition = 0 }, connectServerId = "bs-" + Global.GameServerId.ToString(), uid = info.Id.ToString(), unitTemplateID = 1, robot = false, tempData = new { //x = this.getPlayerAreaData().bornX, //y = this.getPlayerAreaData().bornY, x = 3, y = 4, direction = 0.1, hp = 1000, mp = 0, }, pkInfo = new { mode = 0, value = 0, level = 1, }, //petBase, addTestPetData = 0, sceneData = new { allowAutoGuard = 1, }, }; var retjson = System.Text.Json.JsonSerializer.Serialize(json, new JsonSerializerOptions { IncludeFields = true }); Log.Debug("==================================="); Log.Debug(retjson.ToString()); Log.Debug("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"); return retjson; } } }