FloodProtectorAction.java 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. * This program is free software: you can redistribute it and/or modify it under the terms of the
  3. * GNU General Public License as published by the Free Software Foundation, either version 3 of the
  4. * License, or (at your option) any later version.
  5. *
  6. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
  7. * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  8. * General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with this program. If
  11. * not, see <http://www.gnu.org/licenses/>.
  12. */
  13. package com.l2jserver.gameserver.util;
  14. import java.util.concurrent.atomic.AtomicInteger;
  15. import java.util.logging.Level;
  16. import java.util.logging.Logger;
  17. import com.l2jserver.gameserver.GameTimeController;
  18. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  19. import com.l2jserver.util.StringUtil;
  20. /**
  21. * Flood protector implementation.
  22. *
  23. * @author fordfrog
  24. */
  25. public final class FloodProtectorAction
  26. {
  27. /**
  28. * Logger
  29. */
  30. private static final Logger _log = Logger.getLogger(FloodProtectorAction.class.getName());
  31. /**
  32. * Player for this instance of flood protector.
  33. */
  34. private final L2PcInstance _player;
  35. /**
  36. * Configuration of this instance of flood protector.
  37. */
  38. private final FloodProtectorConfig _config;
  39. /**
  40. * Next game tick when new request is allowed.
  41. */
  42. private volatile int _nextGameTick = GameTimeController.getGameTicks();
  43. /**
  44. * Request counter.
  45. */
  46. private AtomicInteger _count = new AtomicInteger(0);
  47. /**
  48. * Flag determining whether exceeding request has been logged.
  49. */
  50. private boolean _logged;
  51. /**
  52. * Flag determining whether punishment application is in progress so that we do not apply
  53. * punisment multiple times (flooding).
  54. */
  55. private volatile boolean _punishmentInProgress;
  56. /**
  57. * Creates new instance of FloodProtectorAction.
  58. *
  59. * @param player
  60. * player for which flood protection is being created
  61. * @param config
  62. * flood protector configuration
  63. */
  64. public FloodProtectorAction(final L2PcInstance player, final FloodProtectorConfig config)
  65. {
  66. super();
  67. _player = player;
  68. _config = config;
  69. }
  70. /**
  71. * Checks whether the request is flood protected or not.
  72. *
  73. * @param command
  74. * command issued or short command description
  75. *
  76. * @return true if action is allowed, otherwise false
  77. */
  78. public boolean tryPerformAction(final String command)
  79. {
  80. final int curTick = GameTimeController.getGameTicks();
  81. if (curTick < _nextGameTick || _punishmentInProgress)
  82. {
  83. if (_config.LOG_FLOODING && !_logged && _log.isLoggable(Level.WARNING))
  84. {
  85. _log.warning(StringUtil.concat(_config.FLOOD_PROTECTOR_TYPE, ": Player [", _player.getName(), "] called command [", command, "] [~", String.valueOf((_config.FLOOD_PROTECTION_INTERVAL - (_nextGameTick - curTick)) * GameTimeController.MILLIS_IN_TICK), " ms] after previous command"));
  86. _logged = true;
  87. }
  88. _count.incrementAndGet();
  89. if (!_punishmentInProgress && _config.PUNISHMENT_LIMIT > 0 && _count.get() > _config.PUNISHMENT_LIMIT && _config.PUNISHMENT_TYPE != null)
  90. {
  91. _punishmentInProgress = true;
  92. if ("kick".equals(_config.PUNISHMENT_TYPE))
  93. {
  94. kickPlayer();
  95. }
  96. else if ("ban".equals(_config.PUNISHMENT_TYPE))
  97. {
  98. banAccount();
  99. }
  100. else if ("jail".equals(_config.PUNISHMENT_TYPE))
  101. {
  102. jailChar();
  103. }
  104. _punishmentInProgress = false;
  105. }
  106. return false;
  107. }
  108. if (_count.get() > 0)
  109. {
  110. if (_config.LOG_FLOODING && _log.isLoggable(Level.WARNING))
  111. {
  112. _log.warning(StringUtil.concat(_config.FLOOD_PROTECTOR_TYPE, ": Player [", _player.getName(), "] issued [", String.valueOf(_count), "] extra requests within [~", String.valueOf(_config.FLOOD_PROTECTION_INTERVAL * GameTimeController.MILLIS_IN_TICK), " ms]"));
  113. }
  114. }
  115. _nextGameTick = curTick + _config.FLOOD_PROTECTION_INTERVAL;
  116. _logged = false;
  117. _count.set(0);
  118. return true;
  119. }
  120. /**
  121. * Kick player from game (close network connection).
  122. */
  123. private void kickPlayer()
  124. {
  125. _player.logout(false);
  126. if (_log.isLoggable(Level.WARNING))
  127. {
  128. _log.warning(StringUtil.concat(_config.FLOOD_PROTECTOR_TYPE, ": Account [", _player.getAccountName(), "] kicked for flooding [char ", _player.getName(), "]"));
  129. }
  130. }
  131. /**
  132. * Bans char account and logs out the char.
  133. */
  134. private void banAccount()
  135. {
  136. _player.setPunishLevel(L2PcInstance.PunishLevel.ACC, _config.PUNISHMENT_TIME);
  137. if (_log.isLoggable(Level.WARNING))
  138. {
  139. _log.warning(StringUtil.concat(_config.FLOOD_PROTECTOR_TYPE, ": Account [", _player.getAccountName(), "] banned for flooding [char ", _player.getName(), "] ", _config.PUNISHMENT_TIME <= 0 ? "forever" : "for " + _config.PUNISHMENT_TIME + " mins"));
  140. }
  141. _player.logout();
  142. }
  143. /**
  144. * Jails char.
  145. */
  146. private void jailChar()
  147. {
  148. _player.setPunishLevel(L2PcInstance.PunishLevel.JAIL, _config.PUNISHMENT_TIME);
  149. if (_log.isLoggable(Level.WARNING))
  150. {
  151. _log.warning(StringUtil.concat(_config.FLOOD_PROTECTOR_TYPE, ": Player [", _player.getName(), "] jailed for flooding [char ", _player.getName(), "] ", _config.PUNISHMENT_TIME <= 0 ? "forever" : "for " + _config.PUNISHMENT_TIME + " mins"));
  152. }
  153. }
  154. }