AreaZoneNode.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. using DeepCore.GameData.Zone.ZoneEditor;
  2. using DeepCore.GameEvent;
  3. using DeepCore.IO;
  4. using DeepCore.Log;
  5. using DeepCrystal.RPC;
  6. using DeepMMO.Server.AreaManager;
  7. using System;
  8. using System.Threading.Tasks;
  9. using DeepCore.Game3D.Host.Instance;
  10. using DeepCore.Game3D.Host.ZoneEditor;
  11. using DeepCore.Game3D.Host.ZoneServer;
  12. using DeepCore.Game3D.Host.ZoneServer.Interface;
  13. using DeepCore.Geometry;
  14. using DeepMMO.Data;
  15. using DeepCore;
  16. using System.Text;
  17. using System.IO;
  18. namespace DeepMMO.Server.Area
  19. {
  20. public class AreaZoneNode : IZoneNodeServer
  21. {
  22. private readonly static TypeAllocRecorder Alloc = new TypeAllocRecorder(typeof(AreaZoneNode));
  23. protected readonly Logger log;
  24. protected readonly AreaService service;
  25. protected readonly CreateZoneNodeRequest create;
  26. protected readonly MapTemplateData map_temp;
  27. protected readonly string uuid;
  28. protected readonly ZoneNode node;
  29. public string ZoneUUID { get { return uuid; } }
  30. public int MapTemplateID { get { return create.mapTemplateID; } }
  31. public int ZoneTemplateID { get { return map_temp.zone_template_id; } }
  32. public string GuildUUID => create.guildUUID;
  33. public string RoomKey => create.roomKey;
  34. /// <summary>
  35. /// 场景保留时间,将超时时间从TLAreaZoneNode同步到AreaZoneNode,为了ZoneBaseEvent调用
  36. /// </summary>
  37. public DateTime KeepSceneExpireTime;
  38. //public string ServerID => create.serverID;
  39. public string ServerGroupID => create.serverGroupID;
  40. public ZoneNode ZoneNode { get { return node; } }
  41. public AreaZoneNode(AreaService svc, CreateZoneNodeRequest create, MapTemplateData map_temp)
  42. {
  43. Alloc.RecordConstructor(GetType().ToVisibleName() + ":" + map_temp.id);
  44. this.log = LoggerFactory.GetLogger(string.Format("{0}-{1}", GetType().Name, create.managerZoneUUID));
  45. this.service = svc;
  46. this.create = create;
  47. this.map_temp = map_temp;
  48. this.uuid = create.managerZoneUUID;
  49. this.node = CreateZoneNode(create);
  50. }
  51. #if DEBUG
  52. ~AreaZoneNode()
  53. {
  54. Alloc.RecordDestructor(GetType().ToVisibleName() + ":" + map_temp.id);
  55. }
  56. #endif
  57. public virtual void rpc_Handle(ISerializable msg, OnRpcReturn<ISerializable> cb)
  58. {
  59. zone_rpc_call_handler?.Invoke(msg, (rsp, err) => { cb(rsp as ISerializable, err); });
  60. }
  61. public virtual void rpc_Handle(ISerializable msg)
  62. {
  63. zone_rpc_invoke_handler?.Invoke(msg);
  64. }
  65. public virtual void rpc_Call(ISerializable msg, OnRpcReturn<ISerializable> cb)
  66. {
  67. }
  68. public virtual void rpc_Invoke(ISerializable msg)
  69. {
  70. }
  71. //--------------------------------------------------------------------------------------------------------------------------------
  72. #region 主动调用
  73. //--------------------------------------------------------------------------------------------------------------------------------
  74. public virtual async Task<EditorScene> DoStartAsync()
  75. {
  76. var sd = LoadSceneData(create);
  77. var zone = await this.node.StartAsync(sd) as EditorScene;
  78. zone.UUID = ZoneUUID;
  79. OnNodeStarted(zone as EditorScene);
  80. return zone;
  81. }
  82. public virtual Task<EditorScene> DoStopAsync()
  83. {
  84. Alloc.RecordDispose(GetType().ToVisibleName() + ":" + map_temp.id);
  85. node.OnZoneStop += (z) =>
  86. {
  87. OnNodeStopped(z as EditorScene);
  88. };
  89. return node.StopAsync().ContinueWith(t => t.Result as EditorScene);
  90. }
  91. public virtual async Task<RoleEnterZoneResponse> DoPlayerEnterAsync(AreaZonePlayer player, RoleEnterZoneRequest enter)
  92. {
  93. if (await player.OnEnterAsync() == false)
  94. {
  95. log.Error("Can Not Find Session Or Logic : " + enter.roleSessionName + " : " + enter.roleUUID);
  96. }
  97. try
  98. {
  99. player.SessionReconnect();
  100. var tcs = new System.Threading.Tasks.TaskCompletionSource<RoleEnterZoneResponse>();
  101. this.node.PlayerEnter(player, ToAddUnit(enter), client =>
  102. {
  103. if (HasAddPlayer == false)
  104. {
  105. HasAddPlayer = true;
  106. }
  107. client.Actor.SetAttribute(nameof(AreaZonePlayer.RoleSessionName), player.RoleSessionName);
  108. tcs.TrySetResult(new RoleEnterZoneResponse()
  109. {
  110. s2c_code = RoleEnterZoneResponse.CODE_OK,
  111. mapTemplateID = this.MapTemplateID,
  112. zoneUUID = this.ZoneUUID,
  113. zoneTemplateID = this.ZoneTemplateID,
  114. roleBattleData = enter.roleData,
  115. roleDisplayName = enter.roleDisplayName,
  116. roleUnitTemplateID = enter.roleUnitTemplateID,
  117. roleScenePos = new ZonePosition()
  118. {
  119. x = client.Actor.X,
  120. y = client.Actor.Y,
  121. z = client.Actor.Z
  122. },
  123. areaName = service.SelfAddress.ServiceName,
  124. areaNode = service.SelfAddress.ServiceNode,
  125. guildUUID = enter.guildUUID,
  126. });
  127. }, err =>
  128. {
  129. tcs.TrySetResult(new RoleEnterZoneResponse()
  130. {
  131. s2c_code = RoleEnterZoneResponse.CODE_ERROR,
  132. s2c_msg = err.Message,
  133. });
  134. });
  135. return await tcs.Task;
  136. }
  137. catch (Exception err)
  138. {
  139. log.Error(err);
  140. return (new RoleEnterZoneResponse()
  141. {
  142. s2c_code = RoleEnterZoneResponse.CODE_ERROR,
  143. s2c_msg = err.Message,
  144. });
  145. }
  146. }
  147. public virtual Task<RoleLeaveZoneResponse> DoPlayerLeaveAsync(AreaZonePlayer player, RoleLeaveZoneRequest leave)
  148. {
  149. var tcs = new System.Threading.Tasks.TaskCompletionSource<RoleLeaveZoneResponse>();
  150. this.node.PlayerLeave(player,
  151. (c) =>
  152. {
  153. tcs.TrySetResult(new RoleLeaveZoneResponse()
  154. {
  155. lastScenePos = new Data.ZonePosition()
  156. {
  157. x = c.Actor.X,
  158. y = c.Actor.Y,
  159. z = c.Actor.Z,
  160. },
  161. curHP = c.Actor.CurrentHP,
  162. curMP = c.Actor.CurrentMP,
  163. LeaveZoneSaveData = c.LastZoneSaveData,
  164. });
  165. },
  166. (e) =>
  167. {
  168. tcs.TrySetResult(new RoleLeaveZoneResponse()
  169. {
  170. s2c_code = RoleLeaveZoneResponse.CODE_ERROR,
  171. s2c_msg = e.Message,
  172. });
  173. });
  174. return tcs.Task;
  175. }
  176. public Task<GetRolePositionResponse> DoGetPlayerPosition(AreaZonePlayer player, GetRolePositionRequest req)
  177. {
  178. return node.QueuePlayerTaskAsync<GetRolePositionResponse>(player.RoleUUID, (instancePlayer) =>
  179. {
  180. return (new GetRolePositionResponse()
  181. {
  182. x = instancePlayer.X,
  183. y = instancePlayer.Y,
  184. z = instancePlayer.Z,
  185. s2c_code = GetRolePositionResponse.CODE_OK
  186. });
  187. });
  188. }
  189. public virtual void DoPlayerDisconnect(AreaZonePlayer player)
  190. {
  191. player.SessionDisconnect();
  192. this.node.PlayerDisconnect(player, (client) => { }, (err) => { });
  193. }
  194. public virtual void DoPlayerReconnect(AreaZonePlayer player)
  195. {
  196. player.SessionReconnect();
  197. this.node.PlayerReconnect(player, (client) => { }, (err) => { });
  198. }
  199. public virtual Task DoPlayerBeginLeaveAsync(AreaZonePlayer player)
  200. {
  201. player.SessionBeginLeave();
  202. return this.node.QueueSceneTaskAsync(z => { return 1; });
  203. }
  204. public virtual Task<RoleEnterZoneResponse> DoPlayerEnterReplace(AreaZonePlayer player, RoleEnterZoneRequest enter)
  205. {
  206. return node.QueuePlayerTaskAsync<RoleEnterZoneResponse>(player.RoleUUID, (instancePlayer) =>
  207. {
  208. if (instancePlayer == null)
  209. {
  210. return new RoleEnterZoneResponse() { s2c_code = RoleEnterZoneResponse.CODE_ERROR };
  211. }
  212. return (new RoleEnterZoneResponse()
  213. {
  214. mapTemplateID = this.MapTemplateID,
  215. zoneUUID = this.ZoneUUID,
  216. zoneTemplateID = this.ZoneTemplateID,
  217. roleBattleData = enter.roleData,
  218. roleDisplayName = enter.roleDisplayName,
  219. roleUnitTemplateID = enter.roleUnitTemplateID,
  220. roleScenePos = new ZonePosition()
  221. {
  222. x = instancePlayer.X,
  223. y = instancePlayer.Y,
  224. z = instancePlayer.Z
  225. },
  226. areaName = service.SelfAddress.ServiceName,
  227. areaNode = service.SelfAddress.ServiceNode,
  228. guildUUID = enter.guildUUID,
  229. s2c_code = RoleEnterZoneResponse.CODE_OK_REPLACE
  230. });
  231. });
  232. // var client = this.node.GetPlayerClient(player.RoleUUID);
  233. /*
  234. float px = 0, py = 0, pz = 0;
  235. if (client != null)
  236. {
  237. px = client.Actor.X;
  238. py = client.Actor.Y;
  239. pz = client.Actor.Z;
  240. }
  241. return (new RoleEnterZoneResponse()
  242. {
  243. mapTemplateID = this.MapTemplateID,
  244. zoneUUID = this.ZoneUUID,
  245. zoneTemplateID = this.ZoneTemplateID,
  246. roleBattleData = enter.roleData,
  247. roleDisplayName = enter.roleDisplayName,
  248. roleUnitTemplateID = enter.roleUnitTemplateID,
  249. roleScenePos = new ZonePosition() { x = px, y = py, z = pz},
  250. areaName = service.SelfAddress.ServiceName,
  251. areaNode = service.SelfAddress.ServiceNode,
  252. guildUUID = enter.guildUUID,
  253. s2c_code = RoleEnterZoneResponse.CODE_OK_REPLACE;
  254. });
  255. */
  256. }
  257. #endregion
  258. //--------------------------------------------------------------------------------------------------------------------------------
  259. #region 构造对象
  260. //--------------------------------------------------------------------------------------------------------------------------------
  261. protected virtual AddUnit ToAddUnit(RoleEnterZoneRequest enter)
  262. {
  263. var unitInfo = RPGServerBattleManager.DataRoot.Templates.GetUnit(enter.roleUnitTemplateID);
  264. if (unitInfo == null)
  265. {
  266. unitInfo = service.GetDefaultUnitTemplate();
  267. }
  268. DeepCore.Vector.Vector3 pos = null;
  269. if (enter.roleScenePos != null)
  270. {
  271. if (enter.roleScenePos.HasFlag)
  272. {
  273. var sceneObj = node.FindSceneObjData(enter.roleScenePos.flagName);
  274. if (sceneObj != null)
  275. {
  276. pos = new DeepCore.Vector.Vector3(sceneObj.X, sceneObj.Y, sceneObj.Z);
  277. }
  278. }
  279. else if (enter.roleScenePos.HasPos)
  280. {
  281. if (enter.roleScenePos.x == enter.roleScenePos.y && enter.roleScenePos.x == -1)
  282. {
  283. var map = node.SceneData.GetStartRegions();
  284. var ret = map.Get(2);
  285. if (ret != null)
  286. pos = new DeepCore.Vector.Vector3(ret.X, ret.Y, ret.Z);
  287. else
  288. pos = new DeepCore.Vector.Vector3(enter.roleScenePos.x, enter.roleScenePos.y, enter.roleScenePos.z);
  289. }
  290. else
  291. pos = new DeepCore.Vector.Vector3(enter.roleScenePos.x, enter.roleScenePos.y, enter.roleScenePos.z);
  292. }
  293. }
  294. var add = new AddUnit()
  295. {
  296. info = unitInfo,
  297. player_uuid = enter.roleUUID,
  298. pos = pos,
  299. arg = enter,
  300. //中立单位0,怪物1,玩家2.
  301. force = enter.roleForce > 0 ? (byte)enter.roleForce : (byte)2,
  302. editor_name = enter.roleDisplayName,
  303. last_zone_save_data = enter.LastZoneSaveData,
  304. };
  305. return add;
  306. }
  307. protected virtual SceneData LoadSceneData(CreateZoneNodeRequest input)
  308. {
  309. return RPGServerBattleManager.Instance.GetSceneAsCache(this.ZoneTemplateID);
  310. }
  311. protected virtual ZoneNode CreateZoneNode(CreateZoneNodeRequest input)
  312. {
  313. return RPGServerBattleManager.ZoneFactory.CreateServerZoneNode(this, RPGServerBattleManager.DataRoot, RPGServerBattleManager.NodeConfig);
  314. }
  315. #endregion
  316. //--------------------------------------------------------------------------------------------------------------------------------
  317. #region 回调事件
  318. //--------------------------------------------------------------------------------------------------------------------------------
  319. public EventManager EventMgr { get; private set; }
  320. protected virtual void OnNodeStarted(EditorScene z)
  321. {
  322. z.OnUnitDead += Z_OnUnitDead;
  323. z.OnUnitGotInstanceItem += Z_OnUnitGotInstanceItem;
  324. z.OnGameOver += Z_OnGameOver;
  325. //z.OnCurrentSecretPlacePlayTypeUpdateAction += Z_OnCurrentSecretPlacePlayTypeUpdate;
  326. if (TimerConfig.timer_sec_ZoneKeepPlayerTimeout > 0)//场景无人后清理时间.程序控制.
  327. {
  328. keepPlayerExpire = TimeSpan.FromSeconds(TimerConfig.timer_sec_ZoneKeepPlayerTimeout);
  329. z.AddTimePeriodicMS((int)(keepPlayerExpire.TotalMilliseconds / 2), (t) =>
  330. {
  331. CheckZoneDispose(z, t);
  332. });
  333. }
  334. this.EventMgr = EventManagerFactory.Instance.CreateEventManager("Zone", z.UUID);
  335. if (this.EventMgr != null)
  336. {
  337. this.EventMgr.PutObject("Zone", z);
  338. this.EventMgr.PutObject("Service", this.service);
  339. this.EventMgr.PutObject("Node", this);
  340. this.EventMgr.Start();
  341. node.OnZoneBeginUpdate += zone =>
  342. {
  343. this.EventMgr.EnterUpdate();
  344. };
  345. node.OnZoneEndUpdate += zone =>
  346. {
  347. this.EventMgr.Update();
  348. };
  349. }
  350. }
  351. protected virtual void OnNodeStopped(EditorScene z)
  352. {
  353. this.zone_rpc_call_handler = null;
  354. this.zone_rpc_invoke_handler = null;
  355. z.OnUnitDead -= Z_OnUnitDead;
  356. z.OnUnitGotInstanceItem -= Z_OnUnitGotInstanceItem;
  357. z.OnGameOver -= Z_OnGameOver;
  358. //z.OnCurrentSecretPlacePlayTypeUpdateAction -= Z_OnCurrentSecretPlacePlayTypeUpdate;
  359. this.EventMgr?.Dispose();
  360. this.EventMgr = null;
  361. }
  362. //--------------------------------------------------------------------------------------------------------------------------------
  363. public virtual void GetStatus(TextWriter sb)
  364. {
  365. sb.WriteLine(" UUID = " + this.uuid);
  366. sb.WriteLine(" SceneData = " + this.node.SceneData);
  367. sb.WriteLine(" PlayerCount = " + this.node.PlayerCount);
  368. //sb.WriteLine(" ExpireTime = " + this.mExpireTimeUTC.ToLocalTime());
  369. sb.WriteLine(" IsGameOver = " + zoneGameOver);
  370. sb.WriteLine(" HasAddPlayer = " + HasAddPlayer);
  371. sb.WriteLine(" PassTime = " + node.ZonePassTime);
  372. }
  373. private DateTime keepPlayerLastTick = DateTime.Now;
  374. private TimeSpan keepPlayerExpire;
  375. private bool zoneGameOver = false;
  376. //private DateTime mExpireTimeUTC = DateTime.UtcNow;
  377. private bool HasAddPlayer = false;// player already in zone
  378. // public void SetSceneExpireTime(DateTime time)
  379. // {
  380. // mExpireTimeUTC = time.ToUniversalTime();
  381. // }
  382. // private bool IsExpire()
  383. // {
  384. // return (DateTime.UtcNow - mExpireTimeUTC).TotalSeconds > 0;
  385. // }
  386. /// <summary>
  387. /// 检测是否需要维持场景,否则,则销毁场景
  388. /// </summary>
  389. /// <returns></returns>
  390. protected virtual bool CheckNeedKeepPlayer(EditorScene z)
  391. {
  392. if (node.PlayerCount > 0) return true;
  393. if (zoneGameOver) return false;
  394. if (HasAddPlayer == false) return true;
  395. // if (!IsExpire()) return true;
  396. return false;
  397. }
  398. protected virtual void CheckZoneDispose(EditorScene z, TimeTaskMS t)
  399. {
  400. if (CheckNeedKeepPlayer(z))
  401. {
  402. zoneGameOver = false;
  403. keepPlayerLastTick = DateTime.Now;
  404. }
  405. else if ((DateTime.Now - keepPlayerLastTick) > keepPlayerExpire)
  406. {
  407. if (!zoneGameOver)
  408. {
  409. zoneGameOver = true;
  410. //notify areamanager close zone.
  411. service.area_manager.Invoke(new AreaZoneGameOverNotify()
  412. {
  413. zoneUUID = this.ZoneUUID,
  414. reason = "KeepPlayerTimeOver",
  415. });
  416. }
  417. t.Dispose();
  418. //start delay desotry.
  419. var delayDestoryTime = TimeSpan.FromSeconds(TimerConfig.timer_sec_DelayDestoryTime);
  420. // if (delayDestoryTime > TimeSpan.Zero)
  421. {
  422. //log.Info("ZoneNode Start Delay Destory : " + delayDestoryTime + " " + this.ZoneUUID);
  423. var evt = new DeepCore.GameData.Zone.GameOverEvent() { WinForce = 0, message = "KeepPlayerTimeOver" };
  424. service.Provider.Delay((st) =>
  425. {
  426. if (node.IsDisposed) { return; }
  427. //log.Info("ZoneNode Send AreaZoneDestoryNotify ZoneUUID : " + this.ZoneUUID);
  428. NotifyAllLogicsGameOver(evt);
  429. service.area_manager.Invoke(new AreaZoneDestoryNotify()
  430. {
  431. zoneUUID = this.ZoneUUID,
  432. reason = evt.message,
  433. });
  434. }, create, delayDestoryTime);
  435. }
  436. }
  437. }
  438. //--------------------------------------------------------------------------------------------------------------------------------
  439. protected virtual void Z_OnUnitDead(InstanceZone zone, InstanceUnit obj, InstanceUnit attacker)
  440. {
  441. if (attacker != null && obj != null)
  442. {
  443. if (obj.Info.UType == DeepCore.GameData.Zone.UnitInfo.UnitType.TYPE_MONSTER && attacker is InstancePlayer)
  444. {
  445. //玩家.
  446. var player = attacker as InstancePlayer;
  447. //生成奖励信息.
  448. var notify = GetRoleBattleAward(zone, obj, player);
  449. if (notify != null)
  450. {
  451. //通知游戏服.
  452. NotifyLogicRoleAward(player.PlayerUUID, notify);
  453. }
  454. }
  455. }
  456. }
  457. protected virtual void Z_OnCurrentSecretPlacePlayTypeUpdate(int updateType,int playID)
  458. {
  459. service.area_manager.Invoke(new CurrentSecretPlacePlayTypeUpdateNotify()
  460. {
  461. update = updateType,
  462. zoneUUID = this.ZoneUUID,
  463. playID = playID
  464. }); ;
  465. }
  466. //交给子类去实现
  467. protected virtual void Z_OnUnitGotInstanceItem(InstanceZone zone, InstanceUnit unit, InstanceItem item)
  468. {
  469. //TODO
  470. }
  471. protected virtual void Z_OnGameOver(InstanceZone zone, DeepCore.GameData.Zone.GameOverEvent evt)
  472. {
  473. zoneGameOver = true;
  474. //log.Info("ZoneNode GameOver : " + evt.message + " " + this.ZoneUUID);
  475. //notify logic.
  476. NotifyAllLogicsGameOver(evt);
  477. //notify areamanager close zone.
  478. service.area_manager.Invoke(new AreaZoneGameOverNotify()
  479. {
  480. zoneUUID = this.ZoneUUID,
  481. reason = evt.message,
  482. });
  483. }
  484. /// <summary>
  485. /// 通知逻辑服,场景结束
  486. /// </summary>
  487. /// <param name="evt"></param>
  488. protected virtual void NotifyAllLogicsGameOver(DeepCore.GameData.Zone.GameOverEvent evt)
  489. {
  490. node.ForEachPlayers((p) =>
  491. {
  492. var player = p.Client as AreaZonePlayer;
  493. player.DoGameOver(evt);
  494. });
  495. }
  496. /// <summary>
  497. /// 通知客户端,场景即将结束
  498. /// </summary>
  499. protected virtual void NotifyAllSessionsGameOver(TimeSpan delayTime)
  500. {
  501. //TODO 客户端显示倒计时
  502. //node.ForEachPlayers((p) =>
  503. //{
  504. // var player = p.Client as AreaZonePlayer;
  505. // player.SendToSession(null);
  506. //});
  507. }
  508. /// <summary>
  509. /// 向游戏服logic发送奖励信息.
  510. /// </summary>
  511. /// <param name="uuid"></param>
  512. /// <param name="notify"></param>
  513. protected virtual void NotifyLogicRoleAward(string uuid, RoleBattleAwardNotify notify)
  514. {
  515. var logic = service.GetPlayer(uuid);
  516. if (logic != null)
  517. {
  518. logic.logic_rpc_Invoke(notify);
  519. }
  520. }
  521. /// <summary>
  522. /// 生成奖励.
  523. /// </summary>
  524. /// <param name="zone"></param>
  525. /// <param name="obj"></param>
  526. /// <param name="attacker"></param>
  527. /// <returns></returns>
  528. protected virtual RoleBattleAwardNotify GetRoleBattleAward(InstanceZone zone, InstanceUnit obj, InstancePlayer attacker)
  529. {
  530. RoleBattleAwardNotify ret = new RoleBattleAwardNotify();
  531. ret.MonsterID = obj.Info.ID;
  532. ret.RoleID = attacker.PlayerUUID;
  533. return ret;
  534. }
  535. #endregion
  536. //--------------------------------------------------------------------------------------------------------------------------------
  537. #region IServer
  538. private Action<object, Action<object, Exception>> zone_rpc_call_handler;
  539. private Action<object> zone_rpc_invoke_handler;
  540. void IZoneNodeServer.GameServerRpcInvoke(object msg)
  541. {
  542. this.rpc_Invoke(msg as ISerializable);
  543. }
  544. void IZoneNodeServer.GameServerRpcCall(object msg, Action<object, Exception> callback)
  545. {
  546. this.rpc_Call(msg as ISerializable, (rsp, err) => { callback(rsp, err); });
  547. }
  548. void IZoneNodeServer.ListenGameServerRpcInvoke(Action<object> handler)
  549. {
  550. this.zone_rpc_invoke_handler = handler;
  551. }
  552. void IZoneNodeServer.ListenGameServerRpcCall(Action<object, Action<object, Exception>> handler)
  553. {
  554. this.zone_rpc_call_handler = handler;
  555. }
  556. #endregion
  557. }
  558. }