Advertisement
Guest User

Untitled

a guest
Mar 5th, 2014
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 57.42 KB | None | 0 0
  1.  
  2. /*
  3. * DAWN OF LIGHT - The first free open source DAoC server emulator
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License
  7. * as published by the Free Software Foundation; either version 2
  8. * of the License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. *
  19. */
  20. /*
  21. * Created by VaNaTiC@gmx.net
  22. * for Thidranki Classic (http://www.thidrankiclassic.de)
  23. *
  24. * Some notes:
  25. * - ...
  26. *
  27. * Features:
  28. * - ...
  29. *
  30. * ChangeLog:
  31. * 2007-06-27, Sio:
  32. * - PvP-Zone -> Albion SI (RegionID: 51)
  33. * - Safe-Zone -> Mid SI Aegir (new SetupZone, RegionID: 151)
  34. * 2007-06-12, VaNaTiC:
  35. * - PvP-Zone -> Celestius (Stars ML10 Spot RegionID: 91)
  36. * - PvE-Zone -> Passage of Conflict (RegionID: 244)
  37. * - PvE-Zone -> Darkness Falls (RegionID: 249)
  38. * - added changes from PvPServerRules.IsSameRealm() Rev 676
  39. * 2007-06-08, VaNaTiC:
  40. * - added colorhandling on GameEntered
  41. * - added LevelUpSound to RegionChanged and GamEntered to update NPCs color
  42. * 2007-06-04, VaNaTiC:
  43. * - added changes from PvPServerRules.IsSameRealm() Rev 664
  44. * - added changes from AbstractServerRules.IsAllowedToAttack() Rev 664
  45. * 2007-06-02, VaNaTiC:
  46. * - added check for xrealm+disband in event PlayerRegionChanged
  47. * - IsAllowedToCastSpell(): added complete handling PvE, PvP, RvR and SafeZones
  48. * - IsAllowedToUnderstand(): added complete handling PvE, PvP, RvR and SafeZones
  49. * - IsAllowedToTrade(): added complete handling PvE, PvP, RvR and SafeZones
  50. * - IsAllowedToGroup(): added complete handling PvE, PvP, RvR and SafeZones
  51. * - IsSameRealm(): added complete handling PvE, PvP, RvR and SafeZones
  52. * - IsAllowedToAttack(): added complete handling PvE, PvP, RvR and SafeZones
  53. * - added handling PvE-Zones
  54. * 2007-06-01, VaNaTiC:
  55. * - added preparing for PvE-zones
  56. * 2007-05-31, VaNaTiC:
  57. * - renamed ThidrankiClassicServerRules -> TCServerRules
  58. * - added PvE (safe-zone), PvP(pvp-zone) name-coloring and name-handling
  59. * - added m_pvpRegions and related code
  60. * - changed m_safeRegions from int[] to ushort[] and edited related m_safeRegions-Code
  61. * 2007-05-29, VaNaTiC:
  62. * - added PvE name/lastname/guild-handling in safe-zones
  63. * - added experimental PvE color-handling in safe-zones
  64. * 2007-05-22, VaNaTiC:
  65. * - allowed trading for all realms in safe-zones (setup-zone)
  66. * - allowed broadcast for all realms in safe-zones (setup-zone)
  67. * 2007-05-14, Lordy:
  68. * - added configuration Values: CLAIM_STATUS, CLAIM_BONUS, CLAIM_Logging
  69. * - added GuildClaimBonus(int RP, int BP, GamePlayer pl) method Line
  70. * - added in onplayerkilled() line 572 GuildClaimBonus() call
  71. * 2007-04-24, VaNaTiC:
  72. * - OnPlayerKilled(): fixed some things in LOGGING-Section
  73. * 2007-04-19, VaNaTiC:
  74. * - OnPlayerKilled(): fixed bug in handling XPGainers
  75. * - OnPlayerKilled(): added Logging
  76. * - OnPlayerKilled(): recalc for values with percent-based rate
  77. * - OnPlayerKilled(): counting of Friends/Enemies based upon XPGainers
  78. * - OnPlayerKilled(): consts for better configurability
  79. * - OnPlayerKilled(): dont count GMs to Friends/Enemies anymore
  80. * 2007-04-18, VaNaTiC:
  81. * - overridden IsAllowedToConnect() for vip-access
  82. * - added vip-access based upon account.Mail
  83. * - overridden IsAllowedToAttack() for safezones
  84. * - added safezones based upon PvP-RuleSet, as it was implemented in our old AbstractServerRules.cs
  85. * 2007-04-17, VaNaTiC:
  86. * - added in my OnPlayerKilled() handling for both grps
  87. * - handled in my OnPlayerKilled() mali for zergers :D
  88. * - added copy of NormalServerRules.OnPlayerKilled()
  89. * - created ( copy&paste&edit of NormalServerRules :-D )
  90. */
  91. using System;
  92. using System.Net;
  93. using System.Text;
  94. using System.Reflection;
  95. using System.Collections;
  96.  
  97.  
  98.  
  99. using DOL.Database;
  100. using DOL.AI.Brain;
  101. using DOL.Events;
  102. using DOL.Language;
  103. using DOL.GS;
  104. using DOL.GS.Keeps;
  105. using DOL.GS.Scripts;
  106. using DOL.GS.ServerRules;
  107. using DOL.GS.PacketHandler;
  108. using DOL.GS.ServerProperties;
  109.  
  110. using log4net;
  111. using System.Collections.Generic;
  112.  
  113. namespace DOL.GS.ServerRules
  114. {
  115. /// <summary>
  116. /// Set of rules for ThidrankiClassic "RvR" server type.
  117. /// </summary>
  118. [ServerRules(eGameServerType.GST_Test)]
  119. public class TCServerRules : NormalServerRules
  120. {
  121. #region configuration flags
  122. /// <summary>
  123. /// if it is 0.75 it means that only 75% of the whole RP-worth is recalculated
  124. /// </summary>
  125. public readonly double CALC_RATE = 0.75;
  126. /// <summary>
  127. /// if ENEMIES (Killer and Friends) > FRIENDS (Dead Player and Friends)
  128. /// and this property is true then the ENEMIES get a penalty
  129. /// </summary>
  130. public readonly bool CALC_PENALTY = true;
  131. /// <summary>
  132. /// if ENEMIES (Killer and Friends) < FRIENDS (Dead Player and Friends)
  133. /// and this property is true then the ENEMIES get a bonus
  134. /// </summary>
  135. public readonly bool CALC_BONUS = false;
  136. /// <summary>
  137. /// Enable/Disable Logging in GameServer-Logs as [INFO]
  138. /// </summary>
  139. public readonly bool LOGGING = false;
  140. /// <summary>
  141. /// If set true, the Player get a RP/BP bonus if The Guild Claim the Keep/Tower.
  142. /// </summary>
  143. public readonly bool CLAIM_STATUS = true;
  144. /// <summary>
  145. /// The % Value the player will get RPs/BPs to the Normal Amount.
  146. /// </summary>
  147. public readonly double CLAIM_BONUS = 0.10;
  148. /// <summary>
  149. /// ClaimBonus Logging
  150. /// Enable/Disable Logging in GameServer-Logs as [INFO]
  151. /// </summary>
  152. public readonly bool CLAIM_LOGGING = false;
  153.  
  154. #endregion
  155.  
  156. /// <summary>
  157. /// Defines a logger for this class.
  158. /// </summary>
  159. private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  160.  
  161. public override string RulesDescription()
  162. {
  163. return "ThidrankiClassic RvR Server Rules Fair-Play-System";
  164. }
  165.  
  166. #region configuration here your safe/pvp-regions for setup/event-zone
  167.  
  168. /// <summary>
  169. /// our declared safe-zones (based upon PvP-RuleSet)
  170. /// </summary>
  171. protected static int[] m_safeRegions =
  172. {
  173. 335, //Setup
  174. };
  175.  
  176. #endregion
  177.  
  178. #region functions and handling for safe/pvp-regions
  179.  
  180. /// <summary>
  181. /// returns true if the given region is a safe-zone
  182. /// </summary>
  183. /// <param name="regionId"></param>
  184. /// <returns></returns>
  185. public static bool IsSafeZone(int regionId)
  186. {
  187. if (m_safeRegions != null && m_safeRegions.Length > 0)
  188. foreach (int reg in m_safeRegions)
  189. if (reg == regionId)
  190. return true;
  191. return false;
  192. }
  193.  
  194.  
  195.  
  196. #endregion
  197.  
  198. #region IsAllowedToAttack() merge of PvE, PvP, SafeZone and NormalRvR
  199.  
  200. /// <summary>
  201. /// AbstractServerRules: Is attacker allowed to attack defender.
  202. /// </summary>
  203. /// <param name="attacker">living that makes attack</param>
  204. /// <param name="defender">attacker's target</param>
  205. /// <param name="quiet">should messages be sent</param>
  206. /// <returns>true if attack is allowed</returns>
  207. protected virtual bool Abstract_IsAllowedToAttack(GameLiving attacker, GameLiving defender, bool quiet)
  208. {
  209. if (attacker == null || defender == null)
  210. return false;
  211.  
  212. //dead things can't attack
  213. if (!defender.IsAlive || !attacker.IsAlive)
  214. return false;
  215.  
  216. GamePlayer playerAttacker = attacker as GamePlayer;
  217. GamePlayer playerDefender = defender as GamePlayer;
  218.  
  219. if (playerDefender != null && playerDefender.Client.ClientState == GameClient.eClientState.WorldEnter)
  220. {
  221. if (!quiet)
  222. MessageToLiving(attacker, defender.Name + " is entering the game and is temporarily immune to PvP attacks!");
  223. return false;
  224. }
  225.  
  226. if (playerAttacker != null && playerDefender != null)
  227. {
  228. // Attacker immunity
  229. if (playerAttacker.IsInvulnerableToAttack)
  230. {
  231. if (quiet == false) MessageToLiving(attacker, "You can't attack players until your PvP invulnerability timer wears off!");
  232. return false;
  233. }
  234.  
  235. // Defender immunity
  236. if (playerDefender.IsInvulnerableToAttack)
  237. {
  238. if (quiet == false) MessageToLiving(attacker, defender.Name + " is temporarily immune to PvP attacks!");
  239. return false;
  240. }
  241. }
  242.  
  243. // PEACE NPCs can't be attacked/attack
  244. if (attacker is GameNPC)
  245. if ((((GameNPC)attacker).Flags & GameNPC.eFlags.PEACE) != 0)
  246. return false;
  247.  
  248. if (defender is GameNPC)
  249. if ((((GameNPC)defender).Flags & GameNPC.eFlags.PEACE) != 0)
  250. return false;
  251.  
  252. //GMs can't be attacked
  253. if (playerDefender != null && playerDefender.Client.Account.PrivLevel > 1)
  254. return false;
  255.  
  256. //safe area support for defender
  257. foreach (AbstractArea area in defender.CurrentAreas)
  258. {
  259. if (!area.IsSafeArea)
  260. continue;
  261.  
  262. if (quiet == false) MessageToLiving(attacker, "You can't attack someone in a safe area!");
  263. return false;
  264. }
  265.  
  266. //safe area support for attacker
  267. foreach (AbstractArea area in attacker.CurrentAreas)
  268. {
  269. if (area.IsSafeArea)
  270. {
  271. if (quiet == false) MessageToLiving(attacker, "You can't attack someone in a safe area!");
  272. return false;
  273. }
  274. }
  275.  
  276. //I don't want mobs attacking guards
  277. if (defender is GameKeepGuard && attacker is GameNPC && attacker.Realm == 0)
  278. return false;
  279.  
  280. return true;
  281. }
  282.  
  283.  
  284.  
  285.  
  286. /// <summary>
  287. /// Is attacker allowed to attack defender.
  288. /// ThidrankiClassic: PvE, PvP, RvR and SafeRegions in One for our SetupZone Caer Sidi
  289. /// </summary>
  290. /// <param name="attacker">living that makes attack</param>
  291. /// <param name="defender">attacker's target</param>
  292. /// <param name="quiet">should messages be sent</param>
  293. /// <returns>true if attack is allowed</returns>
  294. public override bool IsAllowedToAttack(GameLiving attacker, GameLiving defender, bool quiet)
  295. {
  296. if (attacker == null || defender == null)
  297. return false;
  298.  
  299.  
  300.  
  301. bool allowed = base.IsAllowedToAttack(attacker, defender, true);
  302. // ONLY check safe-zones if allowed from base
  303. if (allowed && TCServerRules.IsSafeZone(attacker.CurrentRegionID))
  304. {
  305. if (defender is GamePlayer
  306. && (attacker is GamePlayer || !(attacker is GameTrainingDummy)))
  307. {
  308. if (!quiet)
  309. MessageToLiving(attacker, "You're currently in a safe zone, you can't attack other players here.");
  310. return false;
  311. }
  312. }
  313. return allowed;
  314. }
  315.  
  316. #endregion
  317.  
  318. #region IsSameRealm merge for PvE, PvP, RvR and SafeRegions
  319.  
  320.  
  321.  
  322. /// <summary>
  323. /// Does source considers target "friendly".
  324. /// Used for spells with "Realm" and "Group" spell types, friend list.
  325. /// </summary>
  326. /// <param name="source">spell source, considering object</param>
  327. /// <param name="target">spell target, considered object</param>
  328. /// <param name="quiet"></param>
  329. /// <returns></returns>
  330.  
  331.  
  332. #endregion
  333.  
  334. #region IsAllowedToCastSpell() merge for PvE, PvP, RvR and SafeZones
  335.  
  336. /// <summary>
  337. /// Is caster allowed to cast a spell
  338. /// </summary>
  339. /// <param name="caster"></param>
  340. /// <param name="target"></param>
  341. /// <param name="spell"></param>
  342. /// <param name="spellLine"></param>
  343. /// <returns>true if allowed</returns>
  344. public override bool IsAllowedToCastSpell(GameLiving caster, GameLiving target, Spell spell, SpellLine spellLine)
  345. {
  346. if (!base.IsAllowedToCastSpell(caster, target, spell, spellLine))
  347. return false;
  348.  
  349. // if reached here, we have to know we are in pvp and check if allowed there
  350.  
  351. GamePlayer casterPlayer = caster as GamePlayer;
  352. if (casterPlayer != null)
  353. {
  354. if (casterPlayer.IsInvulnerableToAttack)
  355. {
  356. // always allow selftargeted spells
  357. if (spell.Target == "Self") return true;
  358.  
  359. // only caster can be the target, can't buff/heal other players
  360. // PBAE/GTAE doesn't need a target so we check spell type as well
  361. if (caster != target || spell.Target == "Area" || spell.Target == "Enemy" || (spell.Target == "Group" && spell.SpellType != "SpeedEnhancement"))
  362. {
  363. MessageToLiving(caster, "You can only cast spells on yourself until your PvP invulnerability timer wears off!", eChatType.CT_Important);
  364. return false;
  365. }
  366. }
  367.  
  368. }
  369. return true;
  370. }
  371.  
  372. #endregion
  373.  
  374. #region possible to grp mates from all realms in safe/pvp-zone (setup or pvp-regions)
  375.  
  376. /// <summary>
  377. /// Is source allowed to group target.
  378. /// </summary>
  379. /// <param name="source"></param>
  380. /// <param name="target"></param>
  381. /// <param name="quiet"></param>
  382. /// <returns></returns>
  383. public override bool IsAllowedToGroup(GamePlayer source, GamePlayer target, bool quiet)
  384. {
  385. bool allowed = base.IsAllowedToGroup(source, target, true);
  386. // ONLY check safe/pvp-zones if NOT allowed from base
  387. if (!allowed
  388. && source != null
  389. && target != null
  390. && source is GamePlayer
  391. && target is GamePlayer
  392. && source.Realm != target.Realm
  393. && source.CurrentRegionID == target.CurrentRegionID)
  394. {
  395. if (TCServerRules.IsSafeZone(target.CurrentRegionID))
  396. return true;
  397.  
  398. if (!quiet)
  399. MessageToLiving(source, "You can't invite a player of another realm.");
  400. return false;
  401. }
  402.  
  403. return allowed;
  404. }
  405.  
  406. #endregion
  407.  
  408. #region all realms can communicate in safe/pvp-zone (setup or pvp-regions)
  409.  
  410. /// <summary>
  411. /// Is target allowed to understand source.
  412. /// </summary>
  413. /// <param name="source"></param>
  414. /// <param name="target"></param>
  415. /// <returns></returns>
  416. public override bool IsAllowedToUnderstand(GameLiving source, GamePlayer target)
  417. {
  418. bool allowed = base.IsAllowedToUnderstand(source, target);
  419. // ONLY check safe/pvp-zones if NOT allowed from base
  420. if (!allowed
  421. && source != null
  422. && target != null
  423. && source is GamePlayer)
  424. if (TCServerRules.IsSafeZone(target.CurrentRegionID))
  425. return true;
  426. return allowed;
  427. }
  428.  
  429. #endregion
  430.  
  431. #region all realms can trade in safe/pvp-zone (setup or pvp-regions)
  432.  
  433. /// <summary>
  434. /// Is source allowed to trade with target.
  435. /// </summary>
  436. /// <param name="source"></param>
  437. /// <param name="target"></param>
  438. /// <param name="quiet"></param>
  439. /// <returns></returns>
  440. public override bool IsAllowedToTrade(GameLiving source, GameLiving target, bool quiet)
  441. {
  442. bool allowed = base.IsAllowedToTrade(source, target, true);
  443. // ONLY check safe/pvp-zones if NOT allowed from base
  444. if (!allowed
  445. && source != null
  446. && target != null
  447. && source is GamePlayer
  448. && target is GamePlayer
  449. && source.Realm != target.Realm
  450. && source.CurrentRegionID == target.CurrentRegionID)
  451. {
  452. if (TCServerRules.IsSafeZone(target.CurrentRegionID))
  453. return true;
  454.  
  455. if (!quiet)
  456. MessageToLiving(source, "You can't trade with enemy realm!");
  457. return false;
  458. }
  459.  
  460. return allowed;
  461. }
  462.  
  463. #endregion
  464.  
  465. #region PvE/PvP name- and color-handling in safe/pvp-zones
  466.  
  467. /// <summary>
  468. /// Gets the server type color handling scheme
  469. ///
  470. /// ColorHandling: this byte tells the client how to handle color for PC and NPC names (over the head)
  471. /// 0: standard way, other realm PC appear red, our realm NPC appear light green
  472. /// 1: standard PvP way, all PC appear red, all NPC appear with their level color
  473. /// 2: Same realm livings are friendly, other realm livings are enemy; nearest friend/enemy buttons work
  474. /// 3: standard PvE way, all PC friendly, realm 0 NPC enemy rest NPC appear light green
  475. /// 4: All NPC are enemy, all players are friendly; nearest friend button selects self, nearest enemy don't work at all
  476. /// </summary>
  477. /// <param name="client">The client asking for color handling</param>
  478. /// <returns>The color handling</returns>
  479. public override byte GetColorHandling(GameClient client)
  480. {
  481. if (client != null && client.Player != null)
  482. {
  483. if (TCServerRules.IsSafeZone(client.Player.CurrentRegionID))
  484. return 3;
  485.  
  486. }
  487. return base.GetColorHandling(client);
  488. }
  489.  
  490.  
  491.  
  492. /// <summary>
  493. /// Gets the player name based on server type and safe/pvp-zone
  494. /// </summary>
  495. /// <param name="source">The "looking" player</param>
  496. /// <param name="target">The considered player</param>
  497. /// <returns>The name of the target</returns>
  498. public override string GetPlayerName(GamePlayer source, GamePlayer target)
  499. {
  500. if (source != null
  501. && target != null
  502. && source is GamePlayer
  503. && target is GamePlayer
  504. && source.Realm != target.Realm
  505. && source.CurrentRegionID == target.CurrentRegionID)
  506. {
  507. if (TCServerRules.IsSafeZone(target.CurrentRegionID))
  508. return target.Name;
  509. }
  510. return base.GetPlayerName(source, target);
  511. }
  512.  
  513. /// <summary>
  514. /// Gets the player last name based on server type and safe/pvp-zone
  515. /// </summary>
  516. /// <param name="source">The "looking" player</param>
  517. /// <param name="target">The considered player</param>
  518. /// <returns>The last name of the target</returns>
  519. public override string GetPlayerLastName(GamePlayer source, GamePlayer target)
  520. {
  521. if (source != null
  522. && target != null
  523. && source is GamePlayer
  524. && target is GamePlayer
  525. && source.Realm != target.Realm
  526. && source.CurrentRegionID == target.CurrentRegionID)
  527. {
  528. if (TCServerRules.IsSafeZone(target.CurrentRegionID))
  529. return target.LastName;
  530. }
  531. return base.GetPlayerLastName(source, target);
  532. }
  533.  
  534. /// <summary>
  535. /// Gets the player guild name based on server type and safe/pvp-zone
  536. /// </summary>
  537. /// <param name="source">The "looking" player</param>
  538. /// <param name="target">The considered player</param>
  539. /// <returns>The guild name of the target</returns>
  540. public override string GetPlayerGuildName(GamePlayer source, GamePlayer target)
  541. {
  542. if (source != null
  543. && target != null
  544. && source is GamePlayer
  545. && target is GamePlayer
  546. && source.Realm != target.Realm
  547. && source.CurrentRegionID == target.CurrentRegionID)
  548. {
  549. if (TCServerRules.IsSafeZone(target.CurrentRegionID))
  550. return target.GuildName;
  551. }
  552. return base.GetPlayerGuildName(source, target);
  553. }
  554.  
  555. #endregion
  556.  
  557. #region vip-handling with account.Mail
  558.  
  559. /// <summary>
  560. /// Allows or denies a client from connecting to the server ...
  561. /// For ThidrankiClassic: Account.Mail != "" -> VIP
  562. /// NOTE: The client has not been fully initialized when this method is called.
  563. /// For example, no account or character data has been loaded yet.
  564. /// </summary>
  565. /// <param name="client">The client that sent the login request</param>
  566. /// <param name="username">The username of the client wanting to connect</param>
  567. /// <returns>true if connection allowed, false if connection should be terminated</returns>
  568. /// <remarks>You can only send ONE packet to the client and this is the
  569. /// LoginDenied packet before returning false. Trying to send any other packet
  570. /// might result in unexpected behaviour on server and client!</remarks>
  571. public override bool IsAllowedToConnect(GameClient client, string username)
  572. {
  573. if (!client.Socket.Connected)
  574. return false;
  575. string accip = ((IPEndPoint)client.Socket.RemoteEndPoint).Address.ToString();
  576.  
  577. // Ban account
  578. IList<DBBannedAccount> objs;
  579. //objs = GameServer.Database.SelectObjects<DBBannedAccount>("(Type ='Account' AND Account ='" + GameServer.Database.Escape(username) + "') OR (Type ='Account+Ip' AND Account ='" + GameServer.Database.Escape(username) + "')");
  580. objs = GameServer.Database.SelectObjects<DBBannedAccount>("((Type='A' OR Type='B') AND Account ='" + GameServer.Database.Escape(username) + "')");
  581. if (objs.Count > 0)
  582. {
  583. client.Out.SendLoginDenied(eLoginError.AccountIsBannedFromThisServerType);
  584. return false;
  585. }
  586.  
  587. // Ban IP Adress
  588. //objs = GameServer.Database.SelectObjects<DBBannedAccount>("(Type = 'Ip' AND Ip ='" + GameServer.Database.Escape(accip) + "') OR (Type ='Account+Ip' AND Ip ='" + GameServer.Database.Escape(accip) + "')");
  589. objs = GameServer.Database.SelectObjects<DBBannedAccount>("((Type='I' OR Type='B') AND Ip ='" + GameServer.Database.Escape(accip) + "')");
  590. if (objs.Count > 0)
  591. {
  592. client.Out.SendLoginDenied(eLoginError.AccountIsBannedFromThisServerType);
  593. return false;
  594. }
  595.  
  596. GameClient.eClientVersion min = (GameClient.eClientVersion)Properties.CLIENT_VERSION_MIN;
  597. if (min != GameClient.eClientVersion.VersionNotChecked && client.Version < min)
  598. {
  599. client.Out.SendLoginDenied(eLoginError.ClientVersionTooLow);
  600. return false;
  601. }
  602.  
  603. GameClient.eClientVersion max = (GameClient.eClientVersion)Properties.CLIENT_VERSION_MAX;
  604. if (max != GameClient.eClientVersion.VersionNotChecked && client.Version > max)
  605. {
  606. client.Out.SendLoginDenied(eLoginError.ClientVersionTooLow);
  607. return false;
  608. }
  609.  
  610. if (Properties.CLIENT_TYPE_MAX > -1)
  611. {
  612. GameClient.eClientType type = (GameClient.eClientType)Properties.CLIENT_TYPE_MAX;
  613. if ((int)client.ClientType > (int)type)
  614. {
  615. client.Out.SendLoginDenied(eLoginError.ExpansionPacketNotAllowed);
  616. return false;
  617. }
  618. }
  619.  
  620. /* Example to limit the connections from a certain IP range!
  621. if(client.Socket.RemoteEndPoint.ToString().StartsWith("192.168.0."))
  622. {
  623. client.Out.SendLoginDenied(eLoginError.AccountNoAccessAnyGame);
  624. return false;
  625. }
  626. */
  627.  
  628.  
  629. /* Example to deny new connections on saturdays
  630. if(DateTime.Now.DayOfWeek == DayOfWeek.Saturday)
  631. {
  632. client.Out.SendLoginDenied(eLoginError.GameCurrentlyClosed);
  633. return false;
  634. }
  635. */
  636.  
  637. /* Example to deny new connections between 10am and 12am
  638. if(DateTime.Now.Hour >= 10 && DateTime.Now.Hour <= 12)
  639. {
  640. client.Out.SendLoginDenied(eLoginError.GameCurrentlyClosed);
  641. return false;
  642. }
  643. */
  644.  
  645. IList<Account> accountobjs;
  646. if (Properties.MAX_PLAYERS > 0)
  647. {
  648. if (WorldMgr.GetAllClients().Count > Properties.MAX_PLAYERS)
  649. {
  650. // GMs are still allowed to enter server
  651. accountobjs = GameServer.Database.SelectObjects<Account>(string.Format("Name = '{0}'", GameServer.Database.Escape(username)));
  652. if (accountobjs.Count > 0)
  653. {
  654. Account account = accountobjs[0] as Account;
  655. if (account.PrivLevel > 1) return true;
  656. if (account.Mail != "") return true;
  657. }
  658.  
  659. // Normal Players will not be allowed over the max
  660. client.Out.SendLoginDenied(eLoginError.TooManyPlayersLoggedIn);
  661. return false;
  662. }
  663. }
  664.  
  665. if (Properties.STAFF_LOGIN)
  666. {
  667. // GMs are still allowed to enter server
  668. accountobjs = GameServer.Database.SelectObjects<Account>(string.Format("Name = '{0}'", GameServer.Database.Escape(username)));
  669. if (accountobjs.Count > 0)
  670. {
  671. Account account = accountobjs[0] as Account;
  672. if (account.PrivLevel > 1) return true;
  673. }
  674.  
  675. // Normal Players will not be allowed to log in
  676. client.Out.SendLoginDenied(eLoginError.GameCurrentlyClosed);
  677. return false;
  678. }
  679.  
  680. return true;
  681. }
  682.  
  683. #endregion
  684.  
  685. #region special anti-zerg-handling on calculating RP/BP-worth on player killed
  686.  
  687. /// <summary>
  688. /// Invoked on Player death and deals out
  689. /// experience/realm points if needed
  690. /// </summary>
  691. /// <param name="killedPlayer">player that died</param>
  692. /// <param name="killer">killer</param>
  693. public override void OnPlayerKilled(GamePlayer killedPlayer, GameObject killer)
  694. {
  695. #region "player has been killed recently"
  696. killedPlayer.LastDeathRealmPoints = 0;
  697. // "player has been killed recently"
  698. long noExpSeconds = ServerProperties.Properties.RP_WORTH_SECONDS;
  699. if (killedPlayer.DBCharacter.DeathTime + noExpSeconds > killedPlayer.PlayedTime)
  700. {
  701. lock (killedPlayer.XPGainers.SyncRoot)
  702. {
  703. foreach (DictionaryEntry de in killedPlayer.XPGainers)
  704. {
  705. if (de.Key is GamePlayer)
  706. {
  707. ((GamePlayer)de.Key).Out.SendMessage(killedPlayer.Name + " has been killed recently and is worth no realm points!", eChatType.CT_Important, eChatLoc.CL_SystemWindow);
  708. ((GamePlayer)de.Key).Out.SendMessage(killedPlayer.Name + " has been killed recently and is worth no experience!", eChatType.CT_Important, eChatLoc.CL_SystemWindow);
  709. }
  710. }
  711. }
  712. return;
  713. }
  714. #endregion "player has been killed recently"
  715.  
  716. lock (killedPlayer.XPGainers.SyncRoot)
  717. {
  718. #region "You gain no experience from this kill!"
  719. bool dealNoXP = false;
  720. float totalDamage = 0;
  721. //Collect the total damage
  722. foreach (DictionaryEntry de in killedPlayer.XPGainers)
  723. {
  724. GameObject obj = (GameObject)de.Key;
  725. if (obj is GamePlayer)
  726. {
  727. //If a gameplayer with privlevel > 1 attacked the
  728. //mob, then the players won't gain xp ...
  729. if (((GamePlayer)obj).Client.Account.PrivLevel > 1)
  730. {
  731. dealNoXP = true;
  732. break;
  733. }
  734. }
  735. totalDamage += (float)de.Value;
  736. }
  737.  
  738. if (dealNoXP)
  739. {
  740. foreach (DictionaryEntry de in killedPlayer.XPGainers)
  741. {
  742. GamePlayer player = de.Key as GamePlayer;
  743. if (player != null)
  744. player.Out.SendMessage("You gain no experience from this kill!", eChatType.CT_System, eChatLoc.CL_SystemWindow);
  745. }
  746. return;
  747. }
  748. #endregion "You gain no experience from this kill!"
  749.  
  750. #region calculating the base-amount of XP,RP+BP
  751. long playerExpValue = killedPlayer.ExperienceValue;
  752. playerExpValue = (long)(playerExpValue * ServerProperties.Properties.XP_RATE);
  753. int playerRPValue = killedPlayer.RealmPointsValue;
  754. int playerBPValue = 0;
  755. bool BG = false;
  756. foreach (AbstractGameKeep keep in GameServer.KeepManager.GetKeepsOfRegion(killedPlayer.CurrentRegionID))
  757. {
  758. if (keep.DBKeep.BaseLevel < 50)
  759. {
  760. BG = true;
  761. break;
  762. }
  763. }
  764. if (!BG)
  765. playerBPValue = killedPlayer.BountyPointsValue;
  766. long playerMoneyValue = killedPlayer.MoneyValue;
  767. #endregion calculating the base-amount
  768.  
  769. #region RECALCULATING the amount of XP,RP+BP based upon count of friends and enemies
  770.  
  771. // getting all attackers for died player
  772. // (better performance if we do it only once)
  773. Hashtable attackersOfKilledPlayer = new Hashtable();
  774. // getting all attackers for the enemies of died player
  775. Hashtable attackersOfKiller = new Hashtable();
  776. lock (killedPlayer.XPGainers.SyncRoot)
  777. {
  778. foreach (DictionaryEntry de in killedPlayer.XPGainers)
  779. if (de.Key is GameLiving)
  780. {
  781. attackersOfKilledPlayer[de.Key] = killedPlayer;
  782. GameLiving living = (GameLiving)de.Key;
  783. lock (living.XPGainers.SyncRoot)
  784. {
  785. foreach (DictionaryEntry de2 in living.XPGainers)
  786. attackersOfKiller[de2.Key] = living;
  787. }
  788. }
  789. }
  790.  
  791. // Counting friends and enemies in radius of 1500
  792. int nFriends = 1; // should be min 1 (killedPlayer itself) + others
  793. int nEnemies = 1; // should be min 1 (killer itself) + others
  794.  
  795. // try to parse killers player grp (if its a player and if it has a grp)
  796. Group killerPlayerGrp = null;
  797. if (killer is GamePlayer)
  798. killerPlayerGrp = ((GamePlayer)killer).Group;
  799. else if (killer is GameNPC && ((GameNPC)killer).Brain is ControlledNpcBrain)
  800. killerPlayerGrp = ((ControlledNpcBrain)((GameNPC)killer).Brain).Owner.Group;
  801.  
  802. // add killed players grp to friends (itself, not)
  803. if (killedPlayer.Group != null)
  804. nFriends += killedPlayer.Group.MemberCount - 1;
  805. if (killerPlayerGrp != null)
  806. nEnemies += killerPlayerGrp.MemberCount - 1;
  807.  
  808. // handle all players in radius
  809. foreach (GamePlayer player in killedPlayer.GetPlayersInRadius(1500))
  810. {
  811. // check if killer or killedPlayer itself (we already counted both above)
  812. if (player == killer || player == killedPlayer)
  813. continue;
  814. // check if player is GM
  815. if (player.Client.Account.PrivLevel >= (uint)ePrivLevel.GM)
  816. continue;
  817. // check if player is in killed players grp
  818. if (killedPlayer.Group != null && killedPlayer.Group.IsInTheGroup(player))
  819. continue;
  820. // check if player is in killer players grp
  821. if (killerPlayerGrp != null && killerPlayerGrp.IsInTheGroup(player))
  822. continue;
  823.  
  824. //->new code (2007-04-19)
  825. // look if this player is in the XPGainers-List of the died player
  826. // -> enemy
  827. if (attackersOfKilledPlayer.ContainsKey(player))
  828. nEnemies++;
  829. // look if this player is in the list of attackers of killedPlayers enemies (created&filled above)
  830. if (attackersOfKiller.ContainsKey(player))
  831. nFriends++;
  832. //<-new code (2007-04-19)
  833.  
  834. //->OBSOLETE as of above new code (2007-04-19)
  835. /*
  836. // else count it to the right side
  837. if ( killedPlayer.Realm == player.Realm )
  838. ++nFriends;
  839. else
  840. ++nEnemies;
  841. */
  842. //<-OBSOLETE as of above new code (2007-04-19)
  843. }
  844.  
  845. if (LOGGING)
  846. {
  847. StringBuilder sb = new StringBuilder();
  848. sb.Append("OnPlayerKilled(): ");
  849. if (killedPlayer != null) sb.Append(killedPlayer.Name); else sb.Append("???");
  850. sb.Append(" was killed by ");
  851. if (killer != null) sb.Append(killer.Name); else sb.Append("???");
  852.  
  853. if (killer != null && killer is GameNPC && ((GameNPC)killer).Brain is ControlledNpcBrain)
  854. sb.Append("(").Append(((ControlledNpcBrain)((GameNPC)killer).Brain).Owner.Name).Append(")");
  855.  
  856. sb.Append(" RP=").Append(playerRPValue).Append("->").Append(ReCalc(playerRPValue, nEnemies, nFriends, CALC_RATE));
  857. sb.Append(" Friends=").Append(nFriends).Append(" Enemies=").Append(nEnemies);
  858. if (CALC_PENALTY && nEnemies > nFriends)
  859. sb.Append(" PENALTY");
  860. else if (CALC_BONUS && nEnemies < nFriends)
  861. sb.Append(" BONUS");
  862. log.Info(sb.ToString());
  863. }
  864. // penalty or bonus for enemies
  865. // if they are more or less as friends
  866. // of died player
  867. if ((CALC_PENALTY && nEnemies > nFriends) ||
  868. (CALC_BONUS && nEnemies < nFriends))
  869. {
  870. playerExpValue = ReCalc(playerExpValue, nEnemies, nFriends, CALC_RATE);
  871. playerRPValue = (int)ReCalc(playerRPValue, nEnemies, nFriends, CALC_RATE);
  872. playerBPValue = (int)ReCalc(playerBPValue, nEnemies, nFriends, CALC_RATE);
  873. playerMoneyValue = ReCalc(playerMoneyValue, nEnemies, nFriends, CALC_RATE);
  874. /*
  875. playerExpValue /= nEnemies * nFriends;
  876. playerRPValue /= nEnemies * nFriends;
  877. playerBPValue /= nEnemies * nFriends;
  878. playerMoneyValue /= nEnemies * nFriends;
  879. */
  880. }
  881.  
  882. #endregion RECALCULATING the amount of XP,RP+BP based upon grp-sizes
  883.  
  884. #region Now deal the XP and RPs to all livings
  885. foreach (DictionaryEntry de in killedPlayer.XPGainers)
  886. {
  887. GameLiving living = de.Key as GameLiving;
  888. GamePlayer expGainPlayer = living as GamePlayer;
  889. if (living == null) continue;
  890. if (living.ObjectState != GameObject.eObjectState.Active) continue;
  891. /*
  892. * http://www.camelotherald.com/more/2289.shtml
  893. * Dead players will now continue to retain and receive their realm point credit
  894. * on targets until they release. This will work for solo players as well as
  895. * grouped players in terms of continuing to contribute their share to the kill
  896. * if a target is being attacked by another non grouped player as well.
  897. */
  898. //if (!living.Alive) continue;
  899. if (!WorldMgr.CheckDistance(living, killedPlayer, WorldMgr.MAX_EXPFORKILL_DISTANCE)) continue;
  900.  
  901.  
  902. double damagePercent = (float)de.Value / totalDamage;
  903. if (!living.IsAlive)//Dead living gets 25% exp only
  904. damagePercent *= 0.25;
  905.  
  906. // realm points
  907. int rpCap = living.RealmPointsValue * 2;
  908. int realmPoints = (int)(playerRPValue * damagePercent);
  909. //rp bonuses from RR and Group
  910. //20% if R1L0 char kills RR10,if RR10 char kills R1L0 he will get -20% bonus
  911. //100% if full group,scales down according to player count in group and their range to target
  912. if (living is GamePlayer)
  913. {
  914. GamePlayer killerPlayer = living as GamePlayer;
  915. realmPoints = (int)(realmPoints * (1.0 + 2.0 * (killedPlayer.RealmLevel - killerPlayer.RealmLevel) / 900.0));
  916. if (killerPlayer.Group != null && killerPlayer.Group.MemberCount > 1)
  917. {
  918. lock (killerPlayer.Group)
  919. {
  920. int count = 0;
  921. foreach (GamePlayer player in killerPlayer.Group.GetPlayersInTheGroup())
  922. {
  923. if (!WorldMgr.CheckDistance(player, killedPlayer, WorldMgr.MAX_EXPFORKILL_DISTANCE)) continue;
  924. count++;
  925. }
  926. realmPoints = (int)(realmPoints * (1.0 + count * 0.125));
  927. }
  928. }
  929. }
  930. if (realmPoints > rpCap)
  931. realmPoints = rpCap;
  932. if (realmPoints > 0)
  933. {
  934. if (living is GamePlayer)
  935. killedPlayer.LastDeathRealmPoints += realmPoints;
  936. living.GainRealmPoints(realmPoints);
  937. }
  938.  
  939. // bounty points
  940. int bpCap = living.BountyPointsValue * 2;
  941. int bountyPoints = (int)(playerBPValue * damagePercent);
  942. if (bountyPoints > bpCap)
  943. bountyPoints = bpCap;
  944.  
  945. #warning this is guessed, i do not believe this is the right way, we will most likely need special messages to be sent
  946. //apply the keep bonus for bounty points
  947. if (killer != null)
  948. {
  949. if (Keeps.KeepBonusMgr.RealmHasBonus(eKeepBonusType.Bounty_Points_5, (eRealm)killer.Realm))
  950. bountyPoints += (bountyPoints / 100) * 5;
  951. else if (Keeps.KeepBonusMgr.RealmHasBonus(eKeepBonusType.Bounty_Points_3, (eRealm)killer.Realm))
  952. bountyPoints += (bountyPoints / 100) * 3;
  953. }
  954.  
  955. if (bountyPoints > 0)
  956. {
  957. living.GainBountyPoints(bountyPoints);
  958. }
  959.  
  960. //Claim Bonus RP/BP if Player Guild have a keep/tower.
  961. GamePlayer pl = living as GamePlayer;
  962. if (pl != null && pl.Guild != null && pl.Guild.ClaimedKeeps != null)
  963. {
  964. foreach (AbstractGameKeep keep in pl.Guild.ClaimedKeeps)
  965. {
  966. if (pl.CurrentRegionID == keep.Region)
  967. {
  968. GuildClaimBonus(realmPoints, bountyPoints, pl, keep);
  969. }
  970. }
  971. }
  972.  
  973.  
  974.  
  975. // experience
  976. // TODO: pets take 25% and owner gets 75%
  977. long xpReward = (long)(playerExpValue * damagePercent); // exp for damage percent
  978.  
  979. long expCap = (long)(living.ExperienceValue * 1.25);
  980. if (xpReward > expCap)
  981. xpReward = expCap;
  982.  
  983. //outpost XP
  984. //1.54 http://www.camelotherald.com/more/567.shtml
  985. //- Players now receive an exp bonus when fighting within 16,000
  986. //units of a keep controlled by your realm or your guild.
  987. //You get 20% bonus if your guild owns the keep or a 10% bonus
  988. //if your realm owns the keep.
  989.  
  990. long outpostXP = 0;
  991.  
  992. if (!BG && living is GamePlayer)
  993. {
  994. AbstractGameKeep keep = GameServer.KeepManager.GetKeepCloseToSpot(living.CurrentRegionID, living, 16000);
  995. if (keep != null)
  996. {
  997. byte bonus = 0;
  998. if (keep.Guild != null && keep.Guild == (living as GamePlayer).Guild)
  999. bonus = 20;
  1000. else if (GameServer.Instance.Configuration.ServerType == eGameServerType.GST_Normal &&
  1001. keep.Realm == living.Realm)
  1002. bonus = 10;
  1003.  
  1004. outpostXP = (xpReward / 100) * bonus;
  1005. }
  1006. }
  1007. xpReward += outpostXP;
  1008.  
  1009. living.GainExperience(GameLiving.eXPSource.Player, xpReward);
  1010.  
  1011. //gold
  1012. if (living is GamePlayer)
  1013. {
  1014. long money = (long)(playerMoneyValue * damagePercent);
  1015. //long money = (long)(Money.GetMoney(0, 0, 17, 85, 0) * damagePercent * killedPlayer.Level / 50);
  1016. ((GamePlayer)living).AddMoney(money, "You recieve {0}");
  1017. }
  1018.  
  1019. if (killedPlayer.ReleaseType != GamePlayer.eReleaseType.Duel && expGainPlayer != null)
  1020. {
  1021. switch ((eRealm)killedPlayer.Realm)
  1022. {
  1023. case eRealm.Albion:
  1024. expGainPlayer.KillsAlbionPlayers++;
  1025. if (expGainPlayer == killer)
  1026. {
  1027. expGainPlayer.KillsAlbionDeathBlows++;
  1028. if ((float)de.Value == totalDamage)
  1029. expGainPlayer.KillsAlbionSolo++;
  1030. }
  1031. break;
  1032.  
  1033. case eRealm.Hibernia:
  1034. expGainPlayer.KillsHiberniaPlayers++;
  1035. if (expGainPlayer == killer)
  1036. {
  1037. expGainPlayer.KillsHiberniaDeathBlows++;
  1038. if ((float)de.Value == totalDamage)
  1039. expGainPlayer.KillsHiberniaSolo++;
  1040. }
  1041. break;
  1042.  
  1043. case eRealm.Midgard:
  1044. expGainPlayer.KillsMidgardPlayers++;
  1045. if (expGainPlayer == killer)
  1046. {
  1047. expGainPlayer.KillsMidgardDeathBlows++;
  1048. if ((float)de.Value == totalDamage)
  1049. expGainPlayer.KillsMidgardSolo++;
  1050. }
  1051. break;
  1052. }
  1053. killedPlayer.DeathsPvP++;
  1054. }
  1055. }
  1056. #endregion Now deal the XP and RPs to all livings
  1057. }
  1058. }
  1059.  
  1060. #region recalculation method
  1061. /// <summary>
  1062. /// it returns (value * rate / devisor * factor) + value * (1-rate)
  1063. /// </summary>
  1064. /// <param name="value">the value which should be recalculated</param>
  1065. /// <param name="divisor">the divisor for the rate of value</param>
  1066. /// <param name="factor">the factor for the rate of value</param>
  1067. /// <param name="rate">rate in percent [0..1]</param>
  1068. /// <returns></returns>
  1069. private long ReCalc(long value, int divisor, int factor, double rate)
  1070. {
  1071. if (rate < 0.0)
  1072. rate = 0.0;
  1073. else if (rate > 1.0)
  1074. rate = 1.0;
  1075. if (divisor == 0)
  1076. divisor = 1;
  1077. return (long)Math.Round(value * rate / divisor * factor + value * (1.0 - rate));
  1078. }
  1079. #endregion
  1080.  
  1081. #region GuildClaimBonus
  1082.  
  1083. /// <summary>
  1084. /// Will add a RP bonus if your guild claim a Tower or Keep.
  1085. /// </summary>
  1086. /// <param name="RP">The RealmPoints the Player will earn.</param>
  1087. /// <param name="BP">The BountyPoints the Player will earn.</param>
  1088. /// <param name="pl">The Player that earn the bonus.</param>
  1089. private void GuildClaimBonus(int RP, int BP, GamePlayer pl, AbstractGameKeep keep)
  1090. {
  1091. if (RP == 0
  1092. && BP == 0
  1093. && pl == null)
  1094. return;
  1095.  
  1096. int RPbonus = (int)(RP * CLAIM_BONUS);
  1097. int BPbonus = (int)(BP * CLAIM_BONUS);
  1098. if (CLAIM_STATUS)
  1099. {
  1100. pl.Out.SendMessage("Your Guild have claimed the " + keep.Name + " therefore you receives " + RPbonus.ToString() + " realmpoints and " + BPbonus.ToString() + " bountypoints as a bonus.", eChatType.CT_Important, eChatLoc.CL_SystemWindow);
  1101. pl.BountyPoints += BPbonus;
  1102. pl.RealmPoints += RPbonus;
  1103. }
  1104. if (CLAIM_LOGGING)
  1105. log.Info("ClaimBonus: Player=" + pl.Name + " Acc: " + pl.Client.Account.Name + " Guild: " + pl.Guild.Name + " HasClaimed: " + keep.Name + " RP/BP Bonus: " + RPbonus.ToString() + " / " + BPbonus.ToString());
  1106.  
  1107. return;
  1108. }
  1109.  
  1110. #endregion GuildClaimBonus
  1111.  
  1112. #endregion
  1113. }
  1114. }
  1115.  
  1116. #region send name-coloring on regionchanged
  1117.  
  1118. namespace DOL.GS.GameEvents
  1119. {
  1120. /// <summary>
  1121. ///
  1122. /// </summary>
  1123. public class ColorHandlingRegionChangedEvent
  1124. {
  1125. /// <summary>
  1126. /// Defines a logger for this class.
  1127. /// </summary>
  1128. public static readonly ILog LOG = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  1129.  
  1130. /// <summary>
  1131. /// Event handler fired when server is started
  1132. /// </summary>
  1133. [GameServerStartedEvent]
  1134. public static void OnServerStart(DOLEvent e, object sender, EventArgs arguments)
  1135. {
  1136. GameEventMgr.AddHandler(GamePlayerEvent.RegionChanged, new DOLEventHandler(PlayerRegionChanged));
  1137. GameEventMgr.AddHandler(GamePlayerEvent.GameEntered, new DOLEventHandler(PlayerGameEntered));
  1138. }
  1139.  
  1140. /// <summary>
  1141. /// Event handler fired when server is stopped
  1142. /// </summary>
  1143. [GameServerStoppedEvent]
  1144. public static void OnServerStop(DOLEvent e, object sender, EventArgs arguments)
  1145. {
  1146. GameEventMgr.RemoveHandler(GamePlayerEvent.RegionChanged, new DOLEventHandler(PlayerRegionChanged));
  1147. GameEventMgr.RemoveHandler(GamePlayerEvent.GameEntered, new DOLEventHandler(PlayerGameEntered));
  1148. }
  1149.  
  1150.  
  1151.  
  1152. private static void CheckGroup(GamePlayer player)
  1153. {
  1154. if (player == null || player.Group == null) return;
  1155. lock (player)
  1156. {
  1157. foreach (GamePlayer p in player.Group.GetPlayersInTheGroup())
  1158. if (p != null
  1159. && p != player
  1160. && !GameServer.ServerRules.IsAllowedToGroup(p, player, true))
  1161. {
  1162. player.Group.SendMessageToGroupMembers("You are not allowed to group other realmmates here!", eChatType.CT_Important, eChatLoc.CL_ChatWindow);
  1163. player.Group.RemoveMember(player);
  1164. break;
  1165. }
  1166. }
  1167. }
  1168.  
  1169. private static void ResetColorHandling(GamePlayer player)
  1170. {
  1171. if (player == null) return;
  1172. lock (player)
  1173. {
  1174. if (player.CurrentRegionID == 335) // my setup zone
  1175. {
  1176. player.Out.SendLoginGranted(3);
  1177. player.Out.SendRegionColorScheme(3);
  1178. /* else if (player.CurrentRegionID == ) // my pve zone
  1179. player.Out.SendLoginGranted(3);
  1180.  
  1181. */
  1182. }
  1183. else
  1184. {
  1185. player.Out.SendLoginGranted(0); // other zones:P
  1186. }
  1187. player.Out.SendLevelUpSound();
  1188. }
  1189. }
  1190. /// <summary>
  1191. /// Event handler fired when players changed region
  1192. /// </summary>
  1193. /// <param name="e"></param>
  1194. /// <param name="sender"></param>
  1195. /// <param name="arguments"></param>
  1196. private static void PlayerRegionChanged(DOLEvent e, object sender, EventArgs arguments)
  1197. {
  1198. ResetColorHandling(sender as GamePlayer);
  1199. CheckGroup(sender as GamePlayer);
  1200. }
  1201.  
  1202. /// <summary>
  1203. /// Event handler fired when players enters the game
  1204. /// </summary>
  1205. /// <param name="e"></param>
  1206. /// <param name="sender"></param>
  1207. /// <param name="arguments"></param>
  1208. private static void PlayerGameEntered(DOLEvent e, object sender, EventArgs arguments)
  1209. {
  1210. ResetColorHandling(sender as GamePlayer);
  1211. }
  1212. }
  1213. }
  1214.  
  1215. #endregion
  1216.  
  1217. #region special examine-handling for safe-zones
  1218.  
  1219. namespace DOL.GS.PacketHandler.Client.v168
  1220. {
  1221. /// <summary>
  1222. /// Handles player target changes
  1223. /// </summary>
  1224. [PacketHandlerAttribute(PacketHandlerType.TCP, 0x18 ^ 168, "Handles player target changes")]
  1225. public class TCPlayerTargetHandler : IPacketHandler
  1226. {
  1227. public void HandlePacket(GameClient client, GSPacketIn packet)
  1228. {
  1229. ushort targetID = packet.ReadShort();
  1230. ushort flags = packet.ReadShort();
  1231. /*
  1232. * 0x8000 = 'examine' bit
  1233. * 0x4000 = LOS1 bit; is 0 if no LOS
  1234. * 0x2000 = LOS2 bit; is 0 if no LOS
  1235. * 0x0001 = players attack mode bit (not targets!)
  1236. */
  1237.  
  1238. ChangeTargetAction action = new ChangeTargetAction(
  1239. client.Player,
  1240. targetID,
  1241. !((flags & (0x4000 | 0x2000)) == 0),
  1242. (flags & 0x8000) != 0);
  1243.  
  1244. action.Start(1);
  1245.  
  1246.  
  1247. }
  1248.  
  1249.  
  1250. /// <summary>
  1251. /// Handles every received packet
  1252. /// </summary>
  1253. /// <param name="client">The client that sent the packet</param>
  1254. /// <param name="packet">The received packet data</param>
  1255. /// <returns></returns>
  1256.  
  1257.  
  1258. /// <summary>
  1259. /// Changes players target
  1260. /// </summary>
  1261. protected class ChangeTargetAction : RegionAction
  1262. {
  1263. /// <summary>
  1264. /// The new target OID
  1265. /// </summary>
  1266. protected readonly int m_newTargetId;
  1267. /// <summary>
  1268. /// The 'target in view' flag
  1269. /// </summary>
  1270. protected readonly bool m_targetInView;
  1271. /// <summary>
  1272. /// The 'examine target' bit
  1273. /// </summary>
  1274. protected readonly bool m_examineTarget;
  1275.  
  1276. /// <summary>
  1277. /// Constructs a new TargetChangeAction
  1278. /// </summary>
  1279. /// <param name="actionSource">The action source</param>
  1280. /// <param name="newTargetId">The new target OID</param>
  1281. /// <param name="targetInView">The target LOS bit</param>
  1282. /// <param name="examineTarget">The 'examine target' bit</param>
  1283. public ChangeTargetAction(GamePlayer actionSource, int newTargetId, bool targetInView, bool examineTarget)
  1284. : base(actionSource)
  1285. {
  1286. m_newTargetId = newTargetId;
  1287. m_targetInView = targetInView;
  1288. m_examineTarget = examineTarget;
  1289. }
  1290.  
  1291. /// <summary>
  1292. /// Called on every timer tick
  1293. /// </summary>
  1294. protected override void OnTick()
  1295. {
  1296. GamePlayer player = (GamePlayer)m_actionSource;
  1297.  
  1298. GameObject myTarget = player.CurrentRegion.GetObject((ushort)m_newTargetId);
  1299. player.TargetObject = myTarget;
  1300. player.TargetInView = m_targetInView;
  1301.  
  1302. if (myTarget != null)
  1303. {
  1304. // Send target message text only if 'examine' bit is set.
  1305. if (m_examineTarget)
  1306. {
  1307. IList messages = myTarget.GetExamineMessages(player);
  1308. if (myTarget is GamePlayer)
  1309. {
  1310. GamePlayer targetPlayer = myTarget as GamePlayer;
  1311. if (player.Client.Account.PrivLevel < (uint)ePrivLevel.GM
  1312. && targetPlayer.Client.Account.PrivLevel < (uint)ePrivLevel.GM)
  1313. {
  1314. if (TCServerRules.IsSafeZone(myTarget.CurrentRegionID))
  1315. {
  1316. messages.RemoveAt(messages.Count - 1);
  1317. messages.Add(string.Format(LanguageMgr.GetTranslation(player.Client, "GamePlayer.GetExamineMessages.RealmMember", player.GetName(targetPlayer), targetPlayer.GetPronoun(player.Client, 0, true), targetPlayer.CharacterClass.Name)));
  1318. }
  1319.  
  1320. }// if both players are no GMs
  1321. }// if myTarget is GamePlayer
  1322.  
  1323. foreach (string message in messages)
  1324. {
  1325. player.Out.SendMessage(message, eChatType.CT_System, eChatLoc.CL_SystemWindow);
  1326. }
  1327. }
  1328. // Then no LOS message; not sure which bit to use so use both :)
  1329. // should be sent if targeted is using group panel to change the target
  1330. if (!m_targetInView)
  1331. {
  1332. player.Out.SendMessage("Target is not in view.", eChatType.CT_System, eChatLoc.CL_SystemWindow);
  1333. }
  1334.  
  1335. player.Out.SendObjectUpdate(myTarget);
  1336. }
  1337.  
  1338. if (player.IsPraying)
  1339. {
  1340. GameGravestone gravestone = myTarget as GameGravestone;
  1341. if (gravestone == null || !gravestone.InternalID.Equals(player.InternalID))
  1342. {
  1343. player.Out.SendMessage("You are no longer targetting your grave. Your prayers fail.", eChatType.CT_System, eChatLoc.CL_SystemWindow);
  1344. player.PrayTimerStop();
  1345. }
  1346. }
  1347. }
  1348. }
  1349.  
  1350.  
  1351. }
  1352. }
  1353.  
  1354.  
  1355. #endregion
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement