Сообщений: 3,354
Тем: 97
Зарегистрирован: Aug 2011
Репутация:
9,445
01-09-2014, 01:43 PM
(Сообщение последний раз редактировалось: 03-01-2014, 03:01 AM Ashe.)
Можете подсказать где бы взять исходники такого чуда, погуглил, но толком ничего не нашел, мб не так искал.
Под любые хроники под любую сборку, нужно просто для тестов.
Под фейкплеер - я подразумеваю фантомов/ботов/и прочую ересь, которая ведет себя в игре как игрок и запускается на стороне сервера.
Сообщений: 2,455
Тем: 53
Зарегистрирован: Apr 2010
Репутация:
19,728
01-09-2014, 01:55 PM
(Сообщение последний раз редактировалось: 03-01-2014, 02:54 AM Ashe.)
я идиот и написал не то, поэтому в спойлер это
Создаете инстанс L2PcInstance/L2Player (как угодно, от рандомных данных для него, до использования персонажей реальных игроков), делаете заглушку для NetworkClient'a, что бы при проверке ИП/операции дисконнекта/етц сторонним кодом (не фейк плеера) не выскакивало исключений. После чего аттачите к нему АИ, для чего придется таки запилить такой метод, с публичной видимостью и кушаете плоды
С АИ я надеюсь вопросов нет?
Более хороший вариант, это наследование от класса игрока и перегрузка нужных методов, плюс добавление своих (аналогично тому, что я написал выше), чтобы не раздувать еще сильнее и так безобразный класс игрока, который даже сейчас имеет 12к строк кода, минимум.
Дополнение. Я идиот, не понял суть вопроса D: Примеры можно увидеть в ребеллионе, гриндах, опенах. Если полуркать, то можно найти еще больше вариантов.
m0nster.art - clear client patches, linkz to utils & code.
Гадаю по капче.
Сообщений: 3,354
Тем: 97
Зарегистрирован: Aug 2011
Репутация:
9,445
01-09-2014, 02:09 PM
(Сообщение последний раз редактировалось: 03-01-2014, 02:54 AM Ashe.)
Pointer*Rage Написал:
я идиот и написал не то, поэтому в спойлер это
Создаете инстанс L2PcInstance/L2Player (как угодно, от рандомных данных для него, до использования персонажей реальных игроков), делаете заглушку для NetworkClient'a, что бы при проверке ИП/операции дисконнекта/етц сторонним кодом (не фейк плеера) не выскакивало исключений. После чего аттачите к нему АИ, для чего придется таки запилить такой метод, с публичной видимостью и кушаете плоды
С АИ я надеюсь вопросов нет?
Более хороший вариант, это наследование от класса игрока и перегрузка нужных методов, плюс добавление своих (аналогично тому, что я написал выше), чтобы не раздувать еще сильнее и так безобразный класс игрока, который даже сейчас имеет 12к строк кода, минимум.
Дополнение. Я идиот, не понял суть вопроса D: Примеры можно увидеть в ребеллионе, гриндах, опенах. Если полуркать, то можно найти еще больше вариантов. Спасибо за совет. Обязательно покопаю, просто хотелось бы более углубленно понять проблему с этими фейкплеерами на которые все грешат, что это боты.
Я не пишу, что хочу очеловечить их, но добавить хоть долю интеллекта в их развитие хотелось бы.
Сообщений: 2,455
Тем: 53
Зарегистрирован: Apr 2010
Репутация:
19,728
01-09-2014, 02:24 PM
(Сообщение последний раз редактировалось: 03-01-2014, 02:54 AM Ashe.)
xolseg Написал:Спасибо за совет. Обязательно покопаю, просто хотелось бы более углубленно понять проблему с этими фейкплеерами на которые все грешат, что это боты.
Я не пишу, что хочу очеловечить их, но добавить хоть долю интеллекта в их развитие хотелось бы.
Я боюсь у Вас не слишком это выедет. Хех.
Если допиливать само АИ фейков, то это огромная куча условий и рандома -> аверейдж и сложность реализации, да и сложность поддержания кода.
Эвристика? - Еще большая нагрузка, много больше, чем простая обработка условий.
С более или менее нормальными фейками сервер может так не хило аверейджить, причем доходит до бреда, что при 800 игроках, из которых хотя бы 60%-70% взаимодействуют с ботами, начинаются неимоверные лаги.
Проблемы начинают возникать из-за того, что в трид пуле АИ скапливается огромная очередь заданий, которые не могут выполниться за адекватное время. Тут есть целая куча вариантов, от костыля: разделить АИ пул для плееров и нпц/фейков (но тогда тормозить будут уже фейки и нпц) до хорошего: нужно к чертям переделывать АИ движек, менять тики мира, но... Все мы знаем, как говорится, но никто не делает и не собирается это делать.
Ах да. Проблема, кроме самого АИ движка еще возникает и в плане сети, т.к. все заглушки на нетворкклиент, которые я видел - были кривыми - пакет таки исполнялся в пуле пакетов сети, что тоже поддает жару, для обычных игроков.
К тому же следует учитывать, что доля трафика возрастет в разы, т.к. для фейков идет намного больше броадкастов пакетов, чем для обычного НПЦ, тем более с активным АИ. Следует учитывать максимально возможный онлайн с числом фейков, т.к. они тоже нагружают сеть, как и игроки (хоть и не так сильно, т.к. существует инактив состояние АИ, плюс временные деатачи АИ).
m0nster.art - clear client patches, linkz to utils & code.
Гадаю по капче.
Сообщений: 3,354
Тем: 97
Зарегистрирован: Aug 2011
Репутация:
9,445
01-09-2014, 02:36 PM
(Сообщение последний раз редактировалось: 03-01-2014, 02:54 AM Ashe.)
Pointer*Rage Написал:Я боюсь у Вас не слишком это выедет. Хех.
Если допиливать само АИ фейков, то это огромная куча условий и рандома -> аверейдж и сложность реализации, да и сложность поддержания кода.
Эвристика? - Еще большая нагрузка, много больше, чем простая обработка условий.
С более или менее нормальными фейками сервер может так не хило аверейджить, причем доходит до бреда, что при 800 игроках, из которых хотя бы 60%-70% взаимодействуют с ботами, начинаются неимоверные лаги.
Проблемы начинают возникать из-за того, что в трид пуле АИ скапливается огромная очередь заданий, которые не могут выполниться за адекватное время. Тут есть целая куча вариантов, от костыля: разделить АИ пул для плееров и нпц/фейков (но тогда тормозить будут уже фейки и нпц) до хорошего: нужно к чертям переделывать АИ движек, менять тики мира, но... Все мы знаем, как говорится, но никто не делает и не собирается это делать.
Я не знаю, по этому и задаю такие вопросы.
Хорошо зайдем с другого бока,... есть некий нпц которые эмулирует человека, т.е.
1. Он ходит убивает мобов
2. Он ходит выполняет задания которые дают нпц
3. Он получает профессию.
4. Он может войти в пати и обучатся по мере роста навыков и заложенного в него кода
5. Он может создать клан для таких же ботов как и он и фармить рб.
6. Он может убить игрока, при условии что на него началась агрессия
7. Он может крафтить вещи и продавать их на рынке анализируя этот рынок по средствам "аукциона".
Возьмем этот минимум.
А теперь, у меня возник вопрос, есть некий пул задач которые способен выполнить бот, каким образом сервер будет обрабатывать эти задачи/задания?
Возьмем допустим 1 задачу, убийство мобов, нпц попадает в локацию и начинает истреблять мобов, куда пападает эта задача и как она обрабатывается?
Я понимаю, что данные попадают в тредпул АИ и он имеет свои ограничения, но нельзя его расширить/разделить, сделать слоями в конце концов или я что то не верно понимаю?
Сообщений: 74
Тем: 3
Зарегистрирован: Nov 2013
01-09-2014, 02:40 PM
(Сообщение последний раз редактировалось: 03-01-2014, 01:38 PM PROGRAMMATOR.)
ну в общем как-то так))
Phantoms
package gameserver.model;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import javolution.text.TextBuilder;
import javolution.util.FastList;
import javolution.util.FastMap;
import org.apache.log4j.Logger;
import gameserver.model.base.InvisibleType;
import gameserver.Config;
import gameserver.ThreadPoolManager;
import gameserver.database.DatabaseFactory;
import gameserver.ai.CtrlIntention;
import gameserver.model.items.ItemInstance;
import gameserver.utils.ItemFunctions;
import gameserver.utils.Location;
import commons.util.Rnd;
import gameserver.ai.PlayableAI;
import gameserver.geodata.GeoEngine;
import gameserver.model.base.Race;
import gameserver.model.instances.NpcInstance;
import gameserver.network.game.send.L2GameServerPacket;
import gameserver.network.game.send.MagicSkillUse;
import gameserver.network.game.send.Say2;
import gameserver.network.game.send.components.ChatType;
import gameserver.skills.AbnormalEffect;
import gameserver.data.tables.SkillTable;
import gameserver.templates.PlayerTemplate;
import gameserver.templates.item.ItemTemplate;
import gameserver.templates.item.CreateItem;
public class PhantomPlayers {
private static final Logger _log = Logger.getLogger(PhantomPlayers.class.getName());
private static String _phantomAcc = Config.PHANTOM_PLAYERS_AKK;
private static int _PhantomsCount = 0;
private static int _PhantomsLimit = 0;
private static int _setsCount = 0;
private static int _setsCountClan = 0;
private static int _nameColCount = 0;
private static int _titleColCount = 0;
private static int _setsArcherCount = 0;
private static int _setsOlyCount = 0;
private static int _locsCount = 0;
private static int _PhantomsEnchPhsCount = 0;
private static int _PhantomsLastPhsCount = 0;
private volatile int _PhantomsTownTotal;
private static FastList<Integer> _nameColors = new FastList();
private static FastList<Integer> _titleColors = new FastList();
private static FastList<L2Set> _sets = new FastList();
private static FastList<L2Set> _setsArcher = new FastList();
private static FastList<L2Set> _setsOly = new FastList();
private static FastList<Location> _PhantomsTownLoc = new FastList();
private static FastList<String> _PhantomsEnchPhrases = new FastList();
private static FastList<String> _PhantomsLastPhrases = new FastList();
private static FastMap<Integer, L2Fantome> _phantoms = new FastMap();
private static PhantomPlayers _instance;
private static Map<Integer, ConcurrentLinkedQueue<Player>> _PhantomsTown = new ConcurrentHashMap();
private static Map<Integer, ConcurrentLinkedQueue<Player>> _PhantomsTownClan = new ConcurrentHashMap();
private static Map<Integer, ConcurrentLinkedQueue<Integer>> _PhantomsTownClanList = new ConcurrentHashMap();
private static final int[][] _mageBuff = {{6, 75, 4322, 1}, {6, 75, 4323, 1}, {6, 75, 5637, 1}, {6, 75, 4328, 1}, {6, 75, 4329, 1}, {6, 75, 4330, 1}, {6, 75, 4331, 1}, {16, 34, 4338, 1}};
private static final int[][] _warrBuff = {{6, 75, 4322, 1}, {6, 75, 4323, 1}, {6, 75, 5637, 1}, {6, 75, 4324, 1}, {6, 75, 4325, 1}, {6, 75, 4326, 1}, {6, 39, 4327, 1}, {40, 75, 5632, 1}, {16, 34, 4338, 1}};
private static final int[] _buffers = {30598, 30599, 30600, 30601, 30602, 32135};
public PhantomPlayers()
{
_PhantomsTownTotal = 0;
}
public static PhantomPlayers getInstance()
{
return _instance;
}
public static void init()
{
_instance = new PhantomPlayers();
_instance.load();
}
private void load()
{
parceArmors();
parceArcherArmors();
parceOlyArmors();
parceColors();
cacheLastPhrases();
if (Config.ALLOW_PHANTOM_PLAYERS)
{
parceTownLocs();
parceTownClans();
cacheFantoms();
cacheEnchantPhrases();
_PhantomsLimit = Config.PHANTOM_PLAYERS_COUNT_FIRST + Config.PHANTOM_PLAYERS_COUNT_NEXT + 10;
_PhantomsTown.put(Integer.valueOf(1), new ConcurrentLinkedQueue());
_PhantomsTown.put(Integer.valueOf(2), new ConcurrentLinkedQueue());
}
}
private void cacheFantoms()
{
new Thread(new Runnable()
{
@Override
public void run()
{
String name = "";
String new_name = "";
Connection con = null;
Object localObject1 = null;
try
{
con = DatabaseFactory.getInstance().getConnection();
con.setTransactionIsolation(1);
PreparedStatement st = con.prepareStatement("SELECT obj_Id,char_name,title,x,y,z,clanid FROM characters WHERE account_name = ?");
st.setString(1, _phantomAcc);
ResultSet rs = st.executeQuery();
rs.setFetchSize(250);
while (rs.next())
{
name = rs.getString("char_name");
_phantoms.put(Integer.valueOf(rs.getInt("obj_Id")) , new L2Fantome(name, rs.getString("title"), rs.getInt("x"), rs.getInt("y"), rs.getInt("z"), rs.getInt("clanid")));
}
st.close();
rs.close();
con.close();
_log.info("PhantomPlayers: Cached " + _phantoms.size() + " players.");
}
catch (SQLException e)
{
_log.warn("PhantomPlayers: could not load chars from DB: " + e);
}
finally
{
if (con != null)
{
con = null;
}
}
if (!_phantoms.isEmpty())
{
ThreadPoolManager.getInstance().schedule(new FantomTask(1), Config.PHANTOM_PLAYERS_DELAY_FIRST * 1000L);
}
}
}).start();
}
private void parceArmors()
{
if (!_sets.isEmpty())
{
_sets.clear();
}
LineNumberReader lnr = null;
BufferedReader br = null;
FileReader fr = null;
try
{
File Data = new File("./config/phantomold/town_sets.ini");
if (!Data.exists())
{
return;
}
fr = new FileReader(Data);
br = new BufferedReader(fr);
lnr = new LineNumberReader(br);
String line;
while ((line = lnr.readLine()) != null)
{
if ((line.trim().length() != 0) && (!line.startsWith("#")))
{
String[] items = line.split(",");
int custom = 0;
try
{
custom = Integer.parseInt(items[5]);
}
catch (NumberFormatException e)
{
custom = 0;
}
_sets.add(new L2Set(Integer.parseInt(items[0]), Integer.parseInt(items[1]), Integer.parseInt(items[2]), Integer.parseInt(items[3]), Integer.parseInt(items[4]), Integer.parseInt(items[5]), custom));
}
}
_setsCount = _sets.size() - 1;
_log.info("Load " + _setsCount + " phantom armor sets");
}
catch (IOException | NumberFormatException e)
{
//
}
finally
{
try
{
if (fr != null)
{
fr.close();
}
if (br != null)
{
br.close();
}
if (lnr != null)
{
lnr.close();
}
}
catch (IOException e)
{
//
}
}
}
private void parceArcherArmors()
{
if (!_setsArcher.isEmpty())
{
_setsArcher.clear();
}
LineNumberReader lnr = null;
BufferedReader br = null;
FileReader fr = null;
try
{
File Data = new File("./config/phantomold/archer_sets.ini");
if (!Data.exists())
{
return;
}
fr = new FileReader(Data);
br = new BufferedReader(fr);
lnr = new LineNumberReader(br);
String line;
while ((line = lnr.readLine()) != null)
{
if ((line.trim().length() != 0) && (!line.startsWith("#")))
{
String[] items = line.split(",");
int custom = 0;
try
{
custom = Integer.parseInt(items[5]);
}
catch (NumberFormatException e)
{
custom = 0;
}
_setsArcher.add(new L2Set(Integer.parseInt(items[0]), Integer.parseInt(items[1]), Integer.parseInt(items[2]), Integer.parseInt(items[3]), Integer.parseInt(items[4]), Integer.parseInt(items[5]), custom));
}
}
_setsArcherCount = _setsArcher.size() - 1;
_log.info("Load " + _setsArcherCount + " Aecher phantom armor sets");
}
catch (IOException | NumberFormatException e)
{
//
}
finally
{
try
{
if (fr != null)
{
fr.close();
}
if (br != null)
{
br.close();
}
if (lnr != null)
{
lnr.close();
}
}
catch (IOException e)
{
//
}
}
}
private void parceOlyArmors()
{
if (!_setsOly.isEmpty())
{
_setsOly.clear();
}
LineNumberReader lnr = null;
BufferedReader br = null;
FileReader fr = null;
try
{
File Data = new File("./config/phantomold/oly_sets.ini");
if (!Data.exists())
{
return;
}
fr = new FileReader(Data);
br = new BufferedReader(fr);
lnr = new LineNumberReader(br);
String line;
while ((line = lnr.readLine()) != null)
{
if ((line.trim().length() != 0) && (!line.startsWith("#")))
{
String[] items = line.split(",");
int custom = 0;
try
{
custom = Integer.parseInt(items[6]);
}
catch (NumberFormatException e)
{
custom = 0;
}
_setsOly.add(new L2Set(Integer.parseInt(items[0]), Integer.parseInt(items[1]), Integer.parseInt(items[2]), Integer.parseInt(items[3]), Integer.parseInt(items[4]), Integer.parseInt(items[5]), custom));
}
}
_setsOlyCount = _setsOly.size() - 1;
_log.info("Load " + _setsOlyCount + " phantom Only armor sets");
}
catch (IOException | NumberFormatException e)
{
//
}
finally
{
try {
if (fr != null) {
fr.close();
}
if (br != null) {
br.close();
}
if (lnr != null) {
lnr.close();
}
} catch (IOException e) {
}
}
}
private void parceTownClans() {
LineNumberReader lnr = null;
BufferedReader br = null;
FileReader fr = null;
try {
File Data = new File("./config/phantomold/town_clans.ini");
if (!Data.exists()) {
return;
}
fr = new FileReader(Data);
br = new BufferedReader(fr);
lnr = new LineNumberReader(br);
int clanId = 0;
String line;
while ((line = lnr.readLine()) != null) {
if ((line.trim().length() != 0) && (!line.startsWith("#"))) {
String[] items = line.split(":");
clanId = Integer.parseInt(items[0]);
String[] pls = items[1].split(",");
ConcurrentLinkedQueue players = new ConcurrentLinkedQueue();
for (String plid : pls) {
players.add(Integer.valueOf(Integer.parseInt(plid) ));
}
_PhantomsTownClanList.put(Integer.valueOf(clanId), players);
}
}
_setsCountClan = _PhantomsTownClanList.size() - 1;
_log.info("Load " + _setsCountClan + " phantom Clans");
} catch (IOException | NumberFormatException e) {
} finally {
try {
if (fr != null) {
fr.close();
}
if (br != null) {
br.close();
}
if (lnr != null) {
lnr.close();
}
} catch (IOException e1) {
}
}
}
private void parceTownLocs() {
_PhantomsTownLoc.clear();
LineNumberReader lnr = null;
BufferedReader br = null;
FileReader fr = null;
try {
File Data = new File("./config/phantomold/town_locs.ini");
if (!Data.exists()) {
return;
}
fr = new FileReader(Data);
br = new BufferedReader(fr);
lnr = new LineNumberReader(br);
String line;
while ((line = lnr.readLine()) != null) {
if ((line.trim().length() != 0) && (!line.startsWith("#"))) {
String[] items = line.split(",");
_PhantomsTownLoc.add(new Location(Integer.parseInt(items[0]), Integer.parseInt(items[1]), Integer.parseInt(items[2])));
}
}
_locsCount = _PhantomsTownLoc.size() - 1;
_log.info("Load " + _locsCount + " phantom Town Locations");
} catch (IOException | NumberFormatException e) {
} finally {
try {
if (fr != null) {
fr.close();
}
if (br != null) {
br.close();
}
if (lnr != null) {
lnr.close();
}
} catch (IOException e1) {
}
}
}
public void startWalk(Player phantom) {
ThreadPoolManager.getInstance().schedule(new PhantomWalk(phantom), 10000L);
}
private void cacheEnchantPhrases() {
_PhantomsEnchPhrases.clear();
LineNumberReader lnr = null;
BufferedReader br = null;
FileReader fr = null;
try {
File Data = new File("./config/phantomold/phrases_enchant.txt");
if (!Data.exists()) {
return;
}
fr = new FileReader(Data);
br = new BufferedReader(fr);
lnr = new LineNumberReader(br);
String line;
while ((line = lnr.readLine()) != null) {
if ((line.trim().length() != 0) && (!line.startsWith("#"))) {
_PhantomsEnchPhrases.add(line);
}
}
_PhantomsEnchPhsCount = _PhantomsEnchPhrases.size() - 1;
_log.info("Load " + _PhantomsEnchPhsCount + " phantom Ench");
} catch (IOException e) {
} finally {
try {
if (fr != null) {
fr.close();
}
if (br != null) {
br.close();
}
if (lnr != null) {
lnr.close();
}
} catch (IOException e1) {
}
}
}
private void cacheLastPhrases() {
_PhantomsLastPhrases.clear();
LineNumberReader lnr = null;
BufferedReader br = null;
FileReader fr = null;
try {
File Data = new File("./config/phantomold/phrases_last.ini");
if (!Data.exists()) {
return;
}
fr = new FileReader(Data);
br = new BufferedReader(fr);
lnr = new LineNumberReader(br);
String line;
while ((line = lnr.readLine()) != null) {
if ((line.trim().length() != 0) && (!line.startsWith("#"))) {
_PhantomsLastPhrases.add(line);
}
}
_PhantomsLastPhsCount = _PhantomsLastPhrases.size() - 1;
_log.info("Load " + _PhantomsLastPhsCount + " phantom Last");
} catch (IOException e) {
} finally {
try {
if (fr != null) {
fr.close();
}
if (br != null) {
br.close();
}
if (lnr != null) {
lnr.close();
}
} catch (IOException e1) {
}
}
}
private void parceColors() {
_nameColors = Config.PHANTOM_PLAYERS_NAME_CLOLORS;
_titleColors = Config.PHANTOM_PLAYERS_TITLE_CLOLORS;
_nameColCount = _nameColors.size() - 1;
_titleColCount = _titleColors.size() - 1;
}
private L2Set getRandomSet() {
return (L2Set) _sets.get(Rnd.get(_setsCount));
}
private L2Set getRandomArcherSet() {
return (L2Set) _setsArcher.get(Rnd.get(_setsArcherCount));
}
private int getRandomPhantom() {
return Rnd.get(600000000, 600006081);
}
private int getRandomPhantomNext() {
for (int i = 6; i > 0; i--) {
int obj = Rnd.get(600000000, 600006081);
if ((!((ConcurrentLinkedQueue) _PhantomsTown.get(Integer.valueOf(1))).contains(In teger.valueOf(obj))) && (!((ConcurrentLinkedQueue) _PhantomsTown.get(Integer.valueOf(2))).contains(In teger.valueOf(obj)))) {
return obj;
}
}
return getRandomPhantomNext();
}
private int getRandomClan() {
return Rnd.get(600000000, 600006081);
}
private Location getRandomLoc() {
Location loc = null;
if (loc == null) {
loc = (Location) _PhantomsTownLoc.get(Rnd.get(0, _locsCount));
}
return loc;
}
private Player loadPhantom(int objId) {
int nbPlayerIG = GameObjectsStorage.getAllPlayersCount();
if (nbPlayerIG < Config.MAXIMUM_ONLINE_USERS) {
L2Fantome phantom = (L2Fantome) _phantoms.get(Integer.valueOf(objId));
if (phantom == null) {
return null;
}
L2Set set = getRandomSet();
ItemInstance body = null;
ItemInstance gaiters = null;
ItemInstance gloves = null;
ItemInstance boots = null;
ItemInstance weapon = null;
if (set._body != 0) {
body = ItemFunctions.createItem(set._body);
}
if (set._gaiters != 0) {
gaiters = ItemFunctions.createItem(set._gaiters);
}
if (set._gloves != 0) {
gloves = ItemFunctions.createItem(set._gloves);
}
if (set._boots != 0) {
boots = ItemFunctions.createItem(set._boots);
}
if (set._weapon != 0) {
weapon = ItemFunctions.createItem(set._weapon);
}
ItemInstance custom = null;
int grade = set._grade;
int setLevel = 1;
int classId = 0;
if (grade == 0) {
setLevel = Rnd.get(1, 19);
}
if (grade == 1) {
setLevel = Rnd.get(20, 39);
}
if (grade == 2) {
setLevel = Rnd.get(40, 51);
}
if (grade == 3) {
setLevel = Rnd.get(52, 60);
}
if (grade == 4) {
setLevel = Rnd.get(61, 75);
}
if (grade == 5) {
setLevel = Rnd.get(76, 85);
}
Player localPlayer = Player.restorePhantom(objId, setLevel, classId, false);
localPlayer.setOfflineMode(false);
localPlayer.setIsOnline(true);
//fantom.updateOnlineStatus();
Location loc = getRandomLoc();
localPlayer.setPhantomLoc(loc.getX(), loc.getY(), loc.getZ());
localPlayer.setXYZ(loc.getX() + Rnd.get(60), loc.getY() + Rnd.get(60), loc.getZ());
Location loc1 = new Location(loc.getX() + Rnd.get(350), loc.getY() + Rnd.get(350), loc.getZ());
localPlayer.setOnlineStatus(true);
localPlayer.setInvisibleType(InvisibleType.NONE);
localPlayer.setNonAggroTime(9223372036854775807L);
localPlayer.spawnMe(loc1);
localPlayer.setCurrentHpMp(localPlayer.getMaxHp(), localPlayer.getMaxMp());
localPlayer.setCurrentCp(localPlayer.getMaxCp());
if ((Config.ALLOW_PHANTOM_SETS) && (localPlayer.getClassId().getRace() != Race.kamael)) {
if (body != null) {
localPlayer.getInventory().addItem(body);
localPlayer.getInventory().equipItem(body);
}
if (gaiters != null) {
localPlayer.getInventory().addItem(gaiters);
localPlayer.getInventory().equipItem(gaiters);
}
if (gloves != null) {
localPlayer.getInventory().addItem(gloves);
localPlayer.getInventory().equipItem(gloves);
}
if (boots != null) {
localPlayer.getInventory().addItem(boots);
localPlayer.getInventory().equipItem(boots);
}
if (weapon != null) {
localPlayer.getInventory().addItem(weapon);
localPlayer.getInventory().equipItem(weapon);
}
}
if ((!Config.ALLOW_PHANTOM_SETS) || (localPlayer.getClassId().getRace() == Race.kamael)) {
PlayerTemplate template = localPlayer.getTemplate();
for (ItemTemplate i : template.getItems()) {
ItemInstance item = ItemFunctions.createItem(i.getItemId());
localPlayer.getInventory().addItem(item);
if ((i.isEquipable()) && (item.isEquipable()) && ((localPlayer.getActiveWeaponItem() == null) || (item.getTemplate().getType2() != 0))) {
localPlayer.getInventory().equipItem(item);
}
}
}
localPlayer.broadcastCharInfo();
localPlayer.rndWalk();
startWalk(localPlayer);
return localPlayer;
}
return null;
}
private String getRandomEnchantPhrase() {
return (String) _PhantomsEnchPhrases.get(Rnd.get(_PhantomsEnchPhsC ount));
}
public String getRandomLastPhrase() {
return (String) _PhantomsLastPhrases.get(Rnd.get(_PhantomsLastPhsC ount));
}
private int getNameColor() {
return ((Integer) _nameColors.get(Rnd.get(_nameColCount))).intValue( );
}
private int getTitleColor() {
return ((Integer) _titleColors.get(Rnd.get(_titleColCount))).intValu e();
}
public class Social
implements Runnable {
public Social() {
}
@Override
public void run() {
TextBuilder tb = new TextBuilder();
for (Map.Entry<Integer, ConcurrentLinkedQueue<Player>> entry : _PhantomsTown.entrySet()) {
Integer wave = entry.getKey();
ConcurrentLinkedQueue<Player> players = entry.getValue();
if ((wave != null) && (players != null) && (!players.isEmpty())) {
int count = 0;
for (Player player : players) {
if (Rnd.get(100) < 65) {
switch (Rnd.get(2)) {
case 0:
case 1:
ItemInstance wpn = player.getActiveWeaponInstance();
int enhchant = wpn.getEnchantLevel();
int nextench = enhchant + 1;
if ((Rnd.get(100) < 45) && (enhchant <= Config.PHANTOM_PLAYERS_ENCHANT_MAX)) {
wpn.setEnchantLevel(nextench);
} else if (Rnd.get(100) < 70) {
wpn.setEnchantLevel(3);
if ((nextench > 13) && (Rnd.get(100) < 2)) {
tb.append("!");
for (int i = Rnd.get(2, 13); i > 0; i--) {
tb.append("!");
}
tb.clear();
}
}
player.broadcastUserInfo(true);
break;
case 2:
if (Rnd.get(100) < 5) {
player.moveToLocation(player.getX() + Rnd.get(30), player.getY() + Rnd.get(30), player.getZ(), 40, true);
player.getAI().setNextAction(PlayableAI.nextAction .INTERACT, null, null, false, false);
}
break;
}
sleep(Rnd.get(500, 1500));
count++;
}
if (count > 55) {
break;
}
}
}
}
tb.clear();
ThreadPoolManager.getInstance().schedule(new Social(), 12000L);
}
}
public class CheckCount
implements Runnable {
public CheckCount() {
}
@Override
public void run() {
for (Map.Entry<Integer, ConcurrentLinkedQueue<Player>> entry : _PhantomsTown.entrySet()) {
Integer wave = entry.getKey();
ConcurrentLinkedQueue<Player> players = entry.getValue();
if ((wave != null) && (players != null) && (!players.isEmpty())) {
int limit = wave.intValue() == 1 ? Config.PHANTOM_PLAYERS_COUNT_FIRST : Config.PHANTOM_PLAYERS_COUNT_NEXT;
int overflow = players.size() - limit;
if (overflow >= 1) {
for (Player fantom : players) {
fantom.setOnlineStatus(false);
((ConcurrentLinkedQueue) _PhantomsTown.get(wave)).remove(fantom);
overflow--;
if (overflow == 0) {
break;
}
}
}
}
}
ThreadPoolManager.getInstance().schedule(new CheckCount(), 300000L);
}
}
public class FantomTaskDespawn
implements Runnable {
public int _task;
public FantomTaskDespawn(int task) {
_task = task;
}
@Override
public void run() {
ConcurrentLinkedQueue<Player> players = _PhantomsTown.get(_task);
for (Player fantom : players) {
if (fantom != null) {
Location loc = fantom.getPhantomLoc();
fantom.setOnlineStatus(false);
((ConcurrentLinkedQueue) _PhantomsTown.get(Integer.valueOf(_task))).remove( fantom);
sleep(_task == 1 ? Config.PHANTOM_PLAYERS_DELAY_DESPAWN_FIRST : Config.PHANTOM_PLAYERS_DELAY_DESPAWN_NEXT);
if (_PhantomsTownTotal <= _PhantomsLimit) {
int nextObjId = getRandomPhantomNext();
if (!((ConcurrentLinkedQueue) _PhantomsTown.get(Integer.valueOf(_task))).contain s(Integer.valueOf(nextObjId))) {
Player next = loadPhantom(nextObjId);
if (next != null) {
((ConcurrentLinkedQueue) _PhantomsTown.get(Integer.valueOf(_task))).add(nex t);
if ((Config.PHANTOM_PLAYERS_SOULSHOT_ANIM) && (Rnd.get(100) < 45)) {
sleep(900L);
if (Rnd.get(100) < 3) {
next.sitDown(null);
}
next.broadcastPacket(new MagicSkillUse(next, next, 2154, 1, 0, 0L));
sleep(300L);
next.broadcastPacket(new MagicSkillUse(next, next, 2164, 1, 0, 0L));
}
sleep(100L);
}
}
}
}
}
ThreadPoolManager.getInstance().schedule(new FantomTaskDespawn(1), _task == 1 ? Config.PHANTOM_PLAYERS_DESPAWN_FIRST : Config.PHANTOM_PLAYERS_DESPAWN_NEXT);
}
}
public class FantomTask
implements Runnable {
public int _task;
public FantomTask(int task) {
_task = task;
}
@Override
public void run() {
int count = 0;
int count2 = 0;
int PhantomObjId = 0;
int PhantomObjId2 = 0;
switch (_task) {
case 1:
_log.info("PhantomPlayers: 1st wave, spawn started.");
while (count < Config.PHANTOM_PLAYERS_COUNT_FIRST) {
PhantomObjId = getRandomPhantomNext();
if (!((ConcurrentLinkedQueue) _PhantomsTown.get(Integer.valueOf(1))).contains(In teger.valueOf(PhantomObjId))) {
Player fantom = loadPhantom(PhantomObjId);
if (fantom != null) {
((ConcurrentLinkedQueue) _PhantomsTown.get(Integer.valueOf(1))).add(fantom) ;
if ((Config.PHANTOM_PLAYERS_SOULSHOT_ANIM) && (Rnd.get(100) < 45)) {
sleep(900L);
if (Rnd.get(100) < 5) {
fantom.sitDown(null);
}
if (Rnd.get(100) < 30) {
fantom.startAbnormalEffect(AbnormalEffect.S_NAVIT) ;
}
sleep(300L);
}
sleep(Config.PHANTOM_PLAYERS_DELAY_SPAWN_FIRST);
count++;
}
}
}
_log.info("FPhantomPlayers: 1st wave, spawned " + count + " players.");
ThreadPoolManager.getInstance().schedule(new FantomTaskDespawn(1), Config.PHANTOM_PLAYERS_DESPAWN_FIRST);
ThreadPoolManager.getInstance().schedule(new FantomTask(2), Config.PHANTOM_PLAYERS_DELAY_NEXT);
ThreadPoolManager.getInstance().schedule(new Social(), 12000L);
ThreadPoolManager.getInstance().schedule(new CheckCount(), 300000L);
break;
case 2:
_log.info("PhantomPlayers: 2nd wave, spawn started.");
while (count2 < Config.PHANTOM_PLAYERS_COUNT_NEXT) {
PhantomObjId2 = getRandomPhantomNext();
if ((!((ConcurrentLinkedQueue) _PhantomsTown.get(Integer.valueOf(1))).contains(In teger.valueOf(PhantomObjId2))) || (!((ConcurrentLinkedQueue) _PhantomsTown.get(Integer.valueOf(2))).contains(In teger.valueOf(PhantomObjId2)))) {
Player fantom2 = loadPhantom(PhantomObjId2);
if (fantom2 != null) {
((ConcurrentLinkedQueue) _PhantomsTown.get(Integer.valueOf(2))).add(fantom2 );
if ((Config.PHANTOM_PLAYERS_SOULSHOT_ANIM) && (Rnd.get(100) < 45)) {
sleep(900L);
if (Rnd.get(100) < 3) {
fantom2.sitDown(null);
}
fantom2.broadcastPacket(new L2GameServerPacket[]{new MagicSkillUse(fantom2, fantom2, 2154, 1, 0, 0L)});
sleep(300L);
fantom2.broadcastPacket(new L2GameServerPacket[]{new MagicSkillUse(fantom2, fantom2, 2164, 1, 0, 0L)});
}
sleep(Config.PHANTOM_PLAYERS_DELAY_SPAWN_NEXT);
count2++;
}
}
}
_log.info("PhantomPlayers: 2nd wave, spawned " + count2 + " players.");
ThreadPoolManager.getInstance().schedule(new FantomTaskDespawn(2), Config.PHANTOM_PLAYERS_DESPAWN_NEXT);
}
}
}
static class L2Fantome {
public String name;
public String title;
public int x;
public int y;
public int z;
public int clanId;
L2Fantome(String name, String title, int x, int y, int z, int clanId) {
this.name = name;
this.title = title;
this.x = x;
this.y = y;
this.z = z;
this.clanId = clanId;
}
}
static class L2Set {
public int _body;
public int _gaiters;
public int _gloves;
public int _boots;
public int _weapon;
public int _custom;
public int _grade;
L2Set(int bod, int gaiter, int glove, int boot, int weapon, int grade, int custom) {
_body = bod;
_gaiters = gaiter;
_gloves = glove;
_boots = boot;
_weapon = weapon;
_grade = grade;
_custom = custom;
}
}
private class PhantomWalk
implements Runnable {
Player _phantom;
public PhantomWalk(Player phantom) {
_phantom = phantom;
}
@Override
public void run() {
if (_phantom.isDead()) {
_phantom.kick();
}
if (_phantom.isInWater()) {
_phantom.teleToClosestTown();
}
if ((Rnd.get(100) < 10)
&& (Rnd.get(100) < 10)
&& (_phantom.isSitting())) {
_phantom.standUp();
}
if (Rnd.get(100) < 80) {
for (NpcInstance npc : World.getAroundNpc(_phantom, 100, 100)) {
for (int buffers_id : _buffers) {
if ((npc.getNpcId() == buffers_id) && (!_phantom.isSitting())) {
if ((!_phantom.getClassId().isMage()) || (_phantom.getClassId().getRace() == Race.orc)) {
for (int[] buff : _warrBuff) {
npc.broadcastPacket(new L2GameServerPacket[]{new MagicSkillUse(npc, _phantom, buff[2], buff[3], 0, 0L)});
}
}
if ((_phantom.getClassId().isMage()) && (_phantom.getClassId().getRace() != Race.orc)) {
for (int[] buff : _mageBuff) {
npc.broadcastPacket(new L2GameServerPacket[]{new MagicSkillUse(npc, _phantom, buff[2], buff[3], 0, 0L)});
}
}
}
}
}
}
Say2 cs3;
if (Rnd.get(100) < 5) {
Say2 cs;
Say2 cs2;
switch (Rnd.get(1, 3)) {
case 1:
cs = new Say2(_phantom.getObjectId(), ChatType.SHOUT, _phantom.getName(), getRandomEnchantPhrase());
for (Player player : World.getAroundPlayers(_phantom, 10000, 3000)) {
if ((player != null)
&& (!player.isBlockAll())) {
player.sendPacket(cs);
}
}
break;
case 2:
cs2 = new Say2(_phantom.getObjectId(), ChatType.TRADE, _phantom.getName(), getRandomEnchantPhrase());
for (Player player : World.getAroundPlayers(_phantom, 5000, 2000)) {
if ((player != null)
&& (!player.isBlockAll())) {
player.sendPacket(cs2);
}
}
break;
case 3:
cs3 = new Say2(_phantom.getObjectId(), ChatType.ALL, _phantom.getName(), getRandomEnchantPhrase());
for (Player player : World.getAroundPlayers(_phantom, 1200, 1000)) {
if ((player != null)
&& (!player.isBlockAll())) {
player.sendPacket(cs3);
}
}
}
}
if (Rnd.get(100) < 10) {
if ((!_phantom.getClassId().isMage()) || (_phantom.getClassId().getRace() == Race.orc)) {
_phantom.broadcastPacket(new L2GameServerPacket[]{new MagicSkillUse(_phantom, _phantom, 2153, 1, 0, 0L)});
}
if ((_phantom.getClassId().isMage()) && (_phantom.getClassId().getRace() != Race.orc)) {
_phantom.broadcastPacket(new L2GameServerPacket[]{new MagicSkillUse(_phantom, _phantom, 2158, 1, 0, 0L)});
}
}
if (Rnd.get(100) < 70) {
if ((!_phantom.getClassId().isMage()) || (_phantom.getClassId().getRace() == Race.orc)) {
for (Player player : World.getAroundPlayers(_phantom, 100, 100)) {
if ((GeoEngine.canSeeTarget(_phantom, player, false)) && (!player.isDead()) && (!player.isInZonePeace()) && (!_phantom.isInZonePeace()) && ((player.getKarma() != 0) || (player.getPvpFlag() > 0))) {
if (_phantom.getRealDistance3D(player) <= _phantom.getPhysicalAttackRange() + 40) {
_phantom.getAI().setIntention(CtrlIntention.AI_INT ENTION_ATTACK, player);
sleep(500L);
if (_phantom.getClassId().getRace() == Race.human) {
_phantom.doCast(SkillTable.getInstance().getInfo(3 , 2), player, true);
}
if (_phantom.getClassId().getRace() == Race.elf) {
_phantom.doCast(SkillTable.getInstance().getInfo(3 , 2), player, true);
}
if (_phantom.getClassId().getRace() == Race.darkelf) {
_phantom.doCast(SkillTable.getInstance().getInfo(3 , 2), player, true);
}
if (_phantom.getClassId().getRace() == Race.orc) {
_phantom.doCast(SkillTable.getInstance().getInfo(2 9, 2), player, true);
}
if (_phantom.getClassId().getRace() == Race.dwarf) {
_phantom.getAI().setIntention(CtrlIntention.AI_INT ENTION_ATTACK, player);
}
if (_phantom.getClassId().getRace() == Race.kamael) {
_phantom.doCast(SkillTable.getInstance().getInfo(4 68, 2), player, true);
}
sleep(500L);
_phantom.getAI().setIntention(CtrlIntention.AI_INT ENTION_ATTACK, player);
} else {
sleep(500L);
}
_phantom.getAI().setIntention(CtrlIntention.AI_INT ENTION_ATTACK, player);
}
}
}
if ((_phantom.getClassId().isMage()) && (_phantom.getClassId().getRace() != Race.orc)) {
for (Player player : World.getAroundPlayers(_phantom, 100, 100)) {
if ((GeoEngine.canSeeTarget(_phantom, player, false)) && (!player.isDead()) && (!player.isInZonePeace()) && (!_phantom.isInZonePeace()) && ((player.getKarma() != 0) || (player.getPvpFlag() > 0))) {
_phantom.getAI().setIntention(CtrlIntention.AI_INT ENTION_ATTACK, player);
_phantom.doCast(SkillTable.getInstance().getInfo(1 177, 2), player, true);
}
}
}
}
if (Rnd.get(100) < 10) {
if ((!_phantom.getClassId().isMage()) || (_phantom.getClassId().getRace() == Race.orc)) {
for (NpcInstance npc : World.getAroundNpc(_phantom, 800, 200)) {
if ((GeoEngine.canSeeTarget(_phantom, npc, false)) && (npc.isMonster()) && (!npc.isDead())) {
_phantom.getAI().setIntention(CtrlIntention.AI_INT ENTION_ATTACK, npc);
}
}
}
if ((_phantom.getClassId().isMage()) && (_phantom.getClassId().getRace() != Race.orc)) {
for (NpcInstance npc : World.getAroundNpc(_phantom, 800, 200)) {
if ((GeoEngine.canSeeTarget(_phantom, npc, false)) && (npc.isMonster()) && (!npc.isDead())) {
_phantom.getAI().setIntention(CtrlIntention.AI_INT ENTION_ATTACK, npc);
_phantom.doCast(SkillTable.getInstance().getInfo(1 177, 2), npc, true);
}
}
}
}
if (Rnd.get(100) < 5) {
if ((!_phantom.getClassId().isMage()) || (_phantom.getClassId().getRace() == Race.orc)) {
for (Player player : World.getAroundPlayers(_phantom, 600, 200)) {
if ((GeoEngine.canSeeTarget(_phantom, player, false)) && (!player.isDead()) && (!player.isInZonePeace()) && (!_phantom.isInZonePeace())) {
_phantom.getAI().setIntention(CtrlIntention.AI_INT ENTION_ATTACK, player);
}
}
}
if ((_phantom.getClassId().isMage()) && (_phantom.getClassId().getRace() != Race.orc)) {
for (Player player : World.getAroundPlayers(_phantom, 600, 200)) {
if ((GeoEngine.canSeeTarget(_phantom, player, false)) && (!player.isDead()) && (!player.isInZonePeace()) && (!_phantom.isInZonePeace())) {
_phantom.getAI().setIntention(CtrlIntention.AI_INT ENTION_ATTACK, player);
_phantom.doCast(SkillTable.getInstance().getInfo(1 177, 2), player, true);
}
}
}
}
if ((Rnd.get(100) < 10) && ((_phantom.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK) || (_phantom.getAI().getIntention() != CtrlIntention.AI_INTENTION_CAST))) {
for (GameObject obj : World.getAroundObjects(_phantom, 800, 200)) {
if (obj.isItem()) {
_phantom.getAI().setIntention(CtrlIntention.AI_INT ENTION_PICK_UP, obj);
}
}
}
if ((_phantom.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK) || (_phantom.getAI().getIntention() != CtrlIntention.AI_INTENTION_CAST)) {
_phantom.rndWalk();
}
startWalk(_phantom);
}
}
public void sleep(long time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
}
}
}
могу так же дать парсера не прикрученые, отвечают за парс брони скилов оружия и т.п. у фантомов
Добавлено через 1 минуту
для стресс тестов подойдет))
Сообщений: 3,354
Тем: 97
Зарегистрирован: Aug 2011
Репутация:
9,445
Pendant Написал:ну в общем как-то так))
Phantoms
package gameserver.model;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import javolution.text.TextBuilder;
import javolution.util.FastList;
import javolution.util.FastMap;
import org.apache.log4j.Logger;
import gameserver.model.base.InvisibleType;
import gameserver.Config;
import gameserver.ThreadPoolManager;
import gameserver.database.DatabaseFactory;
import gameserver.ai.CtrlIntention;
import gameserver.model.items.ItemInstance;
import gameserver.utils.ItemFunctions;
import gameserver.utils.Location;
import commons.util.Rnd;
import gameserver.ai.PlayableAI;
import gameserver.geodata.GeoEngine;
import gameserver.model.base.Race;
import gameserver.model.instances.NpcInstance;
import gameserver.network.game.send.L2GameServerPacket;
import gameserver.network.game.send.MagicSkillUse;
import gameserver.network.game.send.Say2;
import gameserver.network.game.send.components.ChatType;
import gameserver.skills.AbnormalEffect;
import gameserver.data.tables.SkillTable;
import gameserver.templates.PlayerTemplate;
import gameserver.templates.item.ItemTemplate;
import gameserver.templates.item.CreateItem;
public class PhantomPlayers {
private static final Logger _log = Logger.getLogger(PhantomPlayers.class.getName());
private static String _phantomAcc = Config.PHANTOM_PLAYERS_AKK;
private static int _PhantomsCount = 0;
private static int _PhantomsLimit = 0;
private static int _setsCount = 0;
private static int _setsCountClan = 0;
private static int _nameColCount = 0;
private static int _titleColCount = 0;
private static int _setsArcherCount = 0;
private static int _setsOlyCount = 0;
private static int _locsCount = 0;
private static int _PhantomsEnchPhsCount = 0;
private static int _PhantomsLastPhsCount = 0;
private volatile int _PhantomsTownTotal;
private static FastList<Integer> _nameColors = new FastList();
private static FastList<Integer> _titleColors = new FastList();
private static FastList<L2Set> _sets = new FastList();
private static FastList<L2Set> _setsArcher = new FastList();
private static FastList<L2Set> _setsOly = new FastList();
private static FastList<Location> _PhantomsTownLoc = new FastList();
private static FastList<String> _PhantomsEnchPhrases = new FastList();
private static FastList<String> _PhantomsLastPhrases = new FastList();
private static FastMap<Integer, L2Fantome> _phantoms = new FastMap();
private static PhantomPlayers _instance;
private static Map<Integer, ConcurrentLinkedQueue<Player>> _PhantomsTown = new ConcurrentHashMap();
private static Map<Integer, ConcurrentLinkedQueue<Player>> _PhantomsTownClan = new ConcurrentHashMap();
private static Map<Integer, ConcurrentLinkedQueue<Integer>> _PhantomsTownClanList = new ConcurrentHashMap();
private static final int[][] _mageBuff = {{6, 75, 4322, 1}, {6, 75, 4323, 1}, {6, 75, 5637, 1}, {6, 75, 4328, 1}, {6, 75, 4329, 1}, {6, 75, 4330, 1}, {6, 75, 4331, 1}, {16, 34, 4338, 1}};
private static final int[][] _warrBuff = {{6, 75, 4322, 1}, {6, 75, 4323, 1}, {6, 75, 5637, 1}, {6, 75, 4324, 1}, {6, 75, 4325, 1}, {6, 75, 4326, 1}, {6, 39, 4327, 1}, {40, 75, 5632, 1}, {16, 34, 4338, 1}};
private static final int[] _buffers = {30598, 30599, 30600, 30601, 30602, 32135};
public PhantomPlayers()
{
_PhantomsTownTotal = 0;
}
public static PhantomPlayers getInstance()
{
return _instance;
}
public static void init()
{
_instance = new PhantomPlayers();
_instance.load();
}
private void load()
{
parceArmors();
parceArcherArmors();
parceOlyArmors();
parceColors();
cacheLastPhrases();
if (Config.ALLOW_PHANTOM_PLAYERS)
{
parceTownLocs();
parceTownClans();
cacheFantoms();
cacheEnchantPhrases();
_PhantomsLimit = Config.PHANTOM_PLAYERS_COUNT_FIRST + Config.PHANTOM_PLAYERS_COUNT_NEXT + 10;
_PhantomsTown.put(Integer.valueOf(1), new ConcurrentLinkedQueue());
_PhantomsTown.put(Integer.valueOf(2), new ConcurrentLinkedQueue());
}
}
private void cacheFantoms()
{
new Thread(new Runnable()
{
@Override
public void run()
{
String name = "";
String new_name = "";
Connection con = null;
Object localObject1 = null;
try
{
con = DatabaseFactory.getInstance().getConnection();
con.setTransactionIsolation(1);
PreparedStatement st = con.prepareStatement("SELECT obj_Id,char_name,title,x,y,z,clanid FROM characters WHERE account_name = ?");
st.setString(1, _phantomAcc);
ResultSet rs = st.executeQuery();
rs.setFetchSize(250);
while (rs.next())
{
name = rs.getString("char_name");
_phantoms.put(Integer.valueOf(rs.getInt("obj_Id")), new L2Fantome(name, rs.getString("title"), rs.getInt("x"), rs.getInt("y"), rs.getInt("z"), rs.getInt("clanid")));
}
st.close();
rs.close();
con.close();
_log.info("PhantomPlayers: Cached " + _phantoms.size() + " players.");
}
catch (SQLException e)
{
_log.warn("PhantomPlayers: could not load chars from DB: " + e);
}
finally
{
if (con != null)
{
con = null;
}
}
if (!_phantoms.isEmpty())
{
ThreadPoolManager.getInstance().schedule(new FantomTask(1), Config.PHANTOM_PLAYERS_DELAY_FIRST * 1000L);
}
}
}).start();
}
private void parceArmors()
{
if (!_sets.isEmpty())
{
_sets.clear();
}
LineNumberReader lnr = null;
BufferedReader br = null;
FileReader fr = null;
try
{
File Data = new File("./config/phantomold/town_sets.ini");
if (!Data.exists())
{
return;
}
fr = new FileReader(Data);
br = new BufferedReader(fr);
lnr = new LineNumberReader(br);
String line;
while ((line = lnr.readLine()) != null)
{
if ((line.trim().length() != 0) && (!line.startsWith("#")))
{
String[] items = line.split(",");
int custom = 0;
try
{
custom = Integer.parseInt(items[5]);
}
catch (NumberFormatException e)
{
custom = 0;
}
_sets.add(new L2Set(Integer.parseInt(items[0]), Integer.parseInt(items[1]), Integer.parseInt(items[2]), Integer.parseInt(items[3]), Integer.parseInt(items[4]), Integer.parseInt(items[5]), custom));
}
}
_setsCount = _sets.size() - 1;
_log.info("Load " + _setsCount + " phantom armor sets");
}
catch (IOException | NumberFormatException e)
{
//
}
finally
{
try
{
if (fr != null)
{
fr.close();
}
if (br != null)
{
br.close();
}
if (lnr != null)
{
lnr.close();
}
}
catch (IOException e)
{
//
}
}
}
private void parceArcherArmors()
{
if (!_setsArcher.isEmpty())
{
_setsArcher.clear();
}
LineNumberReader lnr = null;
BufferedReader br = null;
FileReader fr = null;
try
{
File Data = new File("./config/phantomold/archer_sets.ini");
if (!Data.exists())
{
return;
}
fr = new FileReader(Data);
br = new BufferedReader(fr);
lnr = new LineNumberReader(br);
String line;
while ((line = lnr.readLine()) != null)
{
if ((line.trim().length() != 0) && (!line.startsWith("#")))
{
String[] items = line.split(",");
int custom = 0;
try
{
custom = Integer.parseInt(items[5]);
}
catch (NumberFormatException e)
{
custom = 0;
}
_setsArcher.add(new L2Set(Integer.parseInt(items[0]), Integer.parseInt(items[1]), Integer.parseInt(items[2]), Integer.parseInt(items[3]), Integer.parseInt(items[4]), Integer.parseInt(items[5]), custom));
}
}
_setsArcherCount = _setsArcher.size() - 1;
_log.info("Load " + _setsArcherCount + " Aecher phantom armor sets");
}
catch (IOException | NumberFormatException e)
{
//
}
finally
{
try
{
if (fr != null)
{
fr.close();
}
if (br != null)
{
br.close();
}
if (lnr != null)
{
lnr.close();
}
}
catch (IOException e)
{
//
}
}
}
private void parceOlyArmors()
{
if (!_setsOly.isEmpty())
{
_setsOly.clear();
}
LineNumberReader lnr = null;
BufferedReader br = null;
FileReader fr = null;
try
{
File Data = new File("./config/phantomold/oly_sets.ini");
if (!Data.exists())
{
return;
}
fr = new FileReader(Data);
br = new BufferedReader(fr);
lnr = new LineNumberReader(br);
String line;
while ((line = lnr.readLine()) != null)
{
if ((line.trim().length() != 0) && (!line.startsWith("#")))
{
String[] items = line.split(",");
int custom = 0;
try
{
custom = Integer.parseInt(items[6]);
}
catch (NumberFormatException e)
{
custom = 0;
}
_setsOly.add(new L2Set(Integer.parseInt(items[0]), Integer.parseInt(items[1]), Integer.parseInt(items[2]), Integer.parseInt(items[3]), Integer.parseInt(items[4]), Integer.parseInt(items[5]), custom));
}
}
_setsOlyCount = _setsOly.size() - 1;
_log.info("Load " + _setsOlyCount + " phantom Only armor sets");
}
catch (IOException | NumberFormatException e)
{
//
}
finally
{
try {
if (fr != null) {
fr.close();
}
if (br != null) {
br.close();
}
if (lnr != null) {
lnr.close();
}
} catch (IOException e) {
}
}
}
private void parceTownClans() {
LineNumberReader lnr = null;
BufferedReader br = null;
FileReader fr = null;
try {
File Data = new File("./config/phantomold/town_clans.ini");
if (!Data.exists()) {
return;
}
fr = new FileReader(Data);
br = new BufferedReader(fr);
lnr = new LineNumberReader(br);
int clanId = 0;
String line;
while ((line = lnr.readLine()) != null) {
if ((line.trim().length() != 0) && (!line.startsWith("#"))) {
String[] items = line.split(":");
clanId = Integer.parseInt(items[0]);
String[] pls = items[1].split(",");
ConcurrentLinkedQueue players = new ConcurrentLinkedQueue();
for (String plid : pls) {
players.add(Integer.valueOf(Integer.parseInt(plid)));
}
_PhantomsTownClanList.put(Integer.valueOf(clanId), players);
}
}
_setsCountClan = _PhantomsTownClanList.size() - 1;
_log.info("Load " + _setsCountClan + " phantom Clans");
} catch (IOException | NumberFormatException e) {
} finally {
try {
if (fr != null) {
fr.close();
}
if (br != null) {
br.close();
}
if (lnr != null) {
lnr.close();
}
} catch (IOException e1) {
}
}
}
private void parceTownLocs() {
_PhantomsTownLoc.clear();
LineNumberReader lnr = null;
BufferedReader br = null;
FileReader fr = null;
try {
File Data = new File("./config/phantomold/town_locs.ini");
if (!Data.exists()) {
return;
}
fr = new FileReader(Data);
br = new BufferedReader(fr);
lnr = new LineNumberReader(br);
String line;
while ((line = lnr.readLine()) != null) {
if ((line.trim().length() != 0) && (!line.startsWith("#"))) {
String[] items = line.split(",");
_PhantomsTownLoc.add(new Location(Integer.parseInt(items[0]), Integer.parseInt(items[1]), Integer.parseInt(items[2])));
}
}
_locsCount = _PhantomsTownLoc.size() - 1;
_log.info("Load " + _locsCount + " phantom Town Locations");
} catch (IOException | NumberFormatException e) {
} finally {
try {
if (fr != null) {
fr.close();
}
if (br != null) {
br.close();
}
if (lnr != null) {
lnr.close();
}
} catch (IOException e1) {
}
}
}
public void startWalk(Player phantom) {
ThreadPoolManager.getInstance().schedule(new PhantomWalk(phantom), 10000L);
}
private void cacheEnchantPhrases() {
_PhantomsEnchPhrases.clear();
LineNumberReader lnr = null;
BufferedReader br = null;
FileReader fr = null;
try {
File Data = new File("./config/phantomold/phrases_enchant.txt");
if (!Data.exists()) {
return;
}
fr = new FileReader(Data);
br = new BufferedReader(fr);
lnr = new LineNumberReader(br);
String line;
while ((line = lnr.readLine()) != null) {
if ((line.trim().length() != 0) && (!line.startsWith("#"))) {
_PhantomsEnchPhrases.add(line);
}
}
_PhantomsEnchPhsCount = _PhantomsEnchPhrases.size() - 1;
_log.info("Load " + _PhantomsEnchPhsCount + " phantom Ench");
} catch (IOException e) {
} finally {
try {
if (fr != null) {
fr.close();
}
if (br != null) {
br.close();
}
if (lnr != null) {
lnr.close();
}
} catch (IOException e1) {
}
}
}
private void cacheLastPhrases() {
_PhantomsLastPhrases.clear();
LineNumberReader lnr = null;
BufferedReader br = null;
FileReader fr = null;
try {
File Data = new File("./config/phantomold/phrases_last.ini");
if (!Data.exists()) {
return;
}
fr = new FileReader(Data);
br = new BufferedReader(fr);
lnr = new LineNumberReader(br);
String line;
while ((line = lnr.readLine()) != null) {
if ((line.trim().length() != 0) && (!line.startsWith("#"))) {
_PhantomsLastPhrases.add(line);
}
}
_PhantomsLastPhsCount = _PhantomsLastPhrases.size() - 1;
_log.info("Load " + _PhantomsLastPhsCount + " phantom Last");
} catch (IOException e) {
} finally {
try {
if (fr != null) {
fr.close();
}
if (br != null) {
br.close();
}
if (lnr != null) {
lnr.close();
}
} catch (IOException e1) {
}
}
}
private void parceColors() {
_nameColors = Config.PHANTOM_PLAYERS_NAME_CLOLORS;
_titleColors = Config.PHANTOM_PLAYERS_TITLE_CLOLORS;
_nameColCount = _nameColors.size() - 1;
_titleColCount = _titleColors.size() - 1;
}
private L2Set getRandomSet() {
return (L2Set) _sets.get(Rnd.get(_setsCount));
}
private L2Set getRandomArcherSet() {
return (L2Set) _setsArcher.get(Rnd.get(_setsArcherCount));
}
private int getRandomPhantom() {
return Rnd.get(600000000, 600006081);
}
private int getRandomPhantomNext() {
for (int i = 6; i > 0; i--) {
int obj = Rnd.get(600000000, 600006081);
if ((!((ConcurrentLinkedQueue) _PhantomsTown.get(Integer.valueOf(1))).contains(Integer.valueOf(obj))) && (!((ConcurrentLinkedQueue) _PhantomsTown.get(Integer.valueOf(2))).contains(Integer.valueOf(obj)))) {
return obj;
}
}
return getRandomPhantomNext();
}
private int getRandomClan() {
return Rnd.get(600000000, 600006081);
}
private Location getRandomLoc() {
Location loc = null;
if (loc == null) {
loc = (Location) _PhantomsTownLoc.get(Rnd.get(0, _locsCount));
}
return loc;
}
private Player loadPhantom(int objId) {
int nbPlayerIG = GameObjectsStorage.getAllPlayersCount();
if (nbPlayerIG < Config.MAXIMUM_ONLINE_USERS) {
L2Fantome phantom = (L2Fantome) _phantoms.get(Integer.valueOf(objId));
if (phantom == null) {
return null;
}
L2Set set = getRandomSet();
ItemInstance body = null;
ItemInstance gaiters = null;
ItemInstance gloves = null;
ItemInstance boots = null;
ItemInstance weapon = null;
if (set._body != 0) {
body = ItemFunctions.createItem(set._body);
}
if (set._gaiters != 0) {
gaiters = ItemFunctions.createItem(set._gaiters);
}
if (set._gloves != 0) {
gloves = ItemFunctions.createItem(set._gloves);
}
if (set._boots != 0) {
boots = ItemFunctions.createItem(set._boots);
}
if (set._weapon != 0) {
weapon = ItemFunctions.createItem(set._weapon);
}
ItemInstance custom = null;
int grade = set._grade;
int setLevel = 1;
int classId = 0;
if (grade == 0) {
setLevel = Rnd.get(1, 19);
}
if (grade == 1) {
setLevel = Rnd.get(20, 39);
}
if (grade == 2) {
setLevel = Rnd.get(40, 51);
}
if (grade == 3) {
setLevel = Rnd.get(52, 60);
}
if (grade == 4) {
setLevel = Rnd.get(61, 75);
}
if (grade == 5) {
setLevel = Rnd.get(76, 85);
}
Player localPlayer = Player.restorePhantom(objId, setLevel, classId, false);
localPlayer.setOfflineMode(false);
localPlayer.setIsOnline(true);
//fantom.updateOnlineStatus();
Location loc = getRandomLoc();
localPlayer.setPhantomLoc(loc.getX(), loc.getY(), loc.getZ());
localPlayer.setXYZ(loc.getX() + Rnd.get(60), loc.getY() + Rnd.get(60), loc.getZ());
Location loc1 = new Location(loc.getX() + Rnd.get(350), loc.getY() + Rnd.get(350), loc.getZ());
localPlayer.setOnlineStatus(true);
localPlayer.setInvisibleType(InvisibleType.NONE);
localPlayer.setNonAggroTime(9223372036854775807L);
localPlayer.spawnMe(loc1);
localPlayer.setCurrentHpMp(localPlayer.getMaxHp(), localPlayer.getMaxMp());
localPlayer.setCurrentCp(localPlayer.getMaxCp());
if ((Config.ALLOW_PHANTOM_SETS) && (localPlayer.getClassId().getRace() != Race.kamael)) {
if (body != null) {
localPlayer.getInventory().addItem(body);
localPlayer.getInventory().equipItem(body);
}
if (gaiters != null) {
localPlayer.getInventory().addItem(gaiters);
localPlayer.getInventory().equipItem(gaiters);
}
if (gloves != null) {
localPlayer.getInventory().addItem(gloves);
localPlayer.getInventory().equipItem(gloves);
}
if (boots != null) {
localPlayer.getInventory().addItem(boots);
localPlayer.getInventory().equipItem(boots);
}
if (weapon != null) {
localPlayer.getInventory().addItem(weapon);
localPlayer.getInventory().equipItem(weapon);
}
}
if ((!Config.ALLOW_PHANTOM_SETS) || (localPlayer.getClassId().getRace() == Race.kamael)) {
PlayerTemplate template = localPlayer.getTemplate();
for (ItemTemplate i : template.getItems()) {
ItemInstance item = ItemFunctions.createItem(i.getItemId());
localPlayer.getInventory().addItem(item);
if ((i.isEquipable()) && (item.isEquipable()) && ((localPlayer.getActiveWeaponItem() == null) || (item.getTemplate().getType2() != 0))) {
localPlayer.getInventory().equipItem(item);
}
}
}
localPlayer.broadcastCharInfo();
localPlayer.rndWalk();
startWalk(localPlayer);
return localPlayer;
}
return null;
}
private String getRandomEnchantPhrase() {
return (String) _PhantomsEnchPhrases.get(Rnd.get(_PhantomsEnchPhsCount));
}
public String getRandomLastPhrase() {
return (String) _PhantomsLastPhrases.get(Rnd.get(_PhantomsLastPhsCount));
}
private int getNameColor() {
return ((Integer) _nameColors.get(Rnd.get(_nameColCount))).intValue();
}
private int getTitleColor() {
return ((Integer) _titleColors.get(Rnd.get(_titleColCount))).intValue();
}
public class Social
implements Runnable {
public Social() {
}
@Override
public void run() {
TextBuilder tb = new TextBuilder();
for (Map.Entry<Integer, ConcurrentLinkedQueue<Player>> entry : _PhantomsTown.entrySet()) {
Integer wave = entry.getKey();
ConcurrentLinkedQueue<Player> players = entry.getValue();
if ((wave != null) && (players != null) && (!players.isEmpty())) {
int count = 0;
for (Player player : players) {
if (Rnd.get(100) < 65) {
switch (Rnd.get(2)) {
case 0:
case 1:
ItemInstance wpn = player.getActiveWeaponInstance();
int enhchant = wpn.getEnchantLevel();
int nextench = enhchant + 1;
if ((Rnd.get(100) < 45) && (enhchant <= Config.PHANTOM_PLAYERS_ENCHANT_MAX)) {
wpn.setEnchantLevel(nextench);
} else if (Rnd.get(100) < 70) {
wpn.setEnchantLevel(3);
if ((nextench > 13) && (Rnd.get(100) < 2)) {
tb.append("!");
for (int i = Rnd.get(2, 13); i > 0; i--) {
tb.append("!");
}
tb.clear();
}
}
player.broadcastUserInfo(true);
break;
case 2:
if (Rnd.get(100) < 5) {
player.moveToLocation(player.getX() + Rnd.get(30), player.getY() + Rnd.get(30), player.getZ(), 40, true);
player.getAI().setNextAction(PlayableAI.nextAction.INTERACT, null, null, false, false);
}
break;
}
sleep(Rnd.get(500, 1500));
count++;
}
if (count > 55) {
break;
}
}
}
}
tb.clear();
ThreadPoolManager.getInstance().schedule(new Social(), 12000L);
}
}
public class CheckCount
implements Runnable {
public CheckCount() {
}
@Override
public void run() {
for (Map.Entry<Integer, ConcurrentLinkedQueue<Player>> entry : _PhantomsTown.entrySet()) {
Integer wave = entry.getKey();
ConcurrentLinkedQueue<Player> players = entry.getValue();
if ((wave != null) && (players != null) && (!players.isEmpty())) {
int limit = wave.intValue() == 1 ? Config.PHANTOM_PLAYERS_COUNT_FIRST : Config.PHANTOM_PLAYERS_COUNT_NEXT;
int overflow = players.size() - limit;
if (overflow >= 1) {
for (Player fantom : players) {
fantom.setOnlineStatus(false);
((ConcurrentLinkedQueue) _PhantomsTown.get(wave)).remove(fantom);
overflow--;
if (overflow == 0) {
break;
}
}
}
}
}
ThreadPoolManager.getInstance().schedule(new CheckCount(), 300000L);
}
}
public class FantomTaskDespawn
implements Runnable {
public int _task;
public FantomTaskDespawn(int task) {
_task = task;
}
@Override
public void run() {
ConcurrentLinkedQueue<Player> players = _PhantomsTown.get(_task);
for (Player fantom : players) {
if (fantom != null) {
Location loc = fantom.getPhantomLoc();
fantom.setOnlineStatus(false);
((ConcurrentLinkedQueue) _PhantomsTown.get(Integer.valueOf(_task))).remove(fantom);
sleep(_task == 1 ? Config.PHANTOM_PLAYERS_DELAY_DESPAWN_FIRST : Config.PHANTOM_PLAYERS_DELAY_DESPAWN_NEXT);
if (_PhantomsTownTotal <= _PhantomsLimit) {
int nextObjId = getRandomPhantomNext();
if (!((ConcurrentLinkedQueue) _PhantomsTown.get(Integer.valueOf(_task))).contains(Integer.valueOf(nextObjId))) {
Player next = loadPhantom(nextObjId);
if (next != null) {
((ConcurrentLinkedQueue) _PhantomsTown.get(Integer.valueOf(_task))).add(next);
if ((Config.PHANTOM_PLAYERS_SOULSHOT_ANIM) && (Rnd.get(100) < 45)) {
sleep(900L);
if (Rnd.get(100) < 3) {
next.sitDown(null);
}
next.broadcastPacket(new MagicSkillUse(next, next, 2154, 1, 0, 0L));
sleep(300L);
next.broadcastPacket(new MagicSkillUse(next, next, 2164, 1, 0, 0L));
}
sleep(100L);
}
}
}
}
}
ThreadPoolManager.getInstance().schedule(new FantomTaskDespawn(1), _task == 1 ? Config.PHANTOM_PLAYERS_DESPAWN_FIRST : Config.PHANTOM_PLAYERS_DESPAWN_NEXT);
}
}
public class FantomTask
implements Runnable {
public int _task;
public FantomTask(int task) {
_task = task;
}
@Override
public void run() {
int count = 0;
int count2 = 0;
int PhantomObjId = 0;
int PhantomObjId2 = 0;
switch (_task) {
case 1:
_log.info("PhantomPlayers: 1st wave, spawn started.");
while (count < Config.PHANTOM_PLAYERS_COUNT_FIRST) {
PhantomObjId = getRandomPhantomNext();
if (!((ConcurrentLinkedQueue) _PhantomsTown.get(Integer.valueOf(1))).contains(Integer.valueOf(PhantomObjId))) {
Player fantom = loadPhantom(PhantomObjId);
if (fantom != null) {
((ConcurrentLinkedQueue) _PhantomsTown.get(Integer.valueOf(1))).add(fantom);
if ((Config.PHANTOM_PLAYERS_SOULSHOT_ANIM) && (Rnd.get(100) < 45)) {
sleep(900L);
if (Rnd.get(100) < 5) {
fantom.sitDown(null);
}
if (Rnd.get(100) < 30) {
fantom.startAbnormalEffect(AbnormalEffect.S_NAVIT);
}
sleep(300L);
}
sleep(Config.PHANTOM_PLAYERS_DELAY_SPAWN_FIRST);
count++;
}
}
}
_log.info("FPhantomPlayers: 1st wave, spawned " + count + " players.");
ThreadPoolManager.getInstance().schedule(new FantomTaskDespawn(1), Config.PHANTOM_PLAYERS_DESPAWN_FIRST);
ThreadPoolManager.getInstance().schedule(new FantomTask(2), Config.PHANTOM_PLAYERS_DELAY_NEXT);
ThreadPoolManager.getInstance().schedule(new Social(), 12000L);
ThreadPoolManager.getInstance().schedule(new CheckCount(), 300000L);
break;
case 2:
_log.info("PhantomPlayers: 2nd wave, spawn started.");
while (count2 < Config.PHANTOM_PLAYERS_COUNT_NEXT) {
PhantomObjId2 = getRandomPhantomNext();
if ((!((ConcurrentLinkedQueue) _PhantomsTown.get(Integer.valueOf(1))).contains(Integer.valueOf(PhantomObjId2))) || (!((ConcurrentLinkedQueue) _PhantomsTown.get(Integer.valueOf(2))).contains(Integer.valueOf(PhantomObjId2)))) {
Player fantom2 = loadPhantom(PhantomObjId2);
if (fantom2 != null) {
((ConcurrentLinkedQueue) _PhantomsTown.get(Integer.valueOf(2))).add(fantom2);
if ((Config.PHANTOM_PLAYERS_SOULSHOT_ANIM) && (Rnd.get(100) < 45)) {
sleep(900L);
if (Rnd.get(100) < 3) {
fantom2.sitDown(null);
}
fantom2.broadcastPacket(new L2GameServerPacket[]{new MagicSkillUse(fantom2, fantom2, 2154, 1, 0, 0L)});
sleep(300L);
fantom2.broadcastPacket(new L2GameServerPacket[]{new MagicSkillUse(fantom2, fantom2, 2164, 1, 0, 0L)});
}
sleep(Config.PHANTOM_PLAYERS_DELAY_SPAWN_NEXT);
count2++;
}
}
}
_log.info("PhantomPlayers: 2nd wave, spawned " + count2 + " players.");
ThreadPoolManager.getInstance().schedule(new FantomTaskDespawn(2), Config.PHANTOM_PLAYERS_DESPAWN_NEXT);
}
}
}
static class L2Fantome {
public String name;
public String title;
public int x;
public int y;
public int z;
public int clanId;
L2Fantome(String name, String title, int x, int y, int z, int clanId) {
this.name = name;
this.title = title;
this.x = x;
this.y = y;
this.z = z;
this.clanId = clanId;
}
}
static class L2Set {
public int _body;
public int _gaiters;
public int _gloves;
public int _boots;
public int _weapon;
public int _custom;
public int _grade;
L2Set(int bod, int gaiter, int glove, int boot, int weapon, int grade, int custom) {
_body = bod;
_gaiters = gaiter;
_gloves = glove;
_boots = boot;
_weapon = weapon;
_grade = grade;
_custom = custom;
}
}
private class PhantomWalk
implements Runnable {
Player _phantom;
public PhantomWalk(Player phantom) {
_phantom = phantom;
}
@Override
public void run() {
if (_phantom.isDead()) {
_phantom.kick();
}
if (_phantom.isInWater()) {
_phantom.teleToClosestTown();
}
if ((Rnd.get(100) < 10)
&& (Rnd.get(100) < 10)
&& (_phantom.isSitting())) {
_phantom.standUp();
}
if (Rnd.get(100) < 80) {
for (NpcInstance npc : World.getAroundNpc(_phantom, 100, 100)) {
for (int buffers_id : _buffers) {
if ((npc.getNpcId() == buffers_id) && (!_phantom.isSitting())) {
if ((!_phantom.getClassId().isMage()) || (_phantom.getClassId().getRace() == Race.orc)) {
for (int[] buff : _warrBuff) {
npc.broadcastPacket(new L2GameServerPacket[]{new MagicSkillUse(npc, _phantom, buff[2], buff[3], 0, 0L)});
}
}
if ((_phantom.getClassId().isMage()) && (_phantom.getClassId().getRace() != Race.orc)) {
for (int[] buff : _mageBuff) {
npc.broadcastPacket(new L2GameServerPacket[]{new MagicSkillUse(npc, _phantom, buff[2], buff[3], 0, 0L)});
}
}
}
}
}
}
Say2 cs3;
if (Rnd.get(100) < 5) {
Say2 cs;
Say2 cs2;
switch (Rnd.get(1, 3)) {
case 1:
cs = new Say2(_phantom.getObjectId(), ChatType.SHOUT, _phantom.getName(), getRandomEnchantPhrase());
for (Player player : World.getAroundPlayers(_phantom, 10000, 3000)) {
if ((player != null)
&& (!player.isBlockAll())) {
player.sendPacket(cs);
}
}
break;
case 2:
cs2 = new Say2(_phantom.getObjectId(), ChatType.TRADE, _phantom.getName(), getRandomEnchantPhrase());
for (Player player : World.getAroundPlayers(_phantom, 5000, 2000)) {
if ((player != null)
&& (!player.isBlockAll())) {
player.sendPacket(cs2);
}
}
break;
case 3:
cs3 = new Say2(_phantom.getObjectId(), ChatType.ALL, _phantom.getName(), getRandomEnchantPhrase());
for (Player player : World.getAroundPlayers(_phantom, 1200, 1000)) {
if ((player != null)
&& (!player.isBlockAll())) {
player.sendPacket(cs3);
}
}
}
}
if (Rnd.get(100) < 10) {
if ((!_phantom.getClassId().isMage()) || (_phantom.getClassId().getRace() == Race.orc)) {
_phantom.broadcastPacket(new L2GameServerPacket[]{new MagicSkillUse(_phantom, _phantom, 2153, 1, 0, 0L)});
}
if ((_phantom.getClassId().isMage()) && (_phantom.getClassId().getRace() != Race.orc)) {
_phantom.broadcastPacket(new L2GameServerPacket[]{new MagicSkillUse(_phantom, _phantom, 2158, 1, 0, 0L)});
}
}
if (Rnd.get(100) < 70) {
if ((!_phantom.getClassId().isMage()) || (_phantom.getClassId().getRace() == Race.orc)) {
for (Player player : World.getAroundPlayers(_phantom, 100, 100)) {
if ((GeoEngine.canSeeTarget(_phantom, player, false)) && (!player.isDead()) && (!player.isInZonePeace()) && (!_phantom.isInZonePeace()) && ((player.getKarma() != 0) || (player.getPvpFlag() > 0))) {
if (_phantom.getRealDistance3D(player) <= _phantom.getPhysicalAttackRange() + 40) {
_phantom.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
sleep(500L);
if (_phantom.getClassId().getRace() == Race.human) {
_phantom.doCast(SkillTable.getInstance().getInfo(3, 2), player, true);
}
if (_phantom.getClassId().getRace() == Race.elf) {
_phantom.doCast(SkillTable.getInstance().getInfo(3, 2), player, true);
}
if (_phantom.getClassId().getRace() == Race.darkelf) {
_phantom.doCast(SkillTable.getInstance().getInfo(3, 2), player, true);
}
if (_phantom.getClassId().getRace() == Race.orc) {
_phantom.doCast(SkillTable.getInstance().getInfo(29, 2), player, true);
}
if (_phantom.getClassId().getRace() == Race.dwarf) {
_phantom.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
}
if (_phantom.getClassId().getRace() == Race.kamael) {
_phantom.doCast(SkillTable.getInstance().getInfo(468, 2), player, true);
}
sleep(500L);
_phantom.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
} else {
sleep(500L);
}
_phantom.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
}
}
}
if ((_phantom.getClassId().isMage()) && (_phantom.getClassId().getRace() != Race.orc)) {
for (Player player : World.getAroundPlayers(_phantom, 100, 100)) {
if ((GeoEngine.canSeeTarget(_phantom, player, false)) && (!player.isDead()) && (!player.isInZonePeace()) && (!_phantom.isInZonePeace()) && ((player.getKarma() != 0) || (player.getPvpFlag() > 0))) {
_phantom.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
_phantom.doCast(SkillTable.getInstance().getInfo(1177, 2), player, true);
}
}
}
}
if (Rnd.get(100) < 10) {
if ((!_phantom.getClassId().isMage()) || (_phantom.getClassId().getRace() == Race.orc)) {
for (NpcInstance npc : World.getAroundNpc(_phantom, 800, 200)) {
if ((GeoEngine.canSeeTarget(_phantom, npc, false)) && (npc.isMonster()) && (!npc.isDead())) {
_phantom.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, npc);
}
}
}
if ((_phantom.getClassId().isMage()) && (_phantom.getClassId().getRace() != Race.orc)) {
for (NpcInstance npc : World.getAroundNpc(_phantom, 800, 200)) {
if ((GeoEngine.canSeeTarget(_phantom, npc, false)) && (npc.isMonster()) && (!npc.isDead())) {
_phantom.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, npc);
_phantom.doCast(SkillTable.getInstance().getInfo(1177, 2), npc, true);
}
}
}
}
if (Rnd.get(100) < 5) {
if ((!_phantom.getClassId().isMage()) || (_phantom.getClassId().getRace() == Race.orc)) {
for (Player player : World.getAroundPlayers(_phantom, 600, 200)) {
if ((GeoEngine.canSeeTarget(_phantom, player, false)) && (!player.isDead()) && (!player.isInZonePeace()) && (!_phantom.isInZonePeace())) {
_phantom.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
}
}
}
if ((_phantom.getClassId().isMage()) && (_phantom.getClassId().getRace() != Race.orc)) {
for (Player player : World.getAroundPlayers(_phantom, 600, 200)) {
if ((GeoEngine.canSeeTarget(_phantom, player, false)) && (!player.isDead()) && (!player.isInZonePeace()) && (!_phantom.isInZonePeace())) {
_phantom.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
_phantom.doCast(SkillTable.getInstance().getInfo(1177, 2), player, true);
}
}
}
}
if ((Rnd.get(100) < 10) && ((_phantom.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK) || (_phantom.getAI().getIntention() != CtrlIntention.AI_INTENTION_CAST))) {
for (GameObject obj : World.getAroundObjects(_phantom, 800, 200)) {
if (obj.isItem()) {
_phantom.getAI().setIntention(CtrlIntention.AI_INTENTION_PICK_UP, obj);
}
}
}
if ((_phantom.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK) || (_phantom.getAI().getIntention() != CtrlIntention.AI_INTENTION_CAST)) {
_phantom.rndWalk();
}
startWalk(_phantom);
}
}
public void sleep(long time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
}
}
}
могу так же дать парсера не прикрученые, отвечают за парс брони скилов оружия и т.п. у фантомов
Добавлено через 1 минуту
для стресс тестов подойдет))
Благодарствую, будет чем заняться на досуге.
Сообщений: 433
Тем: 35
Зарегистрирован: Jun 2009
Репутация:
1,392
Смотря какую ставить цель. Если делать ботов для эмуляции и накрутки онлайна, то тут очень сложно все - бот должен быть основан на Player(L2PcInstance), обрабатываться полностью как чар.
Если скрывать присутствие ботов от игроков не обязательно, то можно делать на базе мобов, с подменой пакетки.
У каждого варианта есть серьезные минусы, требующие весьма изощренного костылирования. Во всяком случае на актульных сборках L2j и овера.
Пилю ботов как хобби уже очень давно. Камней подводных туева хуча)
В данный момент реализую маркерную систему анализа территорий для анализирования отклонений от средних значений по региону и выводов по этому поводу.
Т.е например бот в данный момент может примерно правильно реагировать на появление группы вооруженных противников в регионе в зависимости от их состояния. Например если многие из них флагнуты или в ПК-режиме, то бот может сделать ноги. Наоборот, если боты в группе и в регионе появился ПК-чар, то с большой долей вероятности боты попробуют его выпилить, но если к примеру, после выпила этого чара туда забегают его сокланы и устраивают локальный экстерминатус, то регион будет помечен как "горячий" и шанс того, что боты туда добровольно полезут, будет намного меньше. Как-то так.
Сообщений: 3,354
Тем: 97
Зарегистрирован: Aug 2011
Репутация:
9,445
Aristocrat Написал:Смотря какую ставить цель. Если делать ботов для эмуляции и накрутки онлайна, то тут очень сложно все - бот должен быть основан на Player(L2PcInstance), обрабатываться полностью как чар.
Если скрывать присутствие ботов от игроков не обязательно, то можно делать на базе мобов, с подменой пакетки.
У каждого варианта есть серьезные минусы, требующие весьма изощренного костылирования. Во всяком случае на актульных сборках L2j и овера.
Пилю ботов как хобби уже очень давно. Камней подводных туева хуча)
В данный момент реализую маркерную систему анализа территорий для анализирования отклонений от средних значений по региону и выводов по этому поводу.
Т.е например бот в данный момент может примерно правильно реагировать на появление группы вооруженных противников в регионе в зависимости от их состояния. Например если многие из них флагнуты или в ПК-режиме, то бот может сделать ноги. Наоборот, если боты в группе и в регионе появился ПК-чар, то с большой долей вероятности боты попробуют его выпилить, но если к примеру, после выпила этого чара туда забегают его сокланы и устраивают локальный экстерминатус, то регион будет помечен как "горячий" и шанс того, что боты туда добровольно полезут, будет намного меньше. Как-то так.
Интересная идея и последующая реализация.. Скорее всего нужно переписывать всё что относится к данной задаче с нуля, под эти нужды...
Сообщений: 433
Тем: 35
Зарегистрирован: Jun 2009
Репутация:
1,392
На самом деле пришлось переписать не так уж и много. Были небольшие затруднения с ИИ, т.к механизм работы ИИ чара и моба несколько отличаются и чтобы не плодить сущности и обойтись одним классом, пришлось чутка пройтись по сборке и немного ее прокостылировать.
|