123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932 |
- using CommonAI.RTS;
- using CommonAI.Zone;
- using CommonAI.Zone.Helper;
- using CommonAI.Zone.Instance;
- using CommonAI.Zone.ZoneEditor;
- using CommonAI.ZoneClient;
- using CommonLang;
- using CommonLang.ByteOrder;
- using CommonLang.IO;
- using CommonLang.IO.Attribute;
- using CommonLang.Log;
- using CommonLang.Property;
- using CommonLang.Protocol;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using CommonAI.ZoneServer;
- using System.Threading;
- using CommonLang.Concurrent;
- using System.Diagnostics;
- using CommonAIServer.Node.Interface;
- using CommonLang.Vector;
- using CommonAI.Zone.Interface;
- namespace CommonAIServer.Node
- {
- public class ZoneNode : BaseZoneNode
- {
- //------------------------------------------------------------------------------------------------------------
- /// <summary>
- /// 存储玩家UUID和场景内单位的对应关系,如果玩家掉线重连,优先从此表内获取单位信息。
- /// </summary>
- private PlayerClientMap mPlayerObjectMap = new PlayerClientMap();
- private bool mEnableAOI = true;
- //最后一次场景掉落物时间
- private long mCheckDropEndTime;
- //------------------------------------------------------------------------------------------------------------
- public ZoneNode(EditorTemplates data_root, ZoneNodeConfig cfg)
- : base(data_root, cfg)
- {
- }
- public int PlayerCount
- {
- get { return mPlayerObjectMap.Count; }
- }
- public bool EnableAOI
- {
- get { return mEnableAOI; }
- set
- {
- lock (this)
- {
- if (mEnableAOI != value)
- {
- mEnableAOI = value;
- OnAoiChanged(value);
- }
- }
- }
- }
- /// <summary>
- /// 根据UUID获取单位
- /// </summary>
- /// <param name="uuid"></param>
- /// <returns></returns>
- public InstancePlayer GetPlayer(string uuid)
- {
- return mPlayerObjectMap.GetPlayer(uuid);
- }
- public PlayerClient GetPlayerClient(string uuid)
- {
- return mPlayerObjectMap.GetClient(uuid);
- }
- public bool GetPlayerAndClient(string uuid, out InstancePlayer player, out PlayerClient client)
- {
- return mPlayerObjectMap.Get(uuid, out player, out client);
- }
- /// <summary>
- /// 遍历所有客户端
- /// </summary>
- /// <param name="action"></param>
- public void ForEachPlayers(Action<PlayerClient> action)
- {
- mPlayerObjectMap.ForEachPlayers(action);
- }
- /// <summary>
- /// 单位进入场景
- /// </summary>
- /// <param name="player"></param>
- /// <param name="temp"></param>
- /// <param name="force"></param>
- /// <param name="level"></param>
- /// <param name="enterPos"></param>
- /// <param name="direction"></param>
- /// <param name="callback"></param>
- /// <param name="callerror"></param>
- public void PlayerEnter(IPlayer player, UnitInfo temp, int force, int alliesForce, int level, Vector2 enterPos,
- float direction,Action<PlayerClient> callback, Action<Exception> callerror)
- {
- // 客户端连接到战斗服 //
- QueueTask(() =>
- {
- try
- {
- if (mPlayerObjectMap.ContainsKey(player.PlayerUUID))
- {
- if(player.BindingPlayer == null)
- {
- log.Warn(this.Name + " Player reconnect : " + player.PlayerUUID);
- }
- else
- {
- log.Warn(this.Name + " Player already exist : " + player.BindingPlayer.Actor.Name +"," +player.PlayerUUID);
- }
- }
- // 场景内已有玩家 //
- InstancePlayer actor = Zone.getPlayerByUUID(player.PlayerUUID);
- if (actor == null)
- {
- // 有出生点则放入出生点 //
- if (enterPos == null)
- {
- enterPos = new Vector2();
- ZoneRegion start = base.Zone.GetEditStartRegion(force);
- if (start != null)
- {
- CMath.RandomPosInRound(Zone.RandomN, start.X, start.Y, start.Radius, ref enterPos);
- }
- else
- {
- // 没有出身点,随机一个出生点 //
- using (var kvs = ListObjectPool< KeyValuePair < int, ZoneRegion>>.AllocAutoRelease())
- {
- base.Zone.GetEditStartRegions(kvs);
- if (kvs.Count > 0)
- {
- start = CUtils.GetRandomInArray(kvs, Zone.RandomN).Value;
- if (start != null)
- {
- CMath.RandomPosInRound(Zone.RandomN, start.X, start.Y, start.Radius, ref enterPos);
- }
- }
- }
- }
- }
- AddUnitEvent add;
- try
- {
- actor = base.Zone.AddUnit(
- temp,
- player.PlayerUUID,
- force,
- level,
- enterPos.X,
- enterPos.Y,
- direction,
- out add, null, "", 0, alliesForce) as InstancePlayer;
- if (actor != null)
- {
- // 初始化 InstanceUnit 各个字段 //
- actor.Alias = player.DisplayName;
- add.Sync.Name = player.DisplayName;
- add.Sync.Level = level;
- }
- }
- catch(Exception e)
- {
- log.Error("AddUnit catch:" + (player == null ? "player null" : player.PlayerUUID) + ", " +
- (enterPos == null ? "pos null" : " pos ok") + ", " + e);
- }
- }
- else
- {
- actor.OnReconnected(temp, force, level, enterPos);
- }
- if (actor != null)
- {
- // 绑定客户端ID和游戏角色 //
- //zc.Actor.ClientID = zc.ID;
- //绑定关系//
- PlayerClient zc = CreatePlayerClient(player, actor);
- // 准备发送当前场景信息 //
- mPlayerObjectMap.PutPlayer(zc);
- zc.Send(new ClientEnterScene(SceneData.ID, Zone.SpaceDivSize, Templates.ResourceVersion), true);
- zc.Send(actor.GenLockActorEvent(player.DisplayName, zc.SyncObjectRange, zc.SyncObjectOutRange, base.UpdateInterval), true);
- zc.Send(actor.GetSyncSkillActives(), true);
- zc.Send(Zone.GetSyncFlagsEvent(), true);
- zc.Start();
- if (!mEnableAOI)
- {
- zc.Send(zc.GetSyncObjectsEvent(), true);
- }
- OnPlayerEntered(zc);
- callback(zc);
- }
- else
- {
- callerror(new Exception("Can not add player : " + temp));
- }
- }
- catch (Exception err)
- {
- log.Error(err.Message, err);
- OnError(err);
- callerror(err);
- }
- });
- }
- /// <summary>
- /// 单位离开场景
- /// </summary>
- /// <param name="player"></param>
- /// <param name="callback"></param>
- /// <param name="callerror"></param>
- /// <param name="keep_object">保留单位</param>
- public void PlayerLeave(InstancePlayer player, Action<PlayerClient> callback, Action<Exception> callerror, bool keep_object = false)
- {
- if (player == null) return;
- QueueTask(() =>
- {
- try
- {
- InstancePlayer out_player;
- PlayerClient out_client;
- if (mPlayerObjectMap.RemoveByKey(player.PlayerUUID, out out_player, out out_client))
- {
- try
- {
- if (!keep_object)
- {
- player.removeFromParent();
- }
- else
- {
- player.OnDisconnected();
- }
- // 通知客户端清理BattleClient //
- out_client.Send(new PlayerLeaveScene(out_player.ID), true);
- OnPlayerLeft(out_client);
- }
- finally
- {
- out_client.Dispose();
- }
- callback(out_client);
- }
- else
- {
- callerror(new Exception("leave Player not exist : " + player.PlayerUUID + "from " + this.Name));
- }
- }
- catch (Exception err)
- {
- log.Error(err.Message, err);
- OnError(err);
- callerror(err);
- }
- });
- }
- //------------------------------------------------------------------------------------------------------------
- #region _Virtual_And_Override_
- protected override void OnZoneUpdate(bool slowRefresh)
- {
- //客户端更新//
- mPlayerObjectMap.ForEachPlayers((PlayerClient c) =>
- {
- c.BeginUpdate(slowRefresh);
- });
- //向客户端推送实时场景信息//
- mPlayerObjectMap.ForEachPlayers((PlayerClient zc) =>
- {
- foreach (IMessage msg in PostZoneEvents)
- {
- zc.Send(msg);
- }
- });
- //客户端更新//
- mPlayerObjectMap.ForEachPlayers((PlayerClient c) =>
- {
- c.EndUpdate(slowRefresh);
- });
- }
- protected virtual void OnAoiChanged(bool enable)
- {
- if (!enable)
- {
- ForEachPlayers((zc) =>
- {
- zc.Send(zc.GetSyncObjectsEvent(), true);
- });
- }
- }
- protected virtual void OnPlayerEntered(PlayerClient client) { }
- protected virtual void OnPlayerLeft(PlayerClient client) { }
- protected void RecordDropItem()
- {
- ////场景掉落物最大存活时间,用来降低检测频率
- this.mCheckDropEndTime = CommonLang.CUtils.localTimeMS + 120000;
- }
- public override bool CheckDropItem()
- {
- return this.mCheckDropEndTime > CommonLang.CUtils.localTimeMS;
- }
- /// <summary>
- /// 过滤消息,过滤掉非知晓消息
- /// </summary>
- /// <param name="client"></param>
- /// <param name="msg"></param>
- /// <returns></returns>
- protected virtual IMessage FilterSendingMessage(PlayerClient client, CommonLang.Protocol.IMessage msg)
- {
- if (!mEnableAOI)
- {
- return msg;
- }
- InstancePlayer mActor = client.Actor;
- if (msg is AddUnitEvent)
- {
- return null;
- }
- else if (msg is AddItemEvent)
- {
- return null;
- }
- else if (msg is AddSpellEvent)
- {
- return null;
- }
- else if (msg is RemoveObjectEvent)
- {
- return null;
- }
- // 过滤不是发给自己的聊天指令 //
- else if (msg is ChatEvent)
- {
- ChatEvent chat = msg as ChatEvent;
- switch (chat.To)
- {
- case ChatMessageType.SystemToForce:
- case ChatMessageType.PlayerToForce:
- if (chat.Force != mActor.Force)
- {
- return null;
- }
- break;
- case ChatMessageType.SystemToPlayer:
- case ChatMessageType.PlayerToPlayer:
- if (!string.Equals(chat.ToPlayerUUID, client.PlayerUUID))
- {
- return null;
- }
- break;
- }
- }
- else if (msg is UnitHitEvent)
- {
- //过滤不是自己有关的伤害//
- UnitHitEvent he = msg as UnitHitEvent;
- //if (he.senderId != mActor.ID && he.object_id != mActor.ID)
- //{
- // ISummonedUnit summon = Zone.getUnit(he.senderId) as ISummonedUnit;
- // if (summon == null || summon.SummonerUnit != mActor)
- // {
- // summon = Zone.getUnit(he.object_id) as ISummonedUnit;
- // if (summon == null || summon.SummonerUnit != mActor)
- // {
- // return null;
- // }
- // }
- //}
- if (he.senderId != mActor.ID && he.object_id != mActor.ID && he.senderMasterId != mActor.ID && he.hitMasterId != mActor.ID)
- {
- if(he.InViewForceSend && he.sender != null && client.IsInView(he.object_id))
- {
- return msg;
- }
- return null;
- }
- }
- else if(msg is PlayerSingleMsg)
- {
- ObjectEvent talnetInfo = msg as ObjectEvent;
- if(talnetInfo.ObjectID != mActor.ID)
- {
- return null;
- }
- }
- else if (msg is PlayerEvent)
- {
- // 过滤不是本人的玩家事件 //
- PlayerEvent pe = msg as PlayerEvent;
- if (pe.object_id != mActor.ID)
- {
- return null;
- }
- }
- else if (msg is ActorMessage)
- {
- // 过滤不是本人的玩家事件 //
- ActorMessage pe = msg as ActorMessage;
- if (pe.ObjectID != mActor.ID)
- {
- return null;
- }
- }
- else if (msg is ObjectEvent)
- {
- // 过滤不在自己感兴趣范围内的消息 //
- ObjectEvent om = msg as ObjectEvent;
- if (om.ObjectID != mActor.ID && !client.IsInView(om.ObjectID))
- {
- return null;
- }
- }
- else if (msg is ClientEvent)
- {
- // 过滤不是发给本人的ClientEvent事件 //
- ClientEvent cm = msg as ClientEvent;
- if (cm.sender != null && cm.sender != mActor)
- {
- return null;
- }
- }
- else if (msg is PositionMessage)
- {
- // 过滤不在自己感兴趣范围内的消息 //
- PositionMessage pm = msg as PositionMessage;
- if (!client.IsLookInRange(pm.X, pm.Y))
- {
- return null;
- }
- }
- return msg;
- }
- #endregion
- //------------------------------------------------------------------------------------------------------------
- //------------------------------------------------------------------------------------------------------------
- #region __客户端__
- protected virtual PlayerClient CreatePlayerClient(IPlayer client, InstancePlayer actor)
- {
- return new PlayerClient(client, actor, this, Config.CLIENT_SYNC_OBJECT_IN_RANGE, Config.CLIENT_SYNC_OBJECT_OUT_RANGE);
- }
- public class PlayerClient : PlayerClientObject
- {
- private static AtomicInteger s_alloc_object_count = new AtomicInteger(0);
- private static AtomicInteger s_active_object_count = new AtomicInteger(0);
- /// <summary>
- /// 未释放实例数量
- /// </summary>
- public static int ActiveCount { get { return s_active_object_count.Value; } }
- /// <summary>
- /// 分配实例数量
- /// </summary>
- public static int AllocCount { get { return s_alloc_object_count.Value; } }
- private readonly IPlayer mClient;
- private readonly ZoneNode mNode;
- private readonly EditorScene mZone;
- private readonly InstancePlayer mActor;
- private readonly float mSyncObjectInRange;
- private readonly float mSyncObjectOutRange;
- private bool mDisposed = false;
- private long mPreUpdateTime = 0;
- // 视野范围内的单位 //
- private readonly HashMap<uint, InstanceZoneObject> mInViewList = new HashMap<uint, InstanceZoneObject>();
- protected List<uint> m_RemovingList = new List<uint>();
- private Pong mSendPong = new Pong();
- public float SyncObjectRange { get { return mSyncObjectInRange; } }
- public float SyncObjectOutRange { get { return mSyncObjectOutRange; } }
- public ZoneNode Node { get { return mNode; } }
- public EditorScene Zone { get { return mZone; } }
- public InstancePlayer Actor { get { return mActor; } }
- public IPlayer Client { get { return mClient; } }
- public string PlayerUUID { get { return mClient.PlayerUUID; } }
- public long UpdateTime { get { return mPreUpdateTime; } set{mPreUpdateTime = value;}
- }
- public PlayerClient(IPlayer client, InstancePlayer actor, ZoneNode node, float look_in_range, float look_out_range)
- {
- s_alloc_object_count++;
- s_active_object_count++;
- this.mActor = actor;
- this.mClient = client;
- this.mNode = node;
- this.mZone = node.Zone;
- this.mSyncObjectInRange = Math.Min(look_in_range, look_out_range);
- this.mSyncObjectOutRange = Math.Max(look_in_range, look_out_range);
- if ((int)(mSyncObjectOutRange / mZone.SpaceDivSize) <= (int)(mSyncObjectInRange / mZone.SpaceDivSize))
- {
- mSyncObjectOutRange = mSyncObjectInRange + mZone.SpaceDivSize;
- }
- this.mInViewList.Add(mActor.ID, mActor);
- this.mClient.Listen(RecvInternal);
- this.mClient.BindingPlayer = this;
- this.mClient.OnConnected(this);
- }
- ~PlayerClient()
- {
- s_alloc_object_count--;
- }
- internal void Dispose()
- {
- if (mDisposed) { return; }
- this.Disposing();
- this.mClient.OnDisconnect(this);
- this.mClient.BindingPlayer = null;
- this.mDisposed = true;
- s_active_object_count--;
- }
- protected virtual void Disposing() { }
- protected virtual void OnStart() { }
- protected virtual void OnBeginUpdate() { }
- protected virtual void OnEndUpdate() { }
- internal void Start()
- {
- OnStart();
- BeginUpdate(true);
- }
- /// <summary>
- /// 定时更新Client
- /// </summary>
- internal void BeginUpdate(bool slowRefresh)
- {
- OnBeginUpdate();
- if (mNode.mEnableAOI && slowRefresh)
- {
- LookInRange();
- }
- }
- internal void EndUpdate(bool slowRefresh)
- {
- if (mNode.mEnableAOI)
- {
- LookOutRange(slowRefresh);
-
- // 一直同步周围单位
- SyncPosEvent mSyncPosLocal = GetSyncPosEvent();
- if (mSyncPosLocal != null && !mSyncPosLocal.IsEmpty)
- {
- mClient.Send(mSyncPosLocal);
- }
- }
- OnEndUpdate();
- }
- /// <summary>
- /// 排队发送消息
- /// </summary>
- /// <param name="msg"></param>
- /// <param name="immediately"></param>
- public void Send(IMessage msg, bool immediately = false)
- {
- if (mNode.mEnableAOI)
- {
- if (immediately)
- {
- this.mClient.Send(msg);
- }
- else if (msg is AddSpellEvent)
- {
- OnLookSpell(msg as AddSpellEvent);
- }
- else
- {
- msg = mNode.FilterSendingMessage(this, msg);
- if (msg != null)
- {
- this.mClient.Send(msg);
- }
- }
- }
- else
- {
- this.mClient.Send(msg);
- }
- }
- /// <summary>
- /// 从客户端接收消息
- /// </summary>
- /// <param name="message"></param>
- private void RecvInternal(object message)
- {
- if (message is Ping)
- {
- var ping = message as Ping;
- mSendPong.ClientTimeDayOfMS = ping.DayOfMS;
- mClient.Send(mSendPong);
- return;
- }
- else
- {
- //mNode.QueueTask(() =>
- //{
- if (mActor.Enable)
- {
- ObjectAction oa = message as ObjectAction;
- if (oa != null)
- {
- //BaseZoneNode.log.Debug("C2B msg<<<" + oa);
- oa.object_id = mActor.ID;
- oa.sender = mActor;
- if (oa is ActorRequest)
- {
- mActor.doRequest(oa as ActorRequest);
- }
- else
- {
- mZone.pushAction(oa);
- }
- }
- }
- //});
- }
- }
- //------------------------------------------------------------------------------------------------------------
- //------------------------------------------------------------------------------------------------------------
- #region _AOI_视野控制_
- /// <summary>
- /// 获取当前场景内所有单位,用于同步现有场景中单位
- /// </summary>
- /// <returns></returns>
- public SyncObjectsEvent GetSyncObjectsEvent()
- {
- if (mNode.mEnableAOI)
- {
- return mZone.GetSyncObjectsEvent(mInViewList.Values);
- }
- else
- {
- return mZone.GetSyncUnitsEvent(mActor);
- }
- }
- public bool IsInView(InstanceZoneObject obj)
- {
- if (mNode.mEnableAOI)
- return mInViewList.ContainsKey(obj.ID);
- else
- return true;
- }
- public bool IsInView(uint id)
- {
- if (mNode.mEnableAOI)
- return mInViewList.ContainsKey(id);
- else
- return true;
- }
- public bool IsLookInRange(float x, float y)
- {
- if (mNode.mEnableAOI)
- return CMath.includeRoundPoint(mActor.X, mActor.Y, mSyncObjectInRange, x, y);
- else
- return true;
- }
- public SyncPosEvent GetSyncPosEvent()
- {
- return mZone.GetSyncPosEvent(mInViewList.Values, this.Actor, this);
- }
- /// <summary>
- /// 判断单位是否进入视野
- /// </summary>
- /// <param name="obj"></param>
- /// <returns>True,进入视野</returns>
- protected virtual bool IsLookInRange(InstanceZoneObject obj)
- {
- return CMath.includeRoundPoint(mActor.X, mActor.Y, mSyncObjectInRange, obj.X, obj.Y);
- }
- /// <summary>
- /// 判断单位是否超出视野
- /// </summary>
- /// <param name="obj"></param>
- /// <returns>True,超出视野</returns>
- protected virtual bool IsLookOutRange(InstanceZoneObject obj)
- {
- return !CMath.includeRoundPoint(mActor.GetX(), mActor.GetY(), mSyncObjectOutRange, obj.GetX(), obj.GetY());
- }
- protected void ForceAddObjectInView(InstanceZoneObject obj)
- {
- if (!mInViewList.ContainsKey(obj.ID))
- {
- mInViewList.Put(obj.ID, obj);
- OnEnterView(obj);
- }
- }
- private void LookInRange()
- {
- mZone.ForEachNearObjects<InstanceZoneObject>(mActor.X, mActor.Y, mSyncObjectInRange, mZone_CheckInRange);
- }
- private void mZone_CheckInRange(InstanceZoneObject o, ref bool cancel)
- {
- if ((o != mActor) && o.ClientVisible && !(o is InstanceSpell) && !mInViewList.ContainsKey(o.ID))
- {
- if (o.Enable && mZone.IsVisibleAOI(mActor, o) && IsLookInRange(o))
- {
- mInViewList.Put(o.ID, o);
- OnEnterView(o);
- }
- }
- }
- private void LookOutRange(bool slowRefresh)
- {
- foreach (InstanceZoneObject o in mInViewList.Values)
- {
- if (o == mActor)
- {
- continue;
- }
- if (!o.Enable || (slowRefresh && (!mZone.IsVisibleAOI(mActor, o) || IsLookOutRange(o))))
- {
- m_RemovingList.Add(o.ID);
- OnLeaveView(o);
- }
- }
- if (m_RemovingList.Count > 0)
- {
- foreach (uint oid in m_RemovingList)
- {
- mInViewList.Remove(oid);
- }
- m_RemovingList.Clear();
- }
- }
- public virtual bool RemoveInRange(InstanceZoneObject o) { return false; }
- protected virtual void OnLookSpell(AddSpellEvent em)
- {
- // 过滤不在自己感兴趣范围内的消息
- if (em.sender is InstanceSpell)
- {
- var sp = em.sender as InstanceSpell;
- //作用于自己或者自己发射的//
- if (sp.Launcher == mActor || sp.Target == mActor)
- {
- mInViewList.Put(sp.ID, sp);
- mClient.Send(em);
- return;
- }
- if (mZone.IsVisibleAOI(mActor, sp))
- {
- if (IsLookInRange(em.x, em.y))
- {
- mInViewList.Put(sp.ID, sp);
- mClient.Send(em);
- return;
- }
- }
- log.Debug($"Ignore spell to client: {em.spell_template_id}");
- }
- }
- protected virtual void OnEnterView(InstanceZoneObject obj)
- {
- if (obj is InstanceUnit)
- {
- InstanceUnit u = obj as InstanceUnit;
- var sync = u.GenSyncUnitInfo(true);
- var add = new AddUnitEvent(sync);
- mClient.Send(add);
- if(u.Info.SpawnEffect != null && u.CurrentActionStatus == UnitActionStatus.Spawn)
- {
- u.Parent.queueEvent(new AddEffectEvent(u.ID, u.X, u.Y, u.Direction, u.Info.SpawnEffect));
- }
- }
- else if (obj is InstanceItem)
- {
- InstanceItem i = obj as InstanceItem;
- var sync = i.GenSyncItemInfo(true, this.PlayerUUID);
- var add = new AddItemEvent(sync);
- mClient.Send(add);
- }
- }
- protected virtual void OnLeaveView(InstanceZoneObject obj)
- {
- RemoveObjectEvent remove = new RemoveObjectEvent(obj.ID);
- mClient.Send(remove);
- }
- public void ForEachInViewList(Action<InstanceZoneObject> action)
- {
- using (var list = ListObjectPool<InstanceZoneObject>.AllocAutoRelease(mInViewList.Values))
- {
- foreach (var obj in list) { action(obj); }
- }
- }
- #endregion
- //------------------------------------------------------------------------------------------------------------
- // private OnObjectEnterViewHandler event_OnObjectEnterView;
- // private OnObjectLeaveViewHandler event_OnObjectLeaveView;
- // public delegate void OnObjectEnterViewHandler(PlayerClient sender, InstanceZoneObject obj);
- // public delegate void OnObjectLeaveViewHandler(PlayerClient sender, InstanceZoneObject obj);
- // public event OnObjectEnterViewHandler OnObjectEnterView { add { event_OnObjectEnterView += value; } remove { event_OnObjectEnterView -= value; } }
- // public event OnObjectLeaveViewHandler OnObjectLeaveView { add { event_OnObjectLeaveView += value; } remove { event_OnObjectLeaveView -= value; } }
- }
- private class PlayerClientMap
- {
- private HashMap<string, InstancePlayer> mPlayerObjectMap = new HashMap<string, InstancePlayer>();
- private HashMap<string, PlayerClient> mPlayerClientMap = new HashMap<string, PlayerClient>();
- public int Count
- {
- get
- {
- lock (this)
- {
- return mPlayerClientMap.Count;
- }
- }
- }
- public InstancePlayer[] Players
- {
- get
- {
- lock (this)
- {
- return mPlayerObjectMap.Values.ToArray();
- }
- }
- }
- public void PutPlayer(PlayerClient client)
- {
- lock (this)
- {
- mPlayerObjectMap.Put(client.PlayerUUID, client.Actor);
- mPlayerClientMap.Put(client.PlayerUUID, client);
- }
- }
- public InstancePlayer GetPlayer(string uuid)
- {
- lock (this)
- {
- return mPlayerObjectMap.Get(uuid);
- }
- }
- public PlayerClient GetClient(string uuid)
- {
- lock (this)
- {
- return mPlayerClientMap.Get(uuid);
- }
- }
- public bool Get(string uuid, out InstancePlayer player, out PlayerClient client)
- {
- lock (this)
- {
- player = mPlayerObjectMap.Get(uuid);
- client = mPlayerClientMap.Get(uuid);
- }
- return client != null;
- }
- public bool RemoveByKey(string uuid, out InstancePlayer player, out PlayerClient client)
- {
- lock (this)
- {
- player = mPlayerObjectMap.RemoveByKey(uuid);
- client = mPlayerClientMap.RemoveByKey(uuid);
- }
- return client != null;
- }
- public bool ContainsKey(string uuid)
- {
- lock (this)
- {
- return mPlayerObjectMap.ContainsKey(uuid);
- }
- }
- public void ForEachPlayers(Action<PlayerClient> action)
- {
- lock (this)
- {
- foreach (PlayerClient c in mPlayerClientMap.Values)
- {
- action(c);
- }
- }
- }
- }
- //------------------------------------------------------------------------------------------------------------
- #endregion
- }
- }
|