Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. Index: /trunk/aCis_gameserver/config/server.properties
  2. ===================================================================
  3. --- /trunk/aCis_gameserver/config/server.properties (revision 427)
  4. +++ /trunk/aCis_gameserver/config/server.properties (revision 428)
  5. @@ -286,5 +286,5 @@
  6. -# =================================================================
  7. -#                                Misc
  8. -# =================================================================
  9. -
  10. -# Basic protection against L2Walker.
  11. -L2WalkerProtection = False
  12. -
  13. +# =================================================================
  14. +#                                Misc
  15. +# =================================================================
  16. +
  17. +# Bots prevention system.
  18. +EnableBotsPrevention = False
  19. +# How many monsters have to be killed to run validation task?
  20. +KillsCounter = 60
  21. +# Specify range of randomly taken values summed with main counter.
  22. +KillsCounterRandomization = 50
  23. +# How long validation window awaits an answer? (in seconds)
  24. +ValidationTime = 60
  25. +# Punishments:
  26. +0 = move character to the closest village.
  27. +#  1 = kick characters from the server.
  28. +2 = put character to jail.
  29. +3 = ban character from the server.
  30. +Punishment = 0
  31. +# How long character were suppose to stay in jail? (in minutes)
  32. +PunishmentTime = 60
  33. +
  34. +# Basic protection against L2Walker.
  35. +L2WalkerProtection = False
  36. +
  37. Index: trunk/aCis_gameserver/java/net/sf/l2j/Config.java
  38. ===================================================================
  39. --- trunk/aCis_gameserver/java/net/sf/l2j/Config.java   (rĂ©vision 427)
  40. +++ trunk/aCis_gameserver/java/net/sf/l2j/Config.java   (rĂ©vision 428)
  41. @@ -653,5 +653,5 @@
  42. -   /** Misc */
  43. +   /** Misc */
  44. +   public static boolean BOTS_PREVENTION;
  45. +   public static int KILLS_COUNTER;
  46. +   public static int KILLS_COUNTER_RANDOMIZATION;
  47. +   public static int VALIDATION_TIME;
  48. +   public static int PUNISHMENT;
  49. +   public static int PUNISHMENT_TIME;
  50. @@ -1264 +1264 @@
  51. -           L2WALKER_PROTECTION = server.getProperty("L2WalkerProtection", false);
  52. +           BOTS_PREVENTION = server.getProperty("EnableBotsPrevention", false);
  53. +           KILLS_COUNTER = server.getProperty("KillsCounter", 60);
  54. +           KILLS_COUNTER_RANDOMIZATION = server.getProperty("KillsCounterRandomization", 50);
  55. +           VALIDATION_TIME = server.getProperty("ValidationTime", 60);
  56. +           PUNISHMENT = server.getProperty("Punishment", 0);
  57. +           PUNISHMENT_TIME = server.getProperty("PunishmentTime", 60);
  58. +           L2WALKER_PROTECTION = server.getProperty("L2WalkerProtection", false);
  59. +
  60. Index: trunk/aCis_gameserver/java/net/sf/l2j/gameserver/instancemanager/BotsPreventionManager.java
  61. ===================================================================
  62. --- trunk/aCis_gameserver/java/net/sf/l2j/gameserver/instancemanager/BotsPreventionManager.java (revision 0)
  63. +++ trunk/aCis_gameserver/java/net/sf/l2j/gameserver/instancemanager/BotsPreventionManager.java (revision 1)
  64. @@ -0 +0 @@
  65. +package net.sf.l2j.gameserver.instancemanager;
  66. +
  67. +import java.io.File;
  68. +import java.io.RandomAccessFile;
  69. +import java.sql.Connection;
  70. +import java.sql.PreparedStatement;
  71. +import java.sql.SQLException;
  72. +import java.util.ArrayList;
  73. +import java.util.Calendar;
  74. +import java.util.HashMap;
  75. +import java.util.List;
  76. +import java.util.Map;
  77. +import java.util.Random;
  78. +import java.util.concurrent.Future;
  79. +
  80. +import net.sf.l2j.Config;
  81. +import net.sf.l2j.L2DatabaseFactory;
  82. +import net.sf.l2j.commons.lang.StringUtil;
  83. +import net.sf.l2j.gameserver.ThreadPoolManager;
  84. +import net.sf.l2j.gameserver.datatables.MapRegionTable;
  85. +import net.sf.l2j.gameserver.model.actor.L2Character;
  86. +import net.sf.l2j.gameserver.model.actor.instance.L2MonsterInstance;
  87. +import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
  88. +import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage;
  89. +import net.sf.l2j.gameserver.network.serverpackets.PledgeCrest;
  90. +
  91. +public class BotsPreventionManager
  92. +{
  93. +   private class PlayerData
  94. +   {
  95. +       public PlayerData()
  96. +       {
  97. +           firstWindow = true;
  98. +       }
  99. +      
  100. +       public int mainpattern;
  101. +       public List<Integer> options = new ArrayList<>();
  102. +       public boolean firstWindow;
  103. +       public int patternid;
  104. +   }
  105. +  
  106. +   protected Random _randomize;
  107. +   protected static Map<Integer, Integer> _monsterscounter;
  108. +   protected static Map<Integer, Future<?>> _beginvalidation;
  109. +   protected static Map<Integer, PlayerData> _validation;
  110. +   protected static Map<Integer, byte[]> _images;
  111. +   protected int WINDOW_DELAY = 3; //delay used to generate new window if previous have been closed.
  112. +   protected int VALIDATION_TIME = Config.VALIDATION_TIME * 1000;
  113. +  
  114. +   public static final BotsPreventionManager getInstance()
  115. +   {
  116. +       return SingletonHolder._instance;
  117. +   }
  118. +  
  119. +   BotsPreventionManager()
  120. +   {
  121. +       _randomize = new Random();
  122. +       _monsterscounter = new HashMap<>();
  123. +       _beginvalidation = new HashMap<>();
  124. +       _validation = new HashMap<>();
  125. +       _images = new HashMap<>();
  126. +       _beginvalidation = new HashMap<>();
  127. +      
  128. +       getimages();
  129. +   }
  130. +  
  131. +   public void updatecounter(L2Character player, L2Character monster)
  132. +   {
  133. +       if ((player instanceof L2PcInstance) && (monster instanceof L2MonsterInstance))
  134. +       {
  135. +           L2PcInstance killer = (L2PcInstance) player;
  136. +          
  137. +           if (_validation.get(killer.getObjectId()) != null)
  138. +           {
  139. +               return;
  140. +           }
  141. +          
  142. +           int count = 1;
  143. +           if (_monsterscounter.get(killer.getObjectId()) != null)
  144. +           {
  145. +               count = _monsterscounter.get(killer.getObjectId()) + 1;
  146. +           }
  147. +          
  148. +           int next = _randomize.nextInt(Config.KILLS_COUNTER_RANDOMIZATION);
  149. +           if (Config.KILLS_COUNTER + next < count)
  150. +           {
  151. +               validationtasks(killer);
  152. +               _monsterscounter.remove(killer.getObjectId());
  153. +           }
  154. +           else
  155. +           {
  156. +               _monsterscounter.put(killer.getObjectId(), count);
  157. +           }
  158. +       }
  159. +   }
  160. +  
  161. +   private static void getimages()
  162. +   {
  163. +       String CRESTS_DIR = "data/html/mods/prevention";
  164. +      
  165. +       final File directory = new File(CRESTS_DIR);
  166. +       directory.mkdirs();
  167. +      
  168. +       int i = 0;
  169. +       for (File file : directory.listFiles())
  170. +       {
  171. +           if (!file.getName().endsWith(".dds"))
  172. +               continue;
  173. +          
  174. +           byte[] data;
  175. +          
  176. +           try (RandomAccessFile f = new RandomAccessFile(file, "r"))
  177. +           {
  178. +               data = new byte[(int) f.length()];
  179. +               f.readFully(data);
  180. +           }
  181. +           catch (Exception e)
  182. +           {
  183. +               continue;
  184. +           }
  185. +           _images.put(i, data);
  186. +           i++;
  187. +       }
  188. +   }
  189. +  
  190. +   public void prevalidationwindow(L2PcInstance player)
  191. +   {
  192. +       NpcHtmlMessage html = new NpcHtmlMessage(1);
  193. +       StringBuilder tb = new StringBuilder();
  194. +       StringUtil.append(tb, "<html>");
  195. +       StringUtil.append(tb, "<title>Bots prevention</title>");
  196. +       StringUtil.append(tb, "<body><center><br><br><img src=\"L2UI_CH3.herotower_deco\" width=\"256\" height=\"32\">");
  197. +       StringUtil.append(tb, "<br><br><font color=\"a2a0a2\">if such window appears it means server suspect,<br1>that you may using cheating software.</font>");
  198. +       StringUtil.append(tb, "<br><br><font color=\"b09979\">if given answer results are incorrect or no action is made<br1>server is going to punish character instantly.</font>");
  199. +       StringUtil.append(tb, "<br><br><button value=\"CONTINUE\" action=\"bypass report_continue\" width=\"75\" height=\"21\" back=\"L2UI_CH3.Btn1_normal\" fore=\"L2UI_CH3.Btn1_normal\">");
  200. +       StringUtil.append(tb, "</center></body>");
  201. +       StringUtil.append(tb, "</html>");
  202. +       html.setHtml(tb.toString());
  203. +       player.sendPacket(html);
  204. +   }
  205. +  
  206. +   private static void validationwindow(L2PcInstance player)
  207. +   {
  208. +       PlayerData container = _validation.get(player.getObjectId());
  209. +       NpcHtmlMessage html = new NpcHtmlMessage(1);
  210. +      
  211. +       StringBuilder tb = new StringBuilder();
  212. +       StringUtil.append(tb, "<html>");
  213. +       StringUtil.append(tb, "<title>Bots prevention</title>");
  214. +       StringUtil.append(tb, "<body><center><br><br><img src=\"L2UI_CH3.herotower_deco\" width=\"256\" height=\"32\">");
  215. +       StringUtil.append(tb, "<br><br><font color=\"a2a0a2\">in order to prove you are a human being<br1>you've to</font> <font color=\"b09979\">match colours within generated pattern:</font>");
  216. +      
  217. +       // generated main pattern.
  218. +       StringUtil.append(tb, "<br><br><img src=\"Crest.crest_" + Config.SERVER_ID + "_" + (_validation.get(player.getObjectId()).patternid) + "\" width=\"32\" height=\"32\"></td></tr>");
  219. +       StringUtil.append(tb, "<br><br><font color=b09979>click-on pattern of your choice beneath:</font>");
  220. +      
  221. +       // generate random colours.
  222. +       StringUtil.append(tb, "<table><tr>");
  223. +       for (int i = 0; i < container.options.size(); i++)
  224. +       {
  225. +           StringUtil.append(tb, "<td><button action=\"bypass -h report_" + i + "\" width=32 height=32 back=\"Crest.crest_" + Config.SERVER_ID + "_" + (container.options.get(i) + 1500) + "\" fore=\"Crest.crest_" + Config.SERVER_ID + "_" + (container.options.get(i) + 1500) + "\"></td>");
  226. +       }
  227. +       StringUtil.append(tb, "</tr></table>");
  228. +       StringUtil.append(tb, "</center></body>");
  229. +       StringUtil.append(tb, "</html>");
  230. +      
  231. +       html.setHtml(tb.toString());
  232. +       player.sendPacket(html);
  233. +   }
  234. +  
  235. +   public void punishmentnwindow(L2PcInstance player)
  236. +   {
  237. +       NpcHtmlMessage html = new NpcHtmlMessage(1);
  238. +       StringBuilder tb = new StringBuilder();
  239. +       StringUtil.append(tb, "<html>");
  240. +       StringUtil.append(tb, "<title>Bots prevention</title>");
  241. +       StringUtil.append(tb, "<body><center><br><br><img src=\"L2UI_CH3.herotower_deco\" width=\"256\" height=\"32\">");
  242. +       StringUtil.append(tb, "<br><br><font color=\"a2a0a2\">if such window appears, it means character haven't<br1>passed through prevention system.");
  243. +       StringUtil.append(tb, "<br><br><font color=\"b09979\">in such case character get moved to nearest town.</font>");
  244. +       StringUtil.append(tb, "</center></body>");
  245. +       StringUtil.append(tb, "</html>");
  246. +       html.setHtml(tb.toString());
  247. +       player.sendPacket(html);
  248. +   }
  249. +  
  250. +   public void validationtasks(L2PcInstance player)
  251. +   {
  252. +       PlayerData container = new PlayerData();
  253. +       randomizeimages(container, player);
  254. +      
  255. +       for (int i = 0; i < container.options.size(); i++)
  256. +       {
  257. +           PledgeCrest packet = new PledgeCrest((container.options.get(i) + 1500), _images.get(container.options.get(i)));
  258. +           player.sendPacket(packet);
  259. +          
  260. +       }
  261. +      
  262. +       PledgeCrest packet = new PledgeCrest(container.patternid, _images.get(container.options.get(container.mainpattern)));
  263. +       player.sendPacket(packet);
  264. +      
  265. +       _validation.put(player.getObjectId(), container);
  266. +      
  267. +       Future<?> newTask = ThreadPoolManager.getInstance().scheduleGeneral(new ReportCheckTask(player), VALIDATION_TIME);
  268. +       ThreadPoolManager.getInstance().scheduleGeneral(new countdown(player, VALIDATION_TIME / 1000), 0);
  269. +       _beginvalidation.put(player.getObjectId(), newTask);
  270. +   }
  271. +  
  272. +   protected void randomizeimages(PlayerData container,L2PcInstance player)
  273. +   {
  274. +       int buttonscount = 4;
  275. +       int imagescount = _images.size();
  276. +      
  277. +       for (int i = 0; i < buttonscount; i++)
  278. +       {
  279. +           int next = _randomize.nextInt(imagescount);
  280. +           while (container.options.indexOf(next) > -1)
  281. +           {
  282. +               next = _randomize.nextInt(imagescount);
  283. +           }
  284. +           container.options.add(next);
  285. +       }
  286. +              
  287. +       int mainIndex = _randomize.nextInt(buttonscount);
  288. +       container.mainpattern = mainIndex; 
  289. +      
  290. +       Calendar token =  Calendar.getInstance();
  291. +       String uniquetoken = Integer.toString(token.get(Calendar.DAY_OF_MONTH))+Integer.toString(token.get(Calendar.HOUR_OF_DAY))+Integer.toString(token.get(Calendar.MINUTE))+Integer.toString(token.get(Calendar.SECOND))+Integer.toString(token.get(Calendar.MILLISECOND)/100);
  292. +       container.patternid = Integer.parseInt(uniquetoken);   
  293. +   }
  294. +  
  295. +   protected void banpunishment(L2PcInstance player)
  296. +   {
  297. +       _validation.remove(player.getObjectId());
  298. +       _beginvalidation.get(player.getObjectId()).cancel(true);
  299. +       _beginvalidation.remove(player.getObjectId());
  300. +      
  301. +       switch (Config.PUNISHMENT)
  302. +       {
  303. +       // 0 = move character to the closest village.
  304. +       // 1 = kick characters from the server.
  305. +       // 2 = put character to jail.
  306. +       // 3 = ban character from the server.
  307. +           case 0:
  308. +               player.stopMove(null);
  309. +               player.teleToLocation(MapRegionTable.TeleportWhereType.Town);
  310. +               punishmentnwindow(player);
  311. +               break;
  312. +           case 1:
  313. +               if (player.isOnline())
  314. +               {
  315. +                   player.logout(true);
  316. +               }
  317. +               break;
  318. +           case 2:
  319. +               jailpunishment(player, Config.PUNISHMENT_TIME * 60);
  320. +               break;
  321. +           case 3:
  322. +               //player.setAccessLevel(-100);
  323. +               changeaccesslevel(player, -100);
  324. +               break;
  325. +       }
  326. +      
  327. +       player.sendMessage("Unfortunately, colours doesn't match.");
  328. +   }
  329. +  
  330. +   private static void changeaccesslevel(L2PcInstance targetPlayer, int lvl)
  331. +   {
  332. +       if (targetPlayer.isOnline())
  333. +       {
  334. +           targetPlayer.setAccessLevel(lvl);
  335. +           targetPlayer.logout();
  336. +       }
  337. +       else
  338. +       {
  339. +           try (Connection con = L2DatabaseFactory.getInstance().getConnection())
  340. +           {
  341. +               PreparedStatement statement = con.prepareStatement("UPDATE characters SET accesslevel=? WHERE obj_id=?");
  342. +               statement.setInt(1, lvl);
  343. +               statement.setInt(2, targetPlayer.getObjectId());
  344. +               statement.execute();
  345. +               statement.close();
  346. +           }
  347. +           catch (SQLException se)
  348. +           {
  349. +               if (Config.DEBUG)
  350. +                   se.printStackTrace();
  351. +           }
  352. +       }
  353. +   }
  354. +  
  355. +   private static void jailpunishment(L2PcInstance activeChar, int delay)
  356. +   {
  357. +       if (activeChar.isOnline())
  358. +       {
  359. +           activeChar.setPunishLevel(L2PcInstance.PunishLevel.JAIL, Config.PUNISHMENT_TIME);
  360. +       }
  361. +       else
  362. +       {
  363. +           try (Connection con = L2DatabaseFactory.getInstance().getConnection())
  364. +           {
  365. +               PreparedStatement statement = con.prepareStatement("UPDATE characters SET x=?, y=?, z=?, punish_level=?, punish_timer=? WHERE obj_id=?");
  366. +               statement.setInt(1, -114356);
  367. +               statement.setInt(2, -249645);
  368. +               statement.setInt(3, -2984);
  369. +               statement.setInt(4, L2PcInstance.PunishLevel.JAIL.value());
  370. +               statement.setLong(5, (delay > 0 ? delay * Config.PUNISHMENT_TIME * 100 : 0));
  371. +               statement.setInt(6, activeChar.getObjectId());
  372. +              
  373. +               statement.execute();
  374. +               statement.close();
  375. +           }
  376. +           catch (SQLException se)
  377. +           {
  378. +               activeChar.sendMessage("SQLException while jailing player");
  379. +               if (Config.DEBUG)
  380. +                   se.printStackTrace();
  381. +           }
  382. +       }
  383. +   }
  384. +  
  385. +   public void AnalyseBypass(String command, L2PcInstance player)
  386. +   {
  387. +       if (!_validation.containsKey(player.getObjectId()))
  388. +           return;
  389. +      
  390. +       String params = command.substring(command.indexOf("_") + 1);
  391. +      
  392. +       if (params.startsWith("continue"))
  393. +       {
  394. +           validationwindow(player);
  395. +           _validation.get(player.getObjectId()).firstWindow = false;
  396. +           return;
  397. +       }
  398. +      
  399. +       int choosenoption = -1;
  400. +       if (tryParseInt(params))
  401. +       {
  402. +           choosenoption = Integer.parseInt(params);
  403. +       }
  404. +      
  405. +       if (choosenoption > -1)
  406. +       {
  407. +           PlayerData playerData = _validation.get(player.getObjectId());
  408. +           if (choosenoption != playerData.mainpattern)
  409. +           {
  410. +               banpunishment(player);
  411. +           }
  412. +           else
  413. +           {
  414. +               player.sendMessage("Congratulations, colours match!");
  415. +               _validation.remove(player.getObjectId());
  416. +               _beginvalidation.get(player.getObjectId()).cancel(true);
  417. +               _beginvalidation.remove(player.getObjectId());
  418. +           }
  419. +       }
  420. +   }
  421. +  
  422. +   protected class countdown implements Runnable
  423. +   {
  424. +       private final L2PcInstance _player;
  425. +       private int _time;
  426. +      
  427. +       public countdown(L2PcInstance player, int time)
  428. +       {
  429. +           _time = time;
  430. +           _player = player;
  431. +       }
  432. +      
  433. +       @Override
  434. +       public void run()
  435. +       {
  436. +           if (_player.isOnline())
  437. +           {
  438. +               if (_validation.containsKey(_player.getObjectId()) && _validation.get(_player.getObjectId()).firstWindow)
  439. +               {
  440. +                   if (_time % WINDOW_DELAY == 0)
  441. +                   {
  442. +                       prevalidationwindow(_player);
  443. +                   }
  444. +               }
  445. +              
  446. +               switch (_time)
  447. +               {
  448. +                   case 300:
  449. +                   case 240:
  450. +                   case 180:
  451. +                   case 120:
  452. +                   case 60:
  453. +                       _player.sendMessage(_time / 60 + " minute(s) to match colors.");
  454. +                       break;
  455. +                   case 30:
  456. +                   case 10:
  457. +                   case 5:
  458. +                   case 4:
  459. +                   case 3:
  460. +                   case 2:
  461. +                   case 1:
  462. +                       _player.sendMessage(_time + " second(s) to match colors!");
  463. +                       break;
  464. +               }
  465. +               if (_time > 1 && _validation.containsKey(_player.getObjectId()))
  466. +               {
  467. +                   ThreadPoolManager.getInstance().scheduleGeneral(new countdown(_player, _time - 1), 1000);
  468. +               }
  469. +           }
  470. +       }
  471. +   }
  472. +  
  473. +   protected boolean tryParseInt(String value)
  474. +   {
  475. +       try
  476. +       {
  477. +           Integer.parseInt(value);
  478. +           return true;
  479. +       }
  480. +      
  481. +       catch (NumberFormatException e)
  482. +       {
  483. +           return false;
  484. +       }
  485. +   }
  486. +  
  487. +   public void CaptchaSuccessfull(L2PcInstance player)
  488. +   {
  489. +       if (_validation.get(player.getObjectId()) != null)
  490. +       {
  491. +           _validation.remove(player.getObjectId());
  492. +       }
  493. +   }
  494. +  
  495. +   public Boolean IsAlredyInReportMode(L2PcInstance player)
  496. +   {
  497. +       if (_validation.get(player.getObjectId()) != null)
  498. +       {
  499. +           return true;
  500. +       }
  501. +       return false;
  502. +   }
  503. +  
  504. +   private class ReportCheckTask implements Runnable
  505. +   {
  506. +       private final L2PcInstance _player;
  507. +      
  508. +       public ReportCheckTask(L2PcInstance player)
  509. +       {
  510. +           _player = player;
  511. +       }
  512. +      
  513. +       @Override
  514. +       public void run()
  515. +       {
  516. +           if (_validation.get(_player.getObjectId()) != null)
  517. +           {
  518. +               banpunishment(_player);
  519. +           }
  520. +       }
  521. +   }
  522. +  
  523. +   private static class SingletonHolder
  524. +   {
  525. +       protected static final BotsPreventionManager _instance = new BotsPreventionManager();
  526. +   }
  527. +}
  528. Index: trunk/aCis_gameserver/java/net/sf/l2j/gameserver/model/actor/L2Character.java
  529. ===================================================================
  530. --- trunk/aCis_gameserver/java/net/sf/l2j/gameserver/model/actor/L2Character.java   (revision 427)
  531. +++ trunk/aCis_gameserver/java/net/sf/l2j/gameserver/model/actor/L2Character.java   (revision 428)
  532. @@ -41 +42 @@
  533. -import net.sf.l2j.gameserver.handler.SkillHandler;
  534. +import net.sf.l2j.gameserver.handler.SkillHandler;
  535. +import net.sf.l2j.gameserver.instancemanager.BotsPreventionManager;
  536. @@ -1613 +1613 @@
  537. -       calculateRewards(killer);
  538. +       calculateRewards(killer);
  539. +       if (Config.BOTS_PREVENTION)
  540. +       {
  541. +           BotsPreventionManager.getInstance().updatecounter(killer,this);
  542. +       }
  543. +
  544. Index: trunk/aCis_gameserver/java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java
  545. ===================================================================
  546. --- trunk/aCis_gameserver/java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java   (revision 427)
  547. +++ trunk/aCis_gameserver/java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java   (revision 428)
  548. @@ -24 +24 @@
  549. -import net.sf.l2j.gameserver.handler.IAdminCommandHandler;
  550. +import net.sf.l2j.gameserver.handler.IAdminCommandHandler;
  551. +import net.sf.l2j.gameserver.instancemanager.BotsPreventionManager;
  552. @@ -166 +166 @@
  553. -           else if (_command.startsWith("arenachange")) // change
  554. -           {
  555. -               final boolean isManager = activeChar.getCurrentFolkNPC() instanceof L2OlympiadManagerInstance;
  556. -               if (!isManager)
  557. -               {
  558. -                   // Without npc, command can be used only in observer mode on arena
  559. -                   if (!activeChar.inObserverMode() || activeChar.isInOlympiadMode() || activeChar.getOlympiadGameId() < 0)
  560. -                       return;
  561. -               }
  562. -              
  563. -               if (OlympiadManager.getInstance().isRegisteredInComp(activeChar))
  564. -               {
  565. -                   activeChar.sendPacket(SystemMessageId.WHILE_YOU_ARE_ON_THE_WAITING_LIST_YOU_ARE_NOT_ALLOWED_TO_WATCH_THE_GAME);
  566. -                   return;
  567. -               }
  568. -              
  569. -               final int arenaId = Integer.parseInt(_command.substring(12).trim());
  570. -               activeChar.enterOlympiadObserverMode(arenaId);
  571. -           }
  572. +           else if (_command.startsWith("arenachange")) // change
  573. +           {
  574. +               final boolean isManager = activeChar.getCurrentFolkNPC() instanceof L2OlympiadManagerInstance;
  575. +               if (!isManager)
  576. +               {
  577. +                   // Without npc, command can be used only in observer mode on arena
  578. +                   if (!activeChar.inObserverMode() || activeChar.isInOlympiadMode() || activeChar.getOlympiadGameId() < 0)
  579. +                       return;
  580. +               }
  581. +              
  582. +               if (OlympiadManager.getInstance().isRegisteredInComp(activeChar))
  583. +               {
  584. +                   activeChar.sendPacket(SystemMessageId.WHILE_YOU_ARE_ON_THE_WAITING_LIST_YOU_ARE_NOT_ALLOWED_TO_WATCH_THE_GAME);
  585. +                   return;
  586. +               }
  587. +              
  588. +               final int arenaId = Integer.parseInt(_command.substring(12).trim());
  589. +               activeChar.enterOlympiadObserverMode(arenaId);
  590. +           }
  591. +           else if (_command.startsWith("report"))
  592. +           {
  593. +               BotsPreventionManager.getInstance().AnalyseBypass(_command,activeChar);
  594. +           }
  595. +
  596. Index: trunk/aCis_gameserver/java/net/sf/l2j/gameserver/network/serverpackets/PledgeCrest.java
  597. ===================================================================
  598. --- trunk/aCis_gameserver/java/net/sf/l2j/gameserver/network/serverpackets/PledgeCrest.java (revision 427)
  599. +++ trunk/aCis_gameserver/java/net/sf/l2j/gameserver/network/serverpackets/PledgeCrest.java (revision 428)
  600. @@ -29 +29 @@
  601. -   }
  602. -  
  603. -   @Override
  604. -   protected final void writeImpl()
  605. +   }
  606. +  
  607. +   public PledgeCrest(int crestId, byte[] data)
  608. +   {
  609. +       _crestId = crestId;
  610. +       _data = data;
  611. +   }
  612. +  
  613. +   @Override
  614. +   protected final void writeImpl()
  615. +