### Eclipse Workspace Patch 1.0
#P aCis_gameserver
Index: java/net/sf/l2j/gameserver/datatables/AntiBotTable.java
===================================================================
--- java/net/sf/l2j/gameserver/datatables/AntiBotTable.java (revision 0)
+++ java/net/sf/l2j/gameserver/datatables/AntiBotTable.java (revision 0)
@@ -0,0 +1,183 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.datatables;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import net.sf.l2j.gameserver.ThreadPoolManager;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.network.serverpackets.PledgeImage;
+import net.sf.l2j.util.Rnd;
+
+/**
+ *
+ * @author Fissban
+ *
+ */
+public class AntiBotTable
+{
+ public static Logger _log = Logger.getLogger(AntiBotTable.class.getName());
+
+ public static Map<Integer, antiBotData> _imageAntiBotOri = new HashMap<>();
+ public static Map<Integer, antiBotData> _imageAntiBotClient = new HashMap<>();
+
+ public final static int[] img_antibot_id =
+ {
+ 7000, 7001, 7002, 7003, 7004, 7005, 7006, 7007, 7008, 7009
+ };
+
+ public void loadImage()
+ {
+ LoadImgAntiBot();
+ _log.log(Level.INFO, "loading " + _imageAntiBotOri.size() + " images of AntiBot");
+ }
+
+ private static void LoadImgAntiBot()
+ {
+ _imageAntiBotOri.clear();
+ int cont = 0;
+
+ for (int imgId : img_antibot_id)
+ {
+ File image = new File("data/images/antibot/" + imgId + ".dds");
+ _imageAntiBotOri.put(cont, new antiBotData(cont, ConverterImgBytes(image)));
+ cont++;
+ }
+
+ ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new startEncriptCaptcha(), 100, 600000); // 10 Minutes
+ }
+
+ public void sendImage(L2PcInstance player, int imgId)
+ {
+ PledgeImage packet = null;
+
+ if ((imgId >= 50000) && (imgId <= 800000))
+ {
+ for (Entry<Integer, antiBotData> entrySet : _imageAntiBotClient.entrySet())
+ {
+ antiBotData imgCoding = entrySet.getValue();
+
+ if (imgId == imgCoding.getCodificacion())
+ {
+ packet = new PledgeImage(imgId, imgCoding.getImagen());
+ }
+ }
+ }
+
+ player.sendPacket(packet);
+ }
+
+ public static class startEncriptCaptcha implements Runnable
+ {
+ public startEncriptCaptcha()
+ {
+
+ }
+
+ @Override
+ public void run()
+ {
+ _imageAntiBotClient.clear();
+
+ for (Entry<Integer, antiBotData> entrySet : _imageAntiBotOri.entrySet())
+ {
+ entrySet.getValue().getImagen();
+ _imageAntiBotClient.put(entrySet.getKey(), new antiBotData(Rnd.get(50000, 800000), entrySet.getValue().getImagen()));
+ }
+ }
+ }
+
+ public int getAntiBotClientID(int pos)
+ {
+ int returnCoding = 0;
+
+ for (Entry<Integer, antiBotData> entrySet : _imageAntiBotClient.entrySet())
+ {
+ int numeroImage = entrySet.getKey().intValue();
+
+ if (pos == numeroImage)
+ {
+ antiBotData imgCoding = entrySet.getValue();
+ returnCoding = imgCoding.getCodificacion();
+ }
+
+ if (pos > 9)
+ {
+ _log.log(Level.SEVERE, "error in getAntiBotClientID...number dont exist");
+ }
+ }
+ return returnCoding;
+ }
+
+ public static class antiBotData
+ {
+ int _codificacion;
+ byte[] _data;
+
+ public antiBotData(int codificacion, byte[] data)
+ {
+ _codificacion = codificacion;
+ _data = data;
+ }
+
+ public int getCodificacion()
+ {
+ return _codificacion;
+ }
+
+ public byte[] getImagen()
+ {
+ return _data;
+ }
+ }
+
+ private static byte[] ConverterImgBytes(File imagen)
+ {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ byte[] buffer = new byte[1024];
+ try (FileInputStream fis = new FileInputStream(imagen))
+ {
+ for (int readNum; (readNum = fis.read(buffer)) != -1;)
+ {
+ bos.write(buffer, 0, readNum);
+ }
+ }
+ catch (IOException e)
+ {
+ _log.log(Level.SEVERE, "Error when converter image to byte[]");
+ }
+
+ return bos.toByteArray();
+ }
+
+ public static AntiBotTable getInstance()
+ {
+ return SingletonHolder._instance;
+ }
+
+ private static class SingletonHolder
+ {
+ protected static final AntiBotTable _instance = new AntiBotTable();
+ }
+}
Index: java/net/sf/l2j/gameserver/GameServer.java
===================================================================
--- java/net/sf/l2j/gameserver/GameServer.java (revision 13)
+++ java/net/sf/l2j/gameserver/GameServer.java (working copy)
@@ -35,6 +35,7 @@
import net.sf.l2j.gameserver.communitybbs.Manager.ForumsBBSManager;
import net.sf.l2j.gameserver.datatables.AccessLevels;
import net.sf.l2j.gameserver.datatables.AdminCommandAccessRights;
+import net.sf.l2j.gameserver.datatables.AntiBotTable;
import net.sf.l2j.gameserver.datatables.ArmorSetsTable;
import net.sf.l2j.gameserver.datatables.AugmentationData;
import net.sf.l2j.gameserver.datatables.BookmarkTable;
@@ -309,6 +310,8 @@
MovieMakerManager.getInstance();
+ AntiBotTable.getInstance().loadImage();
+
if (Config.DEADLOCK_DETECTOR)
{
_log.info("Deadlock detector is enabled. Timer: " + Config.DEADLOCK_CHECK_INTERVAL + "s.");
Index: java/net/sf/l2j/Config.java
===================================================================
--- java/net/sf/l2j/Config.java (revision 13)
+++ java/net/sf/l2j/Config.java (working copy)
@@ -513,6 +513,13 @@
public static boolean STORE_SKILL_COOLTIME;
public static int BUFFS_MAX_AMOUNT;
+ /** AntiBot */
+ public static boolean ANTIBOT_ENABLE;
+ public static int ANTIBOT_TIME_JAIL;
+ public static int ANTIBOT_TIME_VOTE;
+ public static int ANTIBOT_KILL_MOBS;
+ public static int ANTIBOT_MIN_LEVEL;
+
// --------------------------------------------------
// Server
// --------------------------------------------------
@@ -1110,6 +1117,12 @@
BUFFS_MAX_AMOUNT = players.getProperty("MaxBuffsAmount", 20);
STORE_SKILL_COOLTIME = players.getProperty("StoreSkillCooltime", true);
+ ANTIBOT_ENABLE = players.getProperty("AntiBotEnable", true);
+ ANTIBOT_TIME_JAIL = players.getProperty("AntiBotTimeJail", 1);
+ ANTIBOT_TIME_VOTE = players.getProperty("AntiBotTimeVote", 30);
+ ANTIBOT_KILL_MOBS = players.getProperty("AntiBotKillMobs", 1);
+ ANTIBOT_MIN_LEVEL = players.getProperty("AntiBotMinLevel", 1);
+
// server
ExProperties server = load(SERVER_FILE);
Index: java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java
===================================================================
--- java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java (revision 13)
+++ java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java (working copy)
@@ -179,6 +179,18 @@
final int arenaId = Integer.parseInt(_command.substring(12).trim());
activeChar.enterOlympiadObserverMode(arenaId);
}
+ else if (_command.startsWith("antibot"))
+ {
+ StringTokenizer st = new StringTokenizer(_command);
+ st.nextToken();
+
+ if (st.hasMoreTokens())
+ {
+ activeChar.checkCode(st.nextToken());
+ return;
+ }
+ activeChar.checkCode("Fail");
+ }
}
catch (Exception e)
{
Index: java/net/sf/l2j/gameserver/network/clientpackets/Say2.java
===================================================================
--- java/net/sf/l2j/gameserver/network/clientpackets/Say2.java (revision 13)
+++ java/net/sf/l2j/gameserver/network/clientpackets/Say2.java (working copy)
@@ -49,6 +49,7 @@
public final static int PARTYROOM_COMMANDER = 15; // (Yellow)
public final static int PARTYROOM_ALL = 16; // (Red)
public final static int HERO_VOICE = 17;
+ public final static int CRITICAL_ANNOUNCE = 18;
private final static String[] CHAT_NAMES =
{
@@ -69,7 +70,8 @@
"PARTYMATCH_ROOM",
"PARTYROOM_COMMANDER",
"PARTYROOM_ALL",
- "HERO_VOICE"
+ "HERO_VOICE",
+ "CRITICAL_ANNOUNCE"
};
private static final String[] WALKER_COMMAND_LIST =
Index: java/net/sf/l2j/gameserver/network/serverpackets/PledgeImage.java
===================================================================
--- java/net/sf/l2j/gameserver/network/serverpackets/PledgeImage.java (revision 0)
+++ java/net/sf/l2j/gameserver/network/serverpackets/PledgeImage.java (revision 0)
@@ -0,0 +1,44 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.network.serverpackets;
+
+public class PledgeImage extends L2GameServerPacket
+{
+ private final int _crestId;
+ private final byte[] _data;
+
+ public PledgeImage(int crestId, byte[] data)
+ {
+ _crestId = crestId;
+ _data = data;
+ }
+
+ @Override
+ protected final void writeImpl()
+ {
+ writeC(0x6c);
+ writeD(_crestId);
+
+ if (_data != null)
+ {
+ writeD(_data.length);
+ writeB(_data);
+ }
+ else
+ {
+ writeD(0);
+ }
+ }
+}
\ No newline at end of file
Index: java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java
===================================================================
--- java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java (revision 13)
+++ java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java (working copy)
@@ -48,6 +48,7 @@
import net.sf.l2j.gameserver.communitybbs.BB.Forum;
import net.sf.l2j.gameserver.communitybbs.Manager.ForumsBBSManager;
import net.sf.l2j.gameserver.datatables.AccessLevels;
+import net.sf.l2j.gameserver.datatables.AntiBotTable;
import net.sf.l2j.gameserver.datatables.CharNameTable;
import net.sf.l2j.gameserver.datatables.CharTemplateTable;
import net.sf.l2j.gameserver.datatables.ClanTable;
@@ -157,12 +158,14 @@
import net.sf.l2j.gameserver.model.zone.type.L2BossZone;
import net.sf.l2j.gameserver.network.L2GameClient;
import net.sf.l2j.gameserver.network.SystemMessageId;
+import net.sf.l2j.gameserver.network.clientpackets.Say2;
import net.sf.l2j.gameserver.network.serverpackets.AbstractNpcInfo;
import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
import net.sf.l2j.gameserver.network.serverpackets.ChairSit;
import net.sf.l2j.gameserver.network.serverpackets.ChangeWaitType;
import net.sf.l2j.gameserver.network.serverpackets.CharInfo;
import net.sf.l2j.gameserver.network.serverpackets.ConfirmDlg;
+import net.sf.l2j.gameserver.network.serverpackets.CreatureSay;
import net.sf.l2j.gameserver.network.serverpackets.EtcStatusUpdate;
import net.sf.l2j.gameserver.network.serverpackets.ExAutoSoulShot;
import net.sf.l2j.gameserver.network.serverpackets.ExDuelUpdateUserInfo;
@@ -170,6 +173,7 @@
import net.sf.l2j.gameserver.network.serverpackets.ExFishingStart;
import net.sf.l2j.gameserver.network.serverpackets.ExOlympiadMode;
import net.sf.l2j.gameserver.network.serverpackets.ExSetCompassZoneCode;
+import net.sf.l2j.gameserver.network.serverpackets.ExShowScreenMessage;
import net.sf.l2j.gameserver.network.serverpackets.ExStorageMaxCount;
import net.sf.l2j.gameserver.network.serverpackets.FriendList;
import net.sf.l2j.gameserver.network.serverpackets.GetOnVehicle;
@@ -219,6 +223,7 @@
import net.sf.l2j.gameserver.network.serverpackets.TradePressOwnOk;
import net.sf.l2j.gameserver.network.serverpackets.TradeStart;
import net.sf.l2j.gameserver.network.serverpackets.UserInfo;
+import net.sf.l2j.gameserver.skills.AbnormalEffect;
import net.sf.l2j.gameserver.skills.Env;
import net.sf.l2j.gameserver.skills.Formulas;
import net.sf.l2j.gameserver.skills.Stats;
@@ -364,6 +369,11 @@
}
}
+ private String _code = "";
+ private int _attempt = 0;
+ private int _mobs_dead = 0;
+ public static ScheduledFuture<?> _antiBotTask;
+
private L2GameClient _client;
private String _accountName;
@@ -10647,4 +10657,183 @@
}
}
}
+
+ // AntiBoot
+ public void antibot()
+ {
+ increaseMobsDead();
+
+ if (getMobsDead() >= Config.ANTIBOT_KILL_MOBS)
+ {
+ resetMobsDead();
+ _antiBotTask = ThreadPoolManager.getInstance().scheduleGeneral(new startAntiBotTask(), Config.ANTIBOT_TIME_VOTE * 1000);
+ }
+ }
+
+ private static void stopAntiBotTask()
+ {
+ if (_antiBotTask != null)
+ {
+ _antiBotTask.cancel(false);
+ _antiBotTask = null;
+ }
+ }
+
+ private class startAntiBotTask implements Runnable
+ {
+ public startAntiBotTask()
+ {
+ setIsParalyzed(true);
+ setIsInvul(true);
+ startAbnormalEffect(AbnormalEffect.FLOATING_ROOT);
+ sendPacket(new ExShowScreenMessage("[AntiBot]: You have " + Config.ANTIBOT_TIME_VOTE + " to confirm the Captcha!", 10000));
+ getActingPlayer().sendPacket(new CreatureSay(0, Say2.CRITICAL_ANNOUNCE, "[AntiBot]:", "You have " + Config.ANTIBOT_TIME_VOTE + " to confirm the Catpcha."));
+ showHtml_Start();
+ }
+
+ @Override
+ public void run()
+ {
+ if (!isInJail())
+ {
+ sendPacket(new CreatureSay(0, Say2.HERO_VOICE, "[AntiBot]:", "Your time limit has elapsed."));
+ increaseAttempt();
+
+ if (getAttempt() >= 3)
+ {
+ setIsParalyzed(false);
+ setIsInvul(false);
+ startAbnormalEffect(AbnormalEffect.FLOATING_ROOT);
+ getActingPlayer().setPunishLevel(L2PcInstance.PunishLevel.JAIL, Config.ANTIBOT_TIME_JAIL);
+ getActingPlayer().sendPacket(new CreatureSay(0, Say2.HERO_VOICE, "[AntiBot]:", "Character " + getName() + " jailed for " + Config.ANTIBOT_TIME_JAIL + " minutes."));
+ _log.warning("[AntiBot]: Character " + getName() + " jailed for " + Config.ANTIBOT_TIME_JAIL + " minutes.");
+ }
+ else
+ {
+ _antiBotTask = ThreadPoolManager.getInstance().scheduleGeneral(new startAntiBotTask(), Config.ANTIBOT_TIME_VOTE * 1000);
+ }
+ }
+ }
+ }
+
+ public String num2img(int numero)
+ {
+ String num = Integer.toString(numero);
+ char[] digitos = num.toCharArray();
+
+ String tmp = "";
+ for(int x=0;x<num.length();x++)
+ {
+ int dig = Integer.parseInt(Character.toString(digitos[x]));
+ final int it = AntiBotTable.getInstance().getAntiBotClientID(dig);
+ AntiBotTable.getInstance().sendImage(this, it);
+ tmp += "<img src=Crest.crest_" + Config.SERVER_ID + "_" + it + " width=38 height=33 align=left>";
+ }
+
+ return tmp;
+ }
+
+ public void showHtml_Start()
+ {
+ NpcHtmlMessage html = new NpcHtmlMessage(0);
+ html.setFile("data/html/antiBot/start.htm");
+
+ html.replace("%playerName%", getName());
+ html.replace("%attemp%", String.valueOf(3 - getAttempt()));
+ int maxR = 3;
+
+ String random = new String();
+
+ for(int x = 0; x<maxR; x++)
+ random += Integer.toString(Rnd.get(0,9));
+
+ html.replace("%code1%",num2img(Integer.parseInt(random)));
+
+ this.sendPacket(html);
+ setCode(String.valueOf(Integer.parseInt(random)));
+ }
+
+ public void showHtml_End()
+ {
+ NpcHtmlMessage html = new NpcHtmlMessage(0);
+ html.setFile("data/html/antiBot/end.htm");
+ html.replace("%playerName%", getName());
+
+ this.sendPacket(html);
+ }
+
+ public void checkCode(String code)
+ {
+ if (code.equals(getCode()))
+ {
+ stopAntiBotTask();
+ resetAttempt();
+
+ sendPacket(new CreatureSay(0, Say2.HERO_VOICE, "[AntiBot]:", "Congratulations, has passed control."));
+ setIsParalyzed(false);
+ setIsInvul(false);
+ stopAbnormalEffect(AbnormalEffect.FLOATING_ROOT);
+ }
+ else
+ {
+ stopAntiBotTask();
+ increaseAttempt();
+
+ _antiBotTask = ThreadPoolManager.getInstance().scheduleGeneral(new startAntiBotTask(), Config.ANTIBOT_TIME_VOTE * 1000);
+ }
+
+ if (getAttempt() >= 3)
+ {
+ stopAntiBotTask();
+ resetAttempt();
+
+ setIsParalyzed(false);
+ setIsInvul(false);
+ startAbnormalEffect(AbnormalEffect.FLOATING_ROOT);
+
+ setPunishLevel(PunishLevel.JAIL, Config.ANTIBOT_TIME_JAIL);
+ sendPacket(new CreatureSay(0, Say2.HERO_VOICE, "[AntiBot]:", "Character " + getName() + " jailed for " + Config.ANTIBOT_TIME_JAIL + " minutes."));
+ _log.warning("[AntiBot]: Character " + getName() + " jailed for " + Config.ANTIBOT_TIME_JAIL + " minutes.");
+ }
+ }
+
+ private int getMobsDead()
+ {
+ return _mobs_dead;
+ }
+
+ private void increaseMobsDead()
+ {
+ _mobs_dead++;
+ }
+
+ private void resetMobsDead()
+ {
+ _mobs_dead = 0;
+ }
+
+ private void setCode(String code)
+ {
+ _code = code;
+ }
+
+ private String getCode()
+ {
+ return _code;
+ }
+
+ public void increaseAttempt()
+ {
+ _attempt += 1;
+ }
+
+ public int getAttempt()
+ {
+ return _attempt;
+ }
+
+ public void resetAttempt()
+ {
+ _attempt = 0;
+ }
}
\ No newline at end of file
Index: java/net/sf/l2j/gameserver/model/actor/L2Attackable.java
===================================================================
--- java/net/sf/l2j/gameserver/model/actor/L2Attackable.java (revision 13)
+++ java/net/sf/l2j/gameserver/model/actor/L2Attackable.java (working copy)
@@ -450,6 +450,12 @@
if (!super.doDie(killer))
return false;
+ // AntiBot
+ if (Config.ANTIBOT_ENABLE && (killer != null) && killer instanceof L2PcInstance && (killer.getLevel() >= Config.ANTIBOT_MIN_LEVEL))
+ {
+ killer.getActingPlayer().antibot();
+ }
+
// Notify the Quest Engine of the L2Attackable death if necessary
try
{
Index: config/players.properties
===================================================================
--- config/players.properties (revision 13)
+++ config/players.properties (working copy)
@@ -294,4 +294,23 @@
MaxBuffsAmount = 20
# Store buffs/debuffs on user logout?
-StoreSkillCooltime = True
\ No newline at end of file
+StoreSkillCooltime = True
+
+#=============================================================
+# AntiBot
+#=============================================================
+
+# AntiBot. True to enable, False to disable.
+AntiBotEnable = True
+
+# Time the user will be in jail in minutes.
+AntiBotTimeJail = 10
+
+# Time that the user will have to control captcha in seconds.
+AntiBotTimeVote = 40
+
+# Dead mobs needed for captcha.
+AntiBotKillMobs = 100
+
+# Level min need for captcha.
+AntiBotMinLevel = 1
\ No newline at end of file