Código:
Index: java/com/l2jserver/Config.java
===================================================================
--- java/com/l2jserver/Config.java (revision 3970)
+++ java/com/l2jserver/Config.java (working copy)
@@ -543,6 +543,7 @@
public static boolean CUSTOM_DROPLIST_TABLE;
public static boolean CUSTOM_MERCHANT_TABLES;
public static boolean CUSTOM_NPCBUFFER_TABLES;
+ public static boolean ENABLE_BOTREPORT;
//--------------------------------------------------
@@ -658,6 +659,9 @@
public static String ANNOUNCE_PK_MSG;
public static String ANNOUNCE_PVP_MSG;
public static boolean L2JMOD_CHAT_ADMIN;
+
+ public static boolean ENABLE_CHAR_CREATE_TITLE;
+ public static String CHAR_CREATE_TITLE;
//--------------------------------------------------
// NPC Settings
@@ -1727,6 +1731,7 @@
CUSTOM_DROPLIST_TABLE = Boolean.valueOf(General.getProperty("CustomDroplistTable", "false"));
CUSTOM_MERCHANT_TABLES = Boolean.valueOf(General.getProperty("CustomMerchantTables", "false"));
CUSTOM_NPCBUFFER_TABLES = Boolean.valueOf(General.getProperty("CustomNpcBufferTables", "false"));
+ ENABLE_BOTREPORT = Boolean.valueOf(General.getProperty("EnableBotReport", "false"));
}
catch (Exception e)
{
@@ -2173,6 +2178,9 @@
ANNOUNCE_PVP_MSG = L2JModSettings.getProperty("AnnouncePvpMsg", "$killer has defeated $target");
L2JMOD_CHAT_ADMIN = Boolean.parseBoolean(L2JModSettings.getProperty("ChatAdmin", "false"));
+
+ ENABLE_CHAR_CREATE_TITLE = Boolean.parseBoolean(L2JModSettings.getProperty("EnableCharCreateTitle", "False"));
+ CHAR_CREATE_TITLE = L2JModSettings.getProperty("CharCreateTitle", "");
}
catch (Exception e)
{
@@ -2818,6 +2826,7 @@
else if (pName.equalsIgnoreCase("GlobalChat")) DEFAULT_GLOBAL_CHAT = pValue;
else if (pName.equalsIgnoreCase("TradeChat")) DEFAULT_TRADE_CHAT = pValue;
else if (pName.equalsIgnoreCase("GMAdminMenuStyle")) GM_ADMIN_MENU_STYLE = pValue;
+ else if (pName.equalsIgnoreCase("EnableBotReport")) ENABLE_BOTREPORT = Boolean.parseBoolean(pValue);
else return false;
return true;
}
Index: java/com/l2jserver/gameserver/GameServer.java
===================================================================
--- java/com/l2jserver/gameserver/GameServer.java (revision 3970)
+++ java/com/l2jserver/gameserver/GameServer.java (working copy)
@@ -83,6 +83,7 @@
import com.l2jserver.gameserver.instancemanager.AirShipManager;
import com.l2jserver.gameserver.instancemanager.AuctionManager;
import com.l2jserver.gameserver.instancemanager.BoatManager;
+import com.l2jserver.gameserver.instancemanager.BotManager;
import com.l2jserver.gameserver.instancemanager.CastleManager;
import com.l2jserver.gameserver.instancemanager.CastleManorManager;
import com.l2jserver.gameserver.instancemanager.ClanHallManager;
@@ -260,7 +261,8 @@
SiegeManager.getInstance().getSieges();
FortManager.getInstance().loadInstances();
FortSiegeManager.getInstance();
-
+ if(Config.ENABLE_BOTREPORT)
+ BotManager.getInstance();
TeleportLocationTable.getInstance();
LevelUpData.getInstance();
L2World.getInstance();
Index: java/com/l2jserver/gameserver/instancemanager/BotManager.java
===================================================================
--- java/com/l2jserver/gameserver/instancemanager/BotManager.java (revision 0)
+++ java/com/l2jserver/gameserver/instancemanager/BotManager.java (revision 0)
@@ -0,0 +1,532 @@
+/*
+ * 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 com.l2jserver.gameserver.instancemanager;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.Calendar;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import javolution.util.FastList;
+import javolution.util.FastMap;
+
+import com.l2jserver.L2DatabaseFactory;
+import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.model.L2Account;
+import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.network.SystemMessageId;
+import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.gameserver.util.BotPunish;
+
+/**
+ * @author BiggBoss
+ *
+ */
+public class BotManager
+{
+ private static final Logger _log = Logger.getLogger(BotManager.class.getName());
+
+ private static FastMap<Integer, String[]> _unread;
+ // Number of reportes made over each player
+ private static FastMap<Integer, FastList<L2PcInstance>> _reportedCount = new FastMap<Integer, FastList<L2PcInstance>>();
+ // Reporters blocked by time
+ private static FastMap<Integer, Long> _lockedReporters = new FastMap<Integer, Long>();
+ // Blocked ips
+ private static Set<String> _lockedIps = new HashSet<String>();
+ // Blocked accounts
+ private static Set<String> _lockedAccounts = new HashSet<String>();
+
+ private BotManager()
+ {
+ loadUnread();
+ }
+
+ public static BotManager getInstance()
+ {
+ return SingletonHolder._instance;
+ }
+
+ /**
+ * Check if the reported player is online
+ * @param reportedId
+ * @return true if L2World contains that player, else returns false
+ */
+ private static boolean reportedIsOnline(L2PcInstance player)
+ {
+ return L2World.getInstance().getPlayer(player.getObjectId()) != null;
+ }
+
+ /**
+ * Will save the report in database
+ * @param reported (the L2PcInstance who was reported)
+ * @param reporter (the L2PcInstance who reported the bot)
+ */
+ public synchronized void reportBot(L2PcInstance reported, L2PcInstance reporter)
+ {
+ if (!reportedIsOnline(reported))
+ {
+ reporter.sendMessage("The player you are reporting is offline.");
+ return;
+ }
+
+ _lockedReporters.put(reporter.getObjectId(), System.currentTimeMillis());
+ _lockedIps.add(reporter.getClient().getConnection().getInetAddress().getHostAddress());
+ _lockedAccounts.add(reporter.getAccountName());
+
+ long date = Calendar.getInstance().getTimeInMillis();
+ Connection con = null;
+
+ try
+ {
+ if (!_reportedCount.containsKey(reported))
+ {
+ FastList<L2PcInstance> p = new FastList<L2PcInstance>();
+ p.add(reported);
+ _reportedCount.put(reporter.getObjectId(), p);
+ }
+ else
+ {
+ if(_reportedCount.get(reporter).contains(reported.getObjectId()))
+ {
+ reporter.sendMessage("You cannot report a player more than 1 time");
+ return;
+ }
+ _reportedCount.get(reporter).add(reported);
+ }
+
+ con = L2DatabaseFactory.getInstance().getConnection();
+ PreparedStatement statement = con.prepareStatement("INSERT INTO `bot_report`(`reported_name`, `reported_objectId`, `reporter_name`, `reporter_objectId`, `date`) VALUES (?,?,?,?,?)", Statement.RETURN_GENERATED_KEYS);
+ statement.setString(1, reported.getName());
+ statement.setInt(2, reported.getObjectId());
+ statement.setString(3, reporter.getName());
+ statement.setInt(4, reporter.getObjectId());
+ statement.setLong(5, date);
+ statement.executeUpdate();
+
+ ResultSet rs = statement.getGeneratedKeys();
+ rs.next();
+ int maxId = rs.getInt(1);
+
+ statement.close();
+ _unread.put(maxId, new String[]{reported.getName(), reporter.getName(), String.valueOf(date)});
+ }
+ catch (Exception e)
+ {
+ _log.severe("Could not save reported bot " + reported.getName() + " by " + reporter.getName() + " at " + date + ".");
+ }
+ finally
+ {
+ try
+ {
+ con.close();
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ SystemMessage sm = new SystemMessage(SystemMessageId.C1_REPORTED_AS_BOT);
+ sm.addCharName(reported);
+ reporter.sendPacket(sm);
+ }
+
+ /**
+ * Will load the data from all unreaded reports (used to load reports
+ * in a window for admins/GMs)
+ * @return a FastMap<Integer, String[]> (Integer - report id, String[] - reported name, report name, date)
+ */
+ private void loadUnread()
+ {
+ _unread = new FastMap<Integer, String[]>();
+ Connection con = null;
+ try
+ {
+ con = L2DatabaseFactory.getInstance().getConnection();
+ PreparedStatement statement = con.prepareStatement("SELECT `report_id`, `reported_name`, `reporter_name`, `date`, MAX(`report_id`) as `max_id` FROM `bot_report` WHERE `read` = ?");
+ statement.setString(1, "false");
+
+ ResultSet rset = statement.executeQuery();
+ while (rset.next())
+ {
+ //Not loading objectIds to increase performance
+ //L2World.getInstance().getPlayer(name).getObjectId();
+ String[] data = new String[3];
+ data[0] = rset.getString("reported_name");
+ data[1] = rset.getString("reporter_name");
+ data[2] = rset.getString("date");
+
+ _unread.put(rset.getInt("report_id"), data);
+ }
+ rset.close();
+ statement.close();
+ }
+ catch (Exception e)
+ {
+ _log.severe("Could not load data from bot_report:\n" + e.getMessage());
+ }
+ finally
+ {
+ try
+ {
+ con.close();
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ }
+
+ /**
+ * Return a FastMap holding all the reports data
+ * to be viewed by any GM
+ * @return _unread
+ */
+ public FastMap<Integer, String[]> getUnread()
+ {
+ return _unread;
+ }
+
+ /**
+ * Marks a reported bot as readed (from admin menu)
+ * @param id (the report id)
+ */
+ public void markAsRead(int id)
+ {
+ Connection con = null;
+ try
+ {
+ con = L2DatabaseFactory.getInstance().getConnection();
+ PreparedStatement statement = con.prepareStatement("UPDATE `bot_report` SET `read` = ? WHERE `report_id` = ?");
+ statement.setString(1, "true");
+ statement.setInt(2, id);
+ statement.execute();
+
+ statement.close();
+ _unread.remove(id);
+ _log.fine("Reported bot marked as read, id was: " + id);
+ }
+ catch (Exception e)
+ {
+ _log.severe("Could not mark as read the reported bot: " + id + ":\n" + e.getMessage());
+ }
+ finally
+ {
+ try
+ {
+ con.close();
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ }
+
+ /**
+ * Returns the number of times the player has been reported
+ * @param reported
+ * @return int
+ */
+ public int getPlayerReportsCount(L2PcInstance reported)
+ {
+ int count = 0;
+ Connection con = null;
+ try
+ {
+ con = L2DatabaseFactory.getInstance().getConnection();
+ PreparedStatement statement = con.prepareStatement("SELECT COUNT(*) FROM `bot_report` WHERE `reported_objectId` = ?");
+ statement.setInt(1, reported.getObjectId());
+
+ ResultSet rset = statement.executeQuery();
+ count = rset.getInt(1);
+ rset.close();
+ statement.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ finally
+ {
+ try
+ {
+ con.close();
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ return count;
+ }
+
+ /**
+ * Will save the punish being suffered to player in database
+ * (at player logs out), to be restored next time players enter
+ * in server
+ * @param punished
+ */
+ public void savePlayerPunish(L2PcInstance punished)
+ {
+ Connection con = null;
+ try
+ {
+ con = L2DatabaseFactory.getInstance().getConnection();
+ PreparedStatement statement = con.prepareStatement("UPDATE `bot_reported_punish` SET `time_left` = ? WHERE `charId` = ?");
+ statement.setLong(1, punished.getPlayerPunish().getPunishTimeLeft());
+ statement.setInt(2, punished.getObjectId());
+ statement.execute();
+ statement.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ finally
+ {
+ try
+ {
+ con.close();
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ }
+
+ /**
+ * Retail report restrictions (Validates the player - reporter relationship)
+ * @param reported (the reported bot)
+ * @return
+ */
+ public boolean validateBot(L2PcInstance reported, L2PcInstance reporter)
+ {
+ if (reported == null || reporter == null)
+ return false;
+
+ // Cannot report while reported is inside peace zone, war zone or olympiad
+ if (reported.isInsideZone(L2Character.ZONE_PEACE) || reported.isInsideZone(L2Character.ZONE_PVP) || reported.isInOlympiadMode())
+ {
+ reporter.sendPacket(new SystemMessage(SystemMessageId.CANNOT_REPORT_IN_WARZONE_PEACEZONE_CLANWAR_OLYMPIAD));
+ return false;
+ }
+ // Cannot report if reported and reporter are in war
+ if (reported.getClan() != null && reporter.getClan() != null)
+ {
+ if (reported.getClan().isAtWarWith(reporter.getClanId()))
+ {
+ reporter.sendPacket(new SystemMessage(SystemMessageId.CANNOT_REPORT_TARGET_IN_CLAN_WAR));
+ return false;
+ }
+ }
+ // Cannot report if the reported didnt earn exp since he logged in
+ if (!reported.getStat().hasEarnedExp())
+ {
+ reporter.sendPacket(new SystemMessage(SystemMessageId.CANNOT_REPORT_CHARACTER_WITHOUT_GAINEXP));
+ return false;
+ }
+ // Cannot report twice or more a player
+ if (_reportedCount.containsKey(reporter))
+ {
+ for (L2PcInstance p : _reportedCount.get(reporter))
+ {
+ if (reported == p)
+ {
+ reporter.sendPacket(new SystemMessage(SystemMessageId.C1_REPORTED_AS_BOT));
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Retail report restrictions (Validates the reporter state)
+ * @param reporter
+ * @return
+ */
+ public synchronized boolean validateReport(L2PcInstance reporter)
+ {
+ if (reporter == null)
+ return false;
+
+ if(reporter._account == null)
+ reporter._account = new L2Account(reporter.getAccountName());
+
+ // The player has a 30 mins lock before be able to report anyone again
+ if(reporter._account.getReportsPoints() == 0)
+ {
+ SystemMessage sm = new SystemMessage(SystemMessageId.YOU_CAN_REPORT_IN_S1_MINUTES_S2_REPORT_POINTS_REMAIN_IN_ACCOUNT);
+ sm.addNumber(0);
+ sm.addNumber(0);
+ reporter.sendPacket(sm);
+ return false;
+ }
+
+ // 30 mins must pass before report again
+ else if (_lockedReporters.containsKey(reporter.getObjectId()))
+ {
+ long delay = (System.currentTimeMillis() - _lockedReporters.get(reporter.getObjectId()));
+ if (delay <= 1800000)
+ {
+ int left = (int) (1800000 - delay) / 60000;
+ SystemMessage sm = new SystemMessage(SystemMessageId.YOU_CAN_REPORT_IN_S1_MINUTES_S2_REPORT_POINTS_REMAIN_IN_ACCOUNT);
+ sm.addNumber(left);
+ sm.addNumber(reporter._account.getReportsPoints());
+ reporter.sendPacket(sm);
+ return false;
+ }
+ else
+ ThreadPoolManager.getInstance().executeTask(new ReportClear(reporter));
+ }
+ // In those 30 mins, the ip which made the first report cannot report again
+ else if (_lockedIps.contains(reporter.getClient().getConnection().getInetAddress().getHostAddress()))
+ {
+ reporter.sendPacket(new SystemMessage(SystemMessageId.CANNOT_REPORT_ALREDY_REPORTED_FROM_YOUR_CLAN_OR_IP));
+ return false;
+ }
+ // In those 30 mins, the account which made report cannot report again
+ else if (_lockedAccounts.contains(reporter.getAccountName()))
+ {
+ reporter.sendPacket(new SystemMessage(SystemMessageId.CANNOT_REPORT_ALAREDY_REPORTED_FROM_SAME_ACCOUNT));
+ return false;
+ }
+ // If any clan/ally mate has reported any bot, you cannot report till he releases his lock
+ else if (reporter.getClan() != null)
+ {
+ for (int i : _lockedReporters.keySet())
+ {
+ // Same clan
+ L2PcInstance p = L2World.getInstance().getPlayer(i);
+ if (p == null)
+ continue;
+
+ if (p.getClanId() == reporter.getClanId())
+ {
+ reporter.sendPacket(new SystemMessage(SystemMessageId.CANNOT_REPORT_ALREDY_REPORTED_FROM_YOUR_CLAN_OR_IP));
+ return false;
+ }
+ // Same ally
+ else if (reporter.getClan().getAllyId() != 0)
+ {
+ if (p.getClan().getAllyId() == reporter.getClan().getAllyId())
+ {
+ reporter.sendPacket(new SystemMessage(SystemMessageId.CANNOT_REPORT_ALREDY_REPORTED_FROM_YOUR_CLAN_OR_IP));
+ return false;
+ }
+ }
+ }
+ }
+ reporter._account.reducePoints();
+ return true;
+ }
+
+ /**
+ * Will manage needed actions on enter
+ * @param activeChar
+ */
+ public void onEnter(L2PcInstance activeChar)
+ {
+ activeChar.getStat().setFirstExp(activeChar.getExp());
+ restorePlayerBotPunishment(activeChar);
+ activeChar._account = new L2Account(activeChar.getAccountName());
+ }
+
+ /**
+ * Will retore the player punish on enter
+ * @param activeChar
+ */
+ private void restorePlayerBotPunishment(L2PcInstance activeChar)
+ {
+ String punish = "";
+ long delay = 0;
+ Connection con = null;
+ try
+ {
+ con = L2DatabaseFactory.getInstance().getConnection();
+ PreparedStatement statement = con.prepareStatement("SELECT `punish_type`, `time_left` FROM `bot_reported_punish` WHERE `charId` = ?");
+ statement.setInt(1, activeChar.getObjectId());
+
+ ResultSet rset = statement.executeQuery();
+ while (rset.next())
+ {
+ punish = rset.getString("punish_type");
+ delay = rset.getLong("time_left");
+ }
+ rset.close();
+ statement.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ finally
+ {
+ try
+ {
+ con.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ if (!punish.isEmpty() && BotPunish.Punish.valueOf(punish) != null)
+ {
+ if (delay < 0)
+ {
+ BotPunish.Punish p = BotPunish.Punish.valueOf(punish);
+ long left = (-delay / 1000) / 60;
+ activeChar.setPunishDueBotting(p, (int) left);
+ }
+ else
+ activeChar.endPunishment();
+ }
+ }
+
+ private static class SingletonHolder
+ {
+ private static BotManager _instance = new BotManager();
+ }
+
+ /**
+ * Manages the reporter restriction data clean up
+ * to be able to report again
+ */
+ private class ReportClear implements Runnable
+ {
+ private L2PcInstance _reporter;
+
+ private ReportClear(L2PcInstance reporter)
+ {
+ _reporter = reporter;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Runnable#run()
+ */
+ @Override
+ public void run()
+ {
+ _lockedReporters.remove(_reporter.getObjectId());
+ _lockedIps.remove(_reporter.getClient().getConnection().getInetAddress().getHostAddress());
+ _lockedAccounts.remove(_reporter.getAccountName());
+ }
+ }
+}
Index: java/com/l2jserver/gameserver/model/L2Account.java
===================================================================
--- java/com/l2jserver/gameserver/model/L2Account.java (revision 0)
+++ java/com/l2jserver/gameserver/model/L2Account.java (revision 0)
@@ -0,0 +1,108 @@
+/*
+ * 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 com.l2jserver.gameserver.model;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.l2jserver.L2DatabaseFactory;
+
+/**
+ * @author BiggBoss
+ */
+public class L2Account
+{
+ private static Logger _log = Logger.getLogger(L2Account.class.getName());
+
+ private int _reportBotPoints;
+
+ public L2Account(String accName)
+ {
+ loadBotPoints(accName);
+ }
+
+ private void loadBotPoints(String accName)
+ {
+ Connection con = null;
+ try
+ {
+ con = L2DatabaseFactory.getInstance().getConnection();
+ PreparedStatement statement = con.prepareStatement("SELECT bot_report_points FROM accounts WHERE login = ?");
+ statement.setString(1, accName);
+
+ ResultSet rset = statement.executeQuery();
+ while(rset.next())
+ {
+ _reportBotPoints = rset.getInt("bot_report_points");
+ }
+ rset.close();
+ statement.close();
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ finally
+ {
+ try
+ {
+ con.close();
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public synchronized void updatePoints(String accName) throws SQLException
+ {
+ Connection con = null;
+ try
+ {
+ con = L2DatabaseFactory.getInstance().getConnection();
+ PreparedStatement statement = con.prepareStatement("UPDATE accounts SET bot_report_points = ? WHERE login = ?");
+ statement.setInt(1, _reportBotPoints);
+ statement.setString(2, accName);
+ statement.execute();
+ statement.close();
+ }
+ catch(SQLException e)
+ {
+ _log.log(Level.SEVERE, "Couldnt save bot reports points for "+accName);
+ e.printStackTrace();
+ }
+ finally
+ {
+ con.close();
+ if(!con.isClosed())
+ throw new SQLException();
+ }
+ }
+
+ public synchronized int getReportsPoints()
+ {
+ return _reportBotPoints;
+ }
+
+ public synchronized void reducePoints()
+ {
+ _reportBotPoints--;
+ }
+}
Index: java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java
===================================================================
--- java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java (revision 3970)
+++ java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java (working copy)
@@ -76,6 +76,7 @@
import com.l2jserver.gameserver.handler.IItemHandler;
import com.l2jserver.gameserver.handler.ItemHandler;
import com.l2jserver.gameserver.instancemanager.AntiFeedManager;
+import com.l2jserver.gameserver.instancemanager.BotManager;
import com.l2jserver.gameserver.instancemanager.CastleManager;
import com.l2jserver.gameserver.instancemanager.CoupleManager;
import com.l2jserver.gameserver.instancemanager.CursedWeaponsManager;
@@ -91,6 +92,7 @@
import com.l2jserver.gameserver.model.Elementals;
import com.l2jserver.gameserver.model.FishData;
import com.l2jserver.gameserver.model.L2AccessLevel;
+import com.l2jserver.gameserver.model.L2Account;
import com.l2jserver.gameserver.model.L2CharPosition;
import com.l2jserver.gameserver.model.L2Clan;
import com.l2jserver.gameserver.model.L2ClanMember;
@@ -242,6 +244,7 @@
import com.l2jserver.gameserver.templates.item.L2WeaponType;
import com.l2jserver.gameserver.templates.skills.L2EffectType;
import com.l2jserver.gameserver.templates.skills.L2SkillType;
+import com.l2jserver.gameserver.util.BotPunish;
import com.l2jserver.gameserver.util.FloodProtectors;
import com.l2jserver.gameserver.util.Util;
import com.l2jserver.util.Point3D;
@@ -409,6 +412,10 @@
/** The PK counter of the L2PcInstance (= Number of non PvP Flagged player killed) */
private int _pkKills;
+
+ /** The player's bot punishment */
+ private BotPunish _botPunish = null;
+ public L2Account _account = null;
/** The PvP Flag state of the L2PcInstance (0=White, 1=Purple) */
private byte _pvpFlag;
@@ -7465,7 +7472,8 @@
{
try { con.close(); } catch (Exception e) {}
}
-
+
+ player._account = new L2Account(player.getAccountName());
return player;
}
@@ -11716,6 +11724,35 @@
_log.log(Level.SEVERE, "deleteMe()", e);
}
+ // Bot punishment
+ if(Config.ENABLE_BOTREPORT)
+ {
+ // Save punish
+ if(isBeingPunished())
+ {
+ try
+ {
+ BotManager.getInstance().savePlayerPunish(this);
+ }
+ catch(Exception e)
+ {
+ _log.log(Level.SEVERE, "deleteMe()", e);
+ }
+ }
+ // Save report points left
+ if(_account != null)
+ {
+ try
+ {
+ _account.updatePoints(this._accountName);
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
try
{
if (_fusionSkill != null)
@@ -14717,4 +14754,76 @@
{
return _uiKeySettings;
}
+
+ /**
+ * Initializes his _botPunish object with the specified punish
+ * and for the specified time
+ * @param punishType
+ * @param minsOfPunish
+ */
+ public synchronized void setPunishDueBotting(BotPunish.Punish punishType, int minsOfPunish)
+ {
+ if(_botPunish == null)
+ _botPunish = new BotPunish(punishType, minsOfPunish);
+ }
+
+ /**
+ * Returns the current object-representative player punish
+ * @return
+ */
+ public BotPunish getPlayerPunish()
+ {
+ return _botPunish;
+ }
+
+ /**
+ * Returns the type of punish being applied
+ * @return
+ */
+ public BotPunish.Punish getBotPunishType()
+ {
+ return _botPunish.getBotPunishType();
+ }
+
+ /**
+ * Will return true if the player has any bot punishment
+ * active
+ * @return
+ */
+ public boolean isBeingPunished()
+ {
+ return _botPunish != null;
+ }
+
+ /**
+ * Will end the punishment once a player attempt to
+ * perform any forbid action and his punishment has
+ * expired
+ */
+ public void endPunishment()
+ {
+ Connection con = null;
+ try
+ {
+ con = L2DatabaseFactory.getInstance().getConnection();
+ PreparedStatement statement = con.prepareStatement("DELETE FROM bot_reported_punish WHERE charId = ?");
+ statement.setInt(1, getObjectId());
+ statement.execute();
+ statement.close();
+ }
+ catch(SQLException sqle)
+ {
+ sqle.printStackTrace();
+ }
+ finally
+ {
+ try
+ {
+ con.close();
+ }
+ catch(SQLException sqle) { }
+ }
+ _botPunish = null;
+ this.sendMessage("Your punishment has expired. Do not bot again!");
+ }
}
Index: java/com/l2jserver/gameserver/model/actor/stat/PcStat.java
===================================================================
--- java/com/l2jserver/gameserver/model/actor/stat/PcStat.java (revision 3970)
+++ java/com/l2jserver/gameserver/model/actor/stat/PcStat.java (working copy)
@@ -48,6 +48,9 @@
public static final int VITALITY_LEVELS[] = {240, 2000, 13000, 17000, 20000};
public static final int MAX_VITALITY_POINTS = VITALITY_LEVELS[4];
public static final int MIN_VITALITY_POINTS = 1;
+
+ // Used to check if the player has gained exp since log in
+ public long _firstExp;
// =========================================================
// Constructor
@@ -563,4 +566,25 @@
{
return _vitalityLevel;
}
+
+ /**
+ * Sets exp holded by the character on log in
+ * @param current exp
+ */
+ public void setFirstExp(long value)
+ {
+ _firstExp = value;
+ }
+
+ /**
+ * Will return true if the player has gained exp
+ * since logged in
+ * @return
+ */
+ public boolean hasEarnedExp()
+ {
+ if(getExp() - _firstExp != 0)
+ return true;
+ return false;
+ }
}
Index: java/com/l2jserver/gameserver/network/SystemMessageId.java
===================================================================
--- java/com/l2jserver/gameserver/network/SystemMessageId.java (revision 3970)
+++ java/com/l2jserver/gameserver/network/SystemMessageId.java (working copy)
@@ -13875,6 +13875,55 @@
TIME_LIMITED_ITEM_DELETED(2366),
/**
+ * ID: 2371
+ * Message: $c1 was reported as a BOT.
+ */
+ C1_REPORTED_AS_BOT(2371),
+
+ /**
+ * ID: 2377
+ * Message: You cannot report a character who is in a peace zone or a battlefield.
+ */
+ CANNOT_REPORT_TARGET_IN_PEACE_ZONE(2377),
+
+ /**
+ * ID: 2378
+ * Message: You cannot report when a clan war has been declared.
+ */
+ CANNOT_REPORT_TARGET_IN_CLAN_WAR(2378),
+
+ /**
+ * ID: 2379
+ * Message: You cannot report a character who has not acquired
+ * any Exp. after connecting.
+ */
+ CANNOT_REPORT_CHARACTER_WITHOUT_GAINEXP(2379),
+
+ /**
+ * ID: 2380
+ * Message: You cannot report this person again at this time.
+ */
+ CANNOT_REPORT_CHARACTER_AGAIN(2380),
+
+ /**
+ * ID: 2381
+ * Message: You cannot report this person again at this time.
+ */
+ CANNOT_REPORT_CHARACTER_AGAIN_2(2381),
+
+ /**
+ * ID: 2382
+ * Message: You cannot report this person again at this time.
+ */
+ CANNOT_REPORT_CHARACTER_AGAIN_3(2382),
+
+ /**
+ * ID: 2383
+ * Message: You cannot report this person again at this time.
+ */
+ CANNOT_REPORT_CHARACTER_AGAIN_4(2383),
+
+ /**
* ID: 2390<br>
* Message: Your number of My Teleports slots has reached its maximum limit.
*/
@@ -13971,6 +14020,138 @@
OLYMPIAD_3VS3_CONFIRM(2465),
/**
+ * ID: 2470
+ * Message: This character cannot make a report. You cannot make a report while located
+ * inside a peace zone or a battlefield, while you are an opposing clan member
+ * during a clan war, or while participating in the Olympiad.
+ */
+ CANNOT_REPORT_IN_WARZONE_PEACEZONE_CLANWAR_OLYMPIAD(2470),
+
+ /**
+ * ID: 2471
+ * Message: This character cannot make a report. The target has already been reported
+ * by either your clan or alliance, or has already been reported from your
+ * current IP.
+ */
+ CANNOT_REPORT_ALREDY_REPORTED_FROM_YOUR_CLAN_OR_IP(2471),
+
+ /**
+ * ID: 2472
+ * Message: This character cannot make a report because another character from this account
+ * has already done so.
+ */
+ CANNOT_REPORT_ALAREDY_REPORTED_FROM_SAME_ACCOUNT(2472),
+
+ /**
+ * ID: 2473
+ * Message: You have been reported as an illegal program user, and your chatting will be blocked for 10 minutes.
+ */
+ REPORTED_10_MINS_WITHOUT_CHAT(2473),
+
+ /**
+ * ID: 2474
+ * Message: You have been reported as an illegal program user, and your party participation will be blocked
+ * for 60 minutes.
+ */
+ REPORTED_60_MINS_WITHOUT_JOIN_PARTY(2474),
+
+ /**
+ * ID: 2475
+ * Message: You have been reported as an illegal program user, and your party participation will be blocked
+ * for 120 minutes.
+ */
+ REPORTED_120_MINS_WITHOUT_JOIN_PARTY(2475),
+
+ /**
+ * ID: 2476
+ * Message: You have been reported as an illegal program user, and your party participation will be blocked
+ * for 180 minutes.
+ */
+ REPORTED_180_MINS_WITHOUT_JOIN_PARTY(2476),
+
+ /**
+ * ID: 2477
+ * Message: You have been reported as an illegal program user, and your actions will be restricted for 120 minutes.
+ */
+ REPORTED_120_MINS_WITHOUT_ACTIONS(2477),
+
+ /**
+ * ID: 2478
+ * Message: You have been reported as an illegal program user, and your actions will be restricted for 180 minutes.
+ */
+ REPORTED_180_MINS_WITHOUT_ACTIONS(2478),
+
+ /**
+ * ID: 2479
+ * Message: You have been reported as an illegal program user, and your actions will be restricted for 180 minutes.
+ */
+ REPORTED_180_MINS_WITHOUT_ACTIONS_2(2479),
+
+ /**
+ * ID: 2480
+ * Message: You have been reported as an illegal program user, and moving will be blocked for 120 minutes.
+ */
+ REPORTED_120_MINS_WITHOUT_MOVE(2480),
+
+ /**
+ * ID: 2481
+ * Message: $c1% has been reported as an illegal program user and has been investigated.
+ */
+ USER_REPORTED_AND_BEING_INVESTIGATED(2481),
+
+ /**
+ * ID: 2482
+ * Message: $c1% has been reported as an illegal program user and cannot join a party.
+ */
+ USER_REPORTED_AND_CANNOT_JOIN_PARTY(2482),
+
+ /**
+ * ID: 2483
+ * Message: You have been reported as an illegal program user, and chatting is not allowed.
+ */
+ YOU_HAVE_BEEN_REPORTED_AND_CANNOT_CHAT(2483),
+
+ /**
+ * ID: 2484
+ * Message: You have been reported as an illegal program user, and participating in a party is not allowed.
+ */
+ YOU_HAVE_BEEN_REPORTED_AND_CANNOT_JOIN_PARTY(2484),
+
+ /**
+ * ID: 2485
+ * Message: You have been reported as an illegal program user, and your activities are only allowed within
+ * limitation.
+ */
+ YOU_HAVE_BEEN_REPORTED_AND_ACTIONS_ARE_LIMITED(2485),
+
+ /**
+ * ID: 2486
+ * Message: You have been blocked due to verification that you are using a third party program.
+ * Subsequent violations may result termination of the account rather than a penalty within the game,
+ * so please keep this in mind.
+ */
+ CHAR_BLOCKED_DUE_THIRD_PARTY_SOFTWARE_USE_VERIFICATION(2486),
+
+ /**
+ * ID: 2487
+ * Message: You have been reported as an illegal program user, and your connection has been ended. Please
+ * contact our CS team to confirm your identity.
+ */
+ YOU_HAVE_BEEN_REPORTED_AND_CONNECTION_HAS_ENDED(2487),
+
+ /**
+ * ID: 2748
+ * Message: You have been reported as an illegal program user and cannot report other users.
+ */
+ YOU_HAVE_BEEN_REPORTED_AND_CANNOT_REPORT(2748),
+
+ /**
+ * ID: 2774
+ * Message: You can make another report in $s1-minute(s). You have $s2 points remaining on this account.
+ */
+ YOU_CAN_REPORT_IN_S1_MINUTES_S2_REPORT_POINTS_REMAIN_IN_ACCOUNT(2774),
+
+ /**
* ID: 2500<br>
* Message: The collection has succeeded.
*/
Index: java/com/l2jserver/gameserver/network/clientpackets/EnterWorld.java
===================================================================
--- java/com/l2jserver/gameserver/network/clientpackets/EnterWorld.java (revision 3970)
+++ java/com/l2jserver/gameserver/network/clientpackets/EnterWorld.java (working copy)
@@ -30,6 +30,7 @@
import com.l2jserver.gameserver.datatables.GMSkillTable;
import com.l2jserver.gameserver.datatables.MapRegionTable;
import com.l2jserver.gameserver.datatables.SkillTable;
+import com.l2jserver.gameserver.instancemanager.BotManager;
import com.l2jserver.gameserver.instancemanager.CastleManager;
import com.l2jserver.gameserver.instancemanager.ClanHallManager;
import com.l2jserver.gameserver.instancemanager.CoupleManager;
@@ -184,6 +185,10 @@
if (Config.GM_GIVE_SPECIAL_SKILLS)
GMSkillTable.getInstance().addSkills(activeChar);
}
+
+ // Bot manager punishment
+ if(Config.ENABLE_BOTREPORT)
+ BotManager.getInstance().onEnter(activeChar);
// Set dead status if applies
if (activeChar.getCurrentHp() < 0.5)
Index: java/com/l2jserver/gameserver/network/clientpackets/RequestActionUse.java
===================================================================
--- java/com/l2jserver/gameserver/network/clientpackets/RequestActionUse.java (revision 3970)
+++ java/com/l2jserver/gameserver/network/clientpackets/RequestActionUse.java (working copy)
@@ -22,6 +22,7 @@
import com.l2jserver.gameserver.ai.L2SummonAI;
import com.l2jserver.gameserver.datatables.PetSkillsTable;
import com.l2jserver.gameserver.datatables.SkillTable;
+import com.l2jserver.gameserver.instancemanager.BotManager;
import com.l2jserver.gameserver.instancemanager.CastleManager;
import com.l2jserver.gameserver.model.L2CharPosition;
import com.l2jserver.gameserver.model.L2ManufactureList;
@@ -41,6 +42,7 @@
import com.l2jserver.gameserver.network.serverpackets.RecipeShopManageList;
import com.l2jserver.gameserver.network.serverpackets.SocialAction;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.gameserver.util.BotPunish;
/**
@@ -73,6 +75,34 @@
if (activeChar == null)
return;
+ // Check if has any bot punishment
+ if(activeChar.isBeingPunished())
+ {
+ // Remove punishment if finished
+ if(activeChar.getPlayerPunish().canPerformAction() && activeChar.getBotPunishType() == BotPunish.Punish.ACTIONBAN)
+ {
+ activeChar.endPunishment();
+ }
+ // Else apply it
+ else
+ {
+ SystemMessageId msgId = null;
+ switch(activeChar.getPlayerPunish().getDuration())
+ {
+ case 7200:
+ msgId = SystemMessageId.REPORTED_120_MINS_WITHOUT_ACTIONS;
+ break;
+ case 10800:
+ msgId = SystemMessageId.REPORTED_180_MINS_WITHOUT_ACTIONS;
+ break;
+ default:
+ }
+ activeChar.sendPacket(new SystemMessage(msgId));
+ return;
+ }
+
+ }
+
if (Config.DEBUG)
_log.finest(activeChar.getName() + " request Action use: id " + _actionId + " 2:" + _ctrlPressed + " 3:" + _shiftPressed);
@@ -347,7 +377,29 @@
activeChar.tryOpenPrivateSellStore(true);
break;
case 65: // Bot Report Button
- activeChar.sendMessage("Action not handled yet.");
+ if(Config.ENABLE_BOTREPORT)
+ {
+ if(activeChar.getTarget() instanceof L2PcInstance)
+ {
+ L2PcInstance reported = (L2PcInstance) activeChar.getTarget();
+ if(!BotManager.getInstance().validateBot(reported, activeChar))
+ return;
+ if(!BotManager.getInstance().validateReport(activeChar))
+ return;
+ try
+ {
+ BotManager.getInstance().reportBot(reported, activeChar);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ else
+ activeChar.sendMessage("Your target is not a player!");
+ }
+ else
+ activeChar.sendMessage("Action disabled.");
break;
case 67: // Steer
case 68: // Cancel Control
Index: java/com/l2jserver/gameserver/network/clientpackets/RequestJoinParty.java
===================================================================
--- java/com/l2jserver/gameserver/network/clientpackets/RequestJoinParty.java (revision 3970)
+++ java/com/l2jserver/gameserver/network/clientpackets/RequestJoinParty.java (working copy)
@@ -24,6 +24,7 @@
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.AskJoinParty;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.gameserver.util.BotPunish;
/**
@@ -67,6 +68,52 @@
return;
}
+ // Check for bot punishment on target
+ if(target.isBeingPunished())
+ {
+ // Check conditions
+ if(target.getPlayerPunish().canJoinParty() && target.getBotPunishType() == BotPunish.Punish.PARTYBAN)
+ {
+ target.endPunishment();
+ }
+ else
+ {
+ // Inform the player cannot join party
+ requestor.sendPacket(new SystemMessage(SystemMessageId.USER_REPORTED_AND_CANNOT_JOIN_PARTY));
+ return;
+ }
+
+ }
+
+ // Check for bot punishment on requestor
+ if(requestor.isBeingPunished())
+ {
+ // Check conditions
+ if(requestor.getPlayerPunish().canJoinParty() && requestor.getBotPunishType() == BotPunish.Punish.PARTYBAN)
+ {
+ requestor.endPunishment();
+ }
+ else
+ {
+ SystemMessageId msgId = null;
+ switch(requestor.getPlayerPunish().getDuration())
+ {
+ case 3600:
+ msgId = SystemMessageId.REPORTED_60_MINS_WITHOUT_JOIN_PARTY;
+ break;
+ case 7200:
+ msgId = SystemMessageId.REPORTED_120_MINS_WITHOUT_JOIN_PARTY;
+ break;
+ case 10800:
+ msgId = SystemMessageId.REPORTED_180_MINS_WITHOUT_JOIN_PARTY;
+ break;
+ default:
+ }
+ requestor.sendPacket(new SystemMessage(msgId));
+ return;
+ }
+ }
+
if (target.getAppearance().getInvisible())
{
requestor.sendPacket(new SystemMessage(SystemMessageId.TARGET_IS_INCORRECT));
Index: java/com/l2jserver/gameserver/network/clientpackets/Say2.java
===================================================================
--- java/com/l2jserver/gameserver/network/clientpackets/Say2.java (revision 3970)
+++ java/com/l2jserver/gameserver/network/clientpackets/Say2.java (working copy)
@@ -24,6 +24,8 @@
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.gameserver.util.BotPunish;
+import com.l2jserver.gameserver.util.Util;
/**
@@ -78,6 +80,10 @@
"UNKNOWN",
"BATTLEFIELD"
};
+
+ private static final String[] WALKER_COMMAND_LIST = { "USESKILL", "USEITEM", "BUYITEM", "SELLITEM", "SAVEITEM", "LOADITEM", "MSG", "SET", "DELAY", "LABEL", "JMP", "CALL",
+ "RETURN", "MOVETO", "NPCSEL", "NPCDLG", "DLGSEL", "CHARSTATUS", "POSOUTRANGE", "POSINRANGE", "GOHOME", "SAY", "EXIT", "PAUSE", "STRINDLG", "STRNOTINDLG", "CHANGEWAITTYPE",
+ "FORCEATTACK", "ISMEMBER", "REQUESTJOINPARTY", "REQUESTOUTPARTY", "QUITPARTY", "MEMBERSTATUS", "CHARBUFFS", "ITEMCOUNT", "FOLLOWTELEPORT" };
private String _text;
private int _type;
@@ -87,7 +93,7 @@
protected void readImpl()
{
_text = readS();
- _type = readD();
+ _type = readD();
_target = (_type == TELL) ? readS() : null;
}
@@ -101,6 +107,23 @@
if (activeChar == null)
return;
+ // Check for bot punishment
+ if(activeChar.isBeingPunished())
+ {
+ // Check if punishment expired
+ if(activeChar.getPlayerPunish().canTalk() && activeChar.getBotPunishType() == BotPunish.Punish.CHATBAN)
+ {
+ activeChar.endPunishment();
+ }
+ // Else, apply it
+ else
+ {
+ // Inform player
+ activeChar.sendPacket(new SystemMessage(SystemMessageId.REPORTED_10_MINS_WITHOUT_CHAT));
+ return;
+ }
+ }
+
if (_type < 0 || _type >= CHAT_NAMES.length)
{
_log.warning("Say2: Invalid type: " +_type + " Player : " + activeChar.getName() + " text: " + String.valueOf(_text));
@@ -120,6 +143,12 @@
activeChar.sendPacket(new SystemMessage(SystemMessageId.DONT_SPAM));
return;
}
+
+ if (_type == TELL && checkBot(_text))
+ {
+ Util.handleIllegalPlayerAction(activeChar, "Client Emulator Detect: Player " + activeChar.getName() + " using l2walker.", Config.DEFAULT_PUNISH);
+ return;
+ }
if (activeChar.isCursedWeaponEquipped() && (_type == TRADE || _type == SHOUT))
{
@@ -177,6 +206,16 @@
filteredText = filteredText.replaceAll("(?i)" + pattern, Config.CHAT_FILTER_CHARS);
_text = filteredText;
}
+
+ private boolean checkBot(String text)
+ {
+ for (String botCommand : WALKER_COMMAND_LIST)
+ {
+ if (text.startsWith(botCommand))
+ return true;
+ }
+ return false;
+ }
/* (non-Javadoc)
* @see com.l2jserver.gameserver.clientpackets.ClientBasePacket#getType()
Index: java/com/l2jserver/gameserver/network/serverpackets/MoveToLocation.java
===================================================================
--- java/com/l2jserver/gameserver/network/serverpackets/MoveToLocation.java (revision 3970)
+++ java/com/l2jserver/gameserver/network/serverpackets/MoveToLocation.java (working copy)
@@ -14,7 +14,11 @@
*/
package com.l2jserver.gameserver.network.serverpackets;
+import com.l2jserver.Config;
import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.network.SystemMessageId;
+import com.l2jserver.gameserver.util.BotPunish;
/**
* 0000: 01 7a 73 10 4c b2 0b 00 00 a3 fc 00 00 e8 f1 ff .zs.L...........
@@ -29,9 +33,11 @@
{
private static final String _S__01_CHARMOVETOLOCATION = "[S] 2f MoveToLocation";
private int _charObjId, _x, _y, _z, _xDst, _yDst, _zDst;
+ private L2Character _cha;
public MoveToLocation(L2Character cha)
{
+ _cha = cha;
_charObjId = cha.getObjectId();
_x = cha.getX();
_y = cha.getY();
@@ -44,6 +50,24 @@
@Override
protected final void writeImpl()
{
+ // Bot punishment restriction
+ if(_cha instanceof L2PcInstance && Config.ENABLE_BOTREPORT)
+ {
+ L2PcInstance actor = (L2PcInstance) _cha;
+ if(actor.isBeingPunished())
+ {
+ if(actor.getPlayerPunish().canWalk() && actor.getPlayerPunish().getBotPunishType() == BotPunish.Punish.MOVEBAN)
+ {
+ actor.endPunishment();
+ }
+ else
+ {
+ actor.sendPacket(new SystemMessage(SystemMessageId.REPORTED_120_MINS_WITHOUT_MOVE));
+ return;
+ }
+ }
+ }
+
writeC(0x2f);
writeD(_charObjId);
Index: java/com/l2jserver/gameserver/taskmanager/tasks/TaskReportPointsRestore.java
===================================================================
--- java/com/l2jserver/gameserver/taskmanager/tasks/TaskReportPointsRestore.java (revision 0)
+++ java/com/l2jserver/gameserver/taskmanager/tasks/TaskReportPointsRestore.java (revision 0)
@@ -0,0 +1,78 @@
+/*
+ * 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 com.l2jserver.gameserver.taskmanager.tasks;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+import com.l2jserver.L2DatabaseFactory;
+import com.l2jserver.gameserver.taskmanager.Task;
+import com.l2jserver.gameserver.taskmanager.TaskManager;
+import com.l2jserver.gameserver.taskmanager.TaskTypes;
+import com.l2jserver.gameserver.taskmanager.TaskManager.ExecutedTask;
+
+/**
+ * @author BiggBoss
+ */
+public class TaskReportPointsRestore extends Task
+{
+ private static final String NAME = "report_points_restore";
+
+ /* (non-Javadoc)
+ * @see com.l2jserver.gameserver.taskmanager.Task#getName()
+ */
+ @Override
+ public String getName()
+ {
+ return NAME;
+ }
+
+ /* (non-Javadoc)
+ * @see com.l2jserver.gameserver.taskmanager.Task#onTimeElapsed(com.l2jserver.gameserver.taskmanager.TaskManager.ExecutedTask)
+ */
+ @Override
+ public void onTimeElapsed(ExecutedTask task)
+ {
+ Connection con = null;
+ try
+ {
+ con = L2DatabaseFactory.getInstance().getConnection();
+ PreparedStatement update = con.prepareStatement("UPDATE accounts SET bot_report_points = 7");
+ update.execute();
+ update.close();
+ System.out.println("Sucessfully restored Bot Report Points for all accounts!");
+ }
+ catch(SQLException sqle)
+ {
+ sqle.printStackTrace();
+ }
+ finally
+ {
+ try { con.close(); } catch(Exception e) { e.printStackTrace(); }
+ }
+ }
+
+ /**
+ *
+ * @see com.l2jserver.gameserver.taskmanager.Task#initializate()
+ */
+ @Override
+ public void initializate()
+ {
+ super.initializate();
+ TaskManager.addUniqueTask(NAME, TaskTypes.TYPE_GLOBAL_TASK, "1", "00:00:00", "");
+ }
+}
Index: java/com/l2jserver/gameserver/util/BotPunish.java
===================================================================
--- java/com/l2jserver/gameserver/util/BotPunish.java (revision 0)
+++ java/com/l2jserver/gameserver/util/BotPunish.java (revision 0)
@@ -0,0 +1,131 @@
+/*
+ * 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 com.l2jserver.gameserver.util;
+
+/**
+ * @author BiggBoss
+ */
+public class BotPunish
+{
+ // Kind of punish
+ private Punish _botPunishment;
+ // Time the punish will last
+ private long _punishTime;
+ // Punis time (in secs)
+ private int _punishDuration;
+
+ // Type of punishments
+ public enum Punish
+ {
+ CHATBAN,
+ MOVEBAN,
+ PARTYBAN,
+ ACTIONBAN
+ }
+
+ public BotPunish(Punish punish, int mins)
+ {
+ _botPunishment = punish;
+ _punishTime = System.currentTimeMillis() + ( mins * 60 * 1000);
+ _punishDuration = mins * 60;
+ }
+
+ /**
+ * Returns the current punishment type
+ * @return Punish (BotPunish enum)
+ */
+ public Punish getBotPunishType()
+ {
+ return _botPunishment;
+ }
+
+ /**
+ * Returns the time (in millis) when the player
+ * punish started
+ * @return long
+ */
+ public long getPunishStarterTime()
+ {
+ return _punishTime;
+ }
+
+ /**
+ * Returns the duration (in seconds) of the applied
+ * punish
+ * @return int
+ */
+ public int getDuration()
+ {
+ return _punishDuration;
+ }
+
+ /**
+ * Return the time left to end up this punish
+ * @return long
+ */
+ public long getPunishTimeLeft()
+ {
+ long left = System.currentTimeMillis() - _punishTime;
+ return left;
+ }
+
+ /**
+ * @return true if the player punishment has
+ * expired
+ */
+ public boolean canWalk()
+ {
+ if(_botPunishment == Punish.MOVEBAN
+ && System.currentTimeMillis() - _punishTime <= 0)
+ return false;
+ return true;
+ }
+
+ /**
+ * @return true if the player punishment has
+ * expired
+ */
+ public boolean canTalk()
+ {
+ if(_botPunishment == Punish.CHATBAN
+ && System.currentTimeMillis() - _punishTime <= 0)
+ return false;
+ return true;
+ }
+
+ /**
+ * @return true if the player punishment has
+ * expired
+ */
+ public boolean canJoinParty()
+ {
+ if(_botPunishment == Punish.PARTYBAN
+ && System.currentTimeMillis() - _punishTime <= 0)
+ return false;
+ return true;
+ }
+
+ /**
+ * @return true if the player punishment has
+ * expired
+ */
+ public boolean canPerformAction()
+ {
+ if(_botPunishment == Punish.ACTIONBAN
+ && System.currentTimeMillis() - _punishTime <= 0)
+ return false;
+ return true;
+ }
+}
Index: java/config/General.properties
===================================================================
--- java/config/General.properties (revision 3970)
+++ java/config/General.properties (working copy)
@@ -659,6 +659,13 @@
# Default: False
CustomNpcBufferTables = False
+# ---------------------------------------------------------------------------
+# Bot Report
+# ---------------------------------------------------------------------------
+# If enabled, the action button in the character action inventory
+# called Bot Report will be used to report bots (stored in database)
+# Default: True
+EnableBotReport = True
# ---------------------------------------------------------------------------
# Developer Settings
Código:
Index: data/scripts/handlers/MasterHandler.java
===================================================================
--- data/scripts/handlers/MasterHandler.java (revision 7123)
+++ data/scripts/handlers/MasterHandler.java (working copy)
@@ -50,6 +50,7 @@
AdminCommandHandler.getInstance().registerAdminCommandHandler(new AdminCache());
AdminCommandHandler.getInstance().registerAdminCommandHandler(new AdminCamera());
AdminCommandHandler.getInstance().registerAdminCommandHandler(new AdminChangeAccessLevel());
+ AdminCommandHandler.getInstance().registerAdminCommandHandler(new AdminCheckBot());
AdminCommandHandler.getInstance().registerAdminCommandHandler(new AdminCreateItem());
AdminCommandHandler.getInstance().registerAdminCommandHandler(new AdminCursedWeapons());
AdminCommandHandler.getInstance().registerAdminCommandHandler(new AdminDelete());
Index: data/scripts/handlers/admincommandhandlers/AdminCheckBot.java
===================================================================
--- data/scripts/handlers/admincommandhandlers/AdminCheckBot.java (revision 0)
+++ data/scripts/handlers/admincommandhandlers/AdminCheckBot.java (revision 0)
@@ -0,0 +1,228 @@
+package handlers.admincommandhandlers;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+import javolution.text.TextBuilder;
+
+import com.l2jserver.Config;
+import com.l2jserver.L2DatabaseFactory;
+import com.l2jserver.gameserver.handler.IAdminCommandHandler;
+import com.l2jserver.gameserver.instancemanager.BotManager;
+import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.network.SystemMessageId;
+import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
+import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+import com.l2jserver.gameserver.util.BotPunish;
+
+/**
+ * @author BiggBoss
+ */
+public class AdminCheckBot implements IAdminCommandHandler
+{
+ private static final String[] ADMIN_COMMANDS = {
+ "admin_checkBots",
+ "admin_readBot",
+ "admin_markBotReaded",
+ "admin_punish_bot"
+ };
+
+ @Override
+ public String[] getAdminCommandList()
+ {
+ return ADMIN_COMMANDS;
+ }
+
+ @Override
+ public boolean useAdminCommand(String command, L2PcInstance activeChar)
+ {
+ if (!Config.ENABLE_BOTREPORT)
+ {
+ activeChar.sendMessage("Bot reporting is not enabled!");
+ return false;
+ }
+
+ String[] sub = command.split(" ");
+ if (command.startsWith("admin_checkBots"))
+ {
+ sendBotPage(activeChar);
+ }
+ else if (command.startsWith("admin_readBot"))
+ {
+ sendBotInfoPage(activeChar, Integer.valueOf(sub[1]));
+ }
+ else if (command.startsWith("admin_markBotReaded"))
+ {
+ try
+ {
+ BotManager.getInstance().markAsRead(Integer.valueOf(sub[1]));
+ sendBotPage(activeChar);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ else if (command.startsWith("admin_punish_bot"))
+ {
+ activeChar.sendMessage("Usage: //punish_bot <charName>");
+
+ if (sub != null)
+ {
+ L2PcInstance target = L2World.getInstance().getPlayer(sub[1]);
+ if (target != null)
+ {
+ synchronized (target)
+ {
+ int punishLevel = 0;
+ try
+ {
+ punishLevel = BotManager.getInstance().getPlayerReportsCount(target);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+ // By System Message guess:
+ // Reported 1 time = 10 mins chat ban
+ // Reported 2 times = 60 mins w/o join pt
+ // Reported 3 times = 120 mins w/o join pt
+ // Reported 4 times = 180 mins w/o join pt
+ // Reported 5 times = 120 mins w/o move
+ // Reported 6 times = 180 mins w/o move
+ // Reported 7 times = 120 mins w/o any action
+
+ // Must be handled by GM or automatically ?
+ // Since never will be retail info, ill put manually
+ switch (punishLevel)
+ {
+ case 1:
+ target.setPunishDueBotting(BotPunish.Punish.CHATBAN, 10);
+ target.sendPacket(new SystemMessage(SystemMessageId.REPORTED_10_MINS_WITHOUT_CHAT));
+ break;
+ case 2:
+ target.setPunishDueBotting(BotPunish.Punish.PARTYBAN, 60);
+ target.sendPacket(new SystemMessage(SystemMessageId.REPORTED_60_MINS_WITHOUT_JOIN_PARTY));
+ break;
+ case 3:
+ target.setPunishDueBotting(BotPunish.Punish.PARTYBAN, 120);
+ target.sendPacket(new SystemMessage(SystemMessageId.REPORTED_120_MINS_WITHOUT_JOIN_PARTY));
+ break;
+ case 4:
+ target.setPunishDueBotting(BotPunish.Punish.PARTYBAN, 180);
+ target.sendPacket(new SystemMessage(SystemMessageId.REPORTED_180_MINS_WITHOUT_JOIN_PARTY));
+ break;
+ case 5:
+ target.setPunishDueBotting(BotPunish.Punish.MOVEBAN, 120);
+ target.sendPacket(new SystemMessage(SystemMessageId.REPORTED_120_MINS_WITHOUT_MOVE));
+ break;
+ case 6:
+ target.setPunishDueBotting(BotPunish.Punish.ACTIONBAN, 120);
+ target.sendPacket(new SystemMessage(SystemMessageId.REPORTED_120_MINS_WITHOUT_ACTIONS));
+ break;
+ case 7:
+ target.setPunishDueBotting(BotPunish.Punish.ACTIONBAN, 180);
+ target.sendPacket(new SystemMessage(SystemMessageId.REPORTED_180_MINS_WITHOUT_ACTIONS));
+ break;
+ default:
+ activeChar.sendMessage("Your target wasnt reported as a bot!");
+ }
+ // Inserts first time player punish in database, avoiding
+ // problems to update punish state in future on log out
+ if (punishLevel != 0)
+ {
+ introduceNewPunishedBotAndClear(target);
+ activeChar.sendMessage(target.getName() + " has been punished");
+ }
+ }
+ }
+ else
+ activeChar.sendMessage("Your target doesnt exist!");
+ }
+ }
+ return true;
+ }
+
+ private static void sendBotPage(L2PcInstance activeChar)
+ {
+ TextBuilder tb = new TextBuilder();
+ tb.append("<html><title>Unread Bot List</title><body><center>");
+ tb.append("Here's a list of the current <font color=LEVEL>unread</font><br1>bots!<br>");
+
+ for (int i : BotManager.getInstance().getUnread().keySet())
+ {
+ tb.append("<a action=\"bypass -h admin_readBot " + i + "\">Ticket #" + i + "</a><br1>");
+ }
+ tb.append("</center></body></html>");
+
+ NpcHtmlMessage nhm = new NpcHtmlMessage(5);
+ nhm.setHtml(tb.toString());
+ activeChar.sendPacket(nhm);
+ }
+
+ private static void sendBotInfoPage(L2PcInstance activeChar, int botId)
+ {
+ String[] report = BotManager.getInstance().getUnread().get(botId);
+ TextBuilder tb = new TextBuilder();
+
+ tb.append("<html><title>Bot #" + botId + "</title><body><center><br>");
+ tb.append("- Bot report ticket Id: <font color=FF0000>" + botId + "</font><br>");
+ tb.append("- Player reported: <font color=FF0000>" + report[0] + "</font><br>");
+ tb.append("- Reported by: <font color=FF0000>" + report[1] + "</font><br>");
+ tb.append("- Date: <font color=FF0000>" + report[2] + "</font><br>");
+ tb.append("<a action=\"bypass -h admin_markBotReaded " + botId + "\">Mark Report as Read</a>");
+ tb.append("<a action=\"bypass -h admin_punish_bot " + report[0] + "\">Punish " + report[0] + "</a>");
+ tb.append("<a action=\"bypass -h admin_checkBots\">Go Back to bot list</a>");
+ tb.append("</center></body></html>");
+
+ NpcHtmlMessage nhm = new NpcHtmlMessage(5);
+ nhm.setHtml(tb.toString());
+ activeChar.sendPacket(nhm);
+ }
+
+ /**
+ * Will introduce the first time a new punished bot in database,
+ * to avoid problems on his punish time left update, as will remove
+ * his reports from database
+ * @param L2PcInstance
+ */
+ private static void introduceNewPunishedBotAndClear(L2PcInstance target)
+ {
+ Connection con = null;
+ try
+ {
+
+ con = L2DatabaseFactory.getInstance().getConnection();
+ // Introduce new Punished Bot in database
+ PreparedStatement statement = con.prepareStatement("INSERT INTO bot_reported_punish VALUES ( ?, ?, ? )");
+ statement.setInt(1, target.getObjectId());
+ statement.setString(2, target.getPlayerPunish().getBotPunishType().name());
+ statement.setLong(3, target.getPlayerPunish().getPunishTimeLeft());
+ statement.execute();
+ statement.close();
+
+ // Delete all his reports from database
+ PreparedStatement delStatement = con.prepareStatement("DELETE FROM bot_report WHERE reported_objectId = ?");
+ delStatement.setInt(1, target.getObjectId());
+ delStatement.execute();
+ delStatement.close();
+ }
+ catch (SQLException sqle)
+ {
+ sqle.printStackTrace();
+ }
+ finally
+ {
+ try
+ {
+ con.close();
+ }
+ catch (SQLException e)
+ {
+ }
+ }
+ }
+}
Index: sql/accounts.sql
===================================================================
--- sql/accounts.sql (revision 7123)
+++ sql/accounts.sql (working copy)
@@ -11,5 +11,6 @@
`hop2` char(15) DEFAULT NULL,
`hop3` char(15) DEFAULT NULL,
`hop4` char(15) DEFAULT NULL,
+ `bot_report_points` int(10) NOT NULL DEFAULT 7,
PRIMARY KEY (`login`)
);
\ No newline at end of file
Index: sql/admin_command_access_rights.sql
===================================================================
--- sql/admin_command_access_rights.sql (revision 7123)
+++ sql/admin_command_access_rights.sql (working copy)
@@ -559,4 +559,10 @@
-- voice commands
('banchat','7'),
-('unbanchat','7');
\ No newline at end of file
+('unbanchat','7'),
+
+-- BOT REPORT
+('admin_checkBots', '1'),
+('admin_readBot', '1'),
+('admin_markBotReaded', '1'),
+('admin_punish_bot', '1');
\ No newline at end of file
Index: sql/bot_report.sql
===================================================================
--- sql/bot_report.sql (revision 0)
+++ sql/bot_report.sql (revision 0)
@@ -0,0 +1,10 @@
+CREATE TABLE IF NOT EXISTS `bot_report` (
+ `report_id` int(10) NOT NULL auto_increment,
+ `reported_name` varchar(45) DEFAULT NULL,
+ `reported_objectId` int(10) DEFAULT NULL,
+ `reporter_name` varchar(45) DEFAULT NULL,
+ `reporter_objectId` int(10) DEFAULT NULL,
+ `date` DECIMAL(20,0) NOT NULL default 0,
+ `read` enum('true','false') DEFAULT 'false' NOT NULL,
+ PRIMARY KEY (`report_id`)
+);
\ No newline at end of file
Index: sql/bot_reported_punish.sql
===================================================================
--- sql/bot_reported_punish.sql (revision 0)
+++ sql/bot_reported_punish.sql (revision 0)
@@ -0,0 +1,6 @@
+CREATE TABLE IF NOT EXISTS `bot_reported_punish` (
+ `charId` int(11) NOT NULL DEFAULT '0',
+ `punish_type` varchar(45) DEFAULT NULL,
+ `time_left` bigint(20) DEFAULT NULL,
+ PRIMARY KEY (`charId`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
\ No newline at end of file
Index: tools/database_installer.bat
===================================================================
--- tools/database_installer.bat (revision 7123)
+++ tools/database_installer.bat (working copy)
@@ -706,6 +706,8 @@
auto_announcements.sql
auto_chat.sql
auto_chat_text.sql
+bot_report.sql
+bot_reported_punish.sql
castle_door.sql
castle_doorupgrade.sql
castle_functions.sql
Creditos: BiggBoss