Grind Team

kick

Предвестник
Administrator
За веру и верность форуму
Отец-основатель
Сообщения
7 027
Розыгрыши
21
Решения
1
Репутация
5 860
Реакции
6 523
Баллы
2 688
Сюда буду публиковать весь код, как выразился гринд раз я балабол то пускай все посмотрят и почитают данный код:
if(player.getVar("EnterAntharas") !=null)
return;

else
{
player.sendMessage(player.isLangRus() ? "Вы не можете находиться здесь." : "You can not be here.");
player.teleToLocation(82698, 148638, -3473);
}
if(player.getVar("EnterBaium") !=null)
return;

else
{
player.sendMessage(player.isLangRus() ? "Вы не можете находиться здесь." : "You can not be here.");
player.teleToLocation(147450, 27120, -2208);
}
if(player.getVar("EnterHellbound") !=null && player.getVar("EnterUrban") !=null && HellboundManager.getHellboundLevel() !=0 && (player.isQuestCompleted("_130_PathToHellbound") || player.isQuestCompleted("_133_ThatsBloodyHot")))
return;

else
{
player.sendMessage(player.isLangRus() ? "Вы не можете находиться здесь." : "You can not be here.");
player.teleToLocation(82698, 148638, -3473);
}
if(player.getVar("EnterHellbound") !=null && HellboundManager.getHellboundLevel() !=0 && (player.isQuestCompleted("_130_PathToHellbound") || player.isQuestCompleted("_133_ThatsBloodyHot")))
return;

else
{
player.sendMessage(player.isLangRus() ? "Вы не можете находиться здесь." : "You can not be here.");
player.teleToLocation(82698, 148638, -3473);
}
if(player.getVar("EnterValakas") !=null)
return;

else
{
player.sendMessage(player.isLangRus() ? "Вы не можете находиться здесь." : "You can not be here.");
player.teleToLocation(147725, -56517, -2780);
}

Вот так реализованы зоны у Grind-Team где реализован весь официальный контент, когда можно от многих багов избавиться глянув офф скрипты, но тут не суть даже в нём а суть в данном коде. Давайте насиловать бд и писать не нужное, а использовать статик методы видимо для лохов.
 

Ну, как бы, тут все ясно:

Забивать базу xD Ты наверно из тех днарей, что тащат все в xml
Я уже давал комментарии по-поводу приоритета использования mysql для хранения любых данных, которые требуют хранения.
Чтобы "забить базу" или "нагрузить" надо очень сильно постараться.
 
public class HeroItems extends Functions
{
//TODO: Bonux, переделать, чтобы было мультиязычное!
private static final String[][] HERO_ITEMS = {
{
"6611",
"weapon_the_sword_of_hero_i00",
"Infinity Blade",
"During a critical attack, decreases one's P. Def and increases de-buff casting ability, damage shield effect, Max HP, Max MP, Max CP, and shield defense power. Also enhances damage to target during PvP.",
"524/230",
"Sword" },
{
"6612",
"weapon_the_two_handed_sword_of_hero_i00",
"Infinity Cleaver",
"Increases Max HP, Max CP, critical power and critical chance. Inflicts extra damage when a critical attack occurs and has possibility of reflecting the skill back on the player. Also enhances damage to target during PvP.",
"638/230",
"Two Handed Sword" },
{
"6613",
"weapon_the_axe_of_hero_i00",
"Infinity Axe",
"During a critical attack, it bestows one the ability to cause internal conflict to one's opponent. Damage shield function, Max HP, Max MP, Max CP as well as one's shield defense rate are increased. It also enhances damage to one's opponent during PvP.",
"524/230",
"Blunt" },
{
"6614",
"weapon_the_mace_of_hero_i00",
"Infinity Rod",
"When good magic is casted upon a target, increases MaxMP, MaxCP, Casting Spd, and MP regeneration rate. Also recovers HP 100% and enhances damage to target during PvP.",
"420/307",
"Blunt" },
{
"6615",
"weapon_the_hammer_of_hero_i00",
"Infinity Crusher",
"Increases MaxHP, MaxCP, and Atk. Spd. Stuns a target when a critical attack occurs and has possibility of reflecting the skill back on the player. Also enhances damage to target during PvP.",
"638/230",
"Blunt" },
{
"6616",
"weapon_the_staff_of_hero_i00",
"Infinity Scepter",
"When casting good magic, it can recover HP by 100% at a certain rate, increases MAX MP, MaxCP, M. Atk., lower MP Consumption, increases the Magic Critical rate, and reduce the Magic Cancel. Enhances damage to target during PvP.",
"511/337",
"Blunt" },
{
"6617",
"weapon_the_dagger_of_hero_i00",
"Infinity Stinger",
"Increases MaxMP, MaxCP, Atk. Spd., MP regen rate, and the success rate of Mortal and Deadly Blow from the back of the target. Silences the target when a critical attack occurs and has Vampiric Rage effect. Also enhances damage to target during PvP.",
"458/230",
"Dagger" },
{
"6618",
"weapon_the_fist_of_hero_i00",
"Infinity Fang",
"Increases MaxHP, MaxMP, MaxCP and evasion. Stuns a target when a critical attack occurs and has possibility of reflecting the skill back on the player at a certain probability rate. Also enhances damage to target during PvP.",
"638/230",
"Dual Fist" },
{
"6619",
"weapon_the_bow_of_hero_i00",
"Infinity Bow",
"Increases MaxMP/MaxCP and decreases re-use delay of a bow. Slows target when a critical attack occurs and has Cheap Shot effect. Also enhances damage to target during PvP.",
"952/230",
"Bow" },
{
"6620",
"weapon_the_dualsword_of_hero_i00",
"Infinity Wing",
"When a critical attack occurs, increases MaxHP, MaxMP, MaxCP and critical chance. Silences the target and has possibility of reflecting the skill back on the target. Also enhances damage to target during PvP.",
"638/230",
"Dual Sword" },
{
"6621",
"weapon_the_pole_of_hero_i00",
"Infinity Spear",
"During a critical attack, increases MaxHP, Max CP, Atk. Spd. and Accuracy. Casts dispel on a target and has possibility of reflecting the skill back on the target. Also enhances damage to target during PvP.",
"524/230",
"Pole" },
{
"9388",
"weapon_infinity_rapier_i00",
"Infinity Rapier",
"Decreases the target P. Def and increases the de-buff casting ability, the damage shield ability, and the Max HP/Max MP/Max CP on a critical attack. Increases damage inflicted during PvP.A critical attack will have a chance to increase P. Atk., M. Atk., and healing power, and decrease MP consumption during skill use, for you and your party members.",
"475/230",
"Rapier" },
{
"9389",
"weapon_infinity_sword_i00",
"Infinity Sword",
"Increases critical attack success rate/power, MaxHP, MaxCP, and damage inflicted during PvP. Also inflicts extra damage on critical attacks, and reflects debuff attacks back on enemies.",
"568/230",
"Ancient Sword" },
{
"9390",
"weapon_infinity_shooter_i00",
"Infinity Shooter",
"Produces the following effects when a critical attack occurs: the target is slowed, decrease MP consumption for skill use, and increase Max MP/Max CP. Enhances damage done to the target during PvP.",
"584/230",
"Crossbow" } };

public void rendershop(String[] val)
{
Player player = getSelf();
NpcInstance npc = getNpc();
if(player == null || npc == null)
return;

String fileName = OLYMPIAD_HTML_PATH;
boolean succ = true;
if(!player.isHero())
{
fileName += "monument_weapon_no_hero.htm";
succ = false;
}
else
{
for(String heroItem[] : HERO_ITEMS)
{
int itemId = Integer.parseInt(heroItem[0]);
if(player.getInventory().getItemByItemId(itemId) != null)
{
fileName += "monument_weapon_have.htm";
succ = false;
break;
}
}
}

if(!succ)
{
npc.showChatWindow(player, fileName);
return;
}

boolean isKamael = player.getRace() == Race.kamael;
String htmltext = "";
if(val[0].equalsIgnoreCase("list"))
{
htmltext = "<html><body><font color=\"LEVEL\">List of Hero Weapons:</font><table border=0 width=270><tr><td>";
for(int i = isKamael ? 11 : 0; i < (isKamael ? HERO_ITEMS.length : HERO_ITEMS.length - 3); i++)
{
htmltext += "<tr><td width=32 height=45 valign=top>";
htmltext += "<img src=icon." + HERO_ITEMS[1] + " width=32 height=32></td>";
htmltext += "<td valign=top>[<a action=\"bypass -h scripts_services.HeroItems:rendershop " + i + "\">" + HERO_ITEMS[2] + "</a>]<br1>";
htmltext += "Type: " + HERO_ITEMS[5] + ", Patk/Matk: " + HERO_ITEMS[4];
htmltext += "</td></tr>";
}
htmltext += "</table>";
}
else if(Integer.parseInt(val[0]) >= 0 && Integer.parseInt(val[0]) <= HERO_ITEMS.length)
{
int itemIndex = Integer.parseInt(val[0]);

// Для камаэль оружия сообщение:
// 2234 Will you use the selected Kamael race-only Hero Weapon?
// Для всего остального оружия сообщение:
// 1484 Are you sure this is the Hero weapon you wish to use? Kamael race cannot use this.
int msgId = itemIndex > 10 ? 2234 : 1484;

htmltext = "<html><body><font color=\"LEVEL\">Item Information:</font><table border=0 width=270><tr><td>";
htmltext += "<img src=\"L2UI.SquareWhite\" width=270 height=1>";
htmltext += "<table border=0 width=240>";
htmltext += "<tr><td width=32 height=45 valign=top>";
htmltext += "<img src=icon." + HERO_ITEMS[itemIndex][1] + " width=32 height=32></td>";
htmltext += "<td valign=top>[<a action=\"bypass -h scripts_services.HeroItems:getweapon " + HERO_ITEMS[itemIndex][0] + "\" msg=\"" + msgId + "\">" + HERO_ITEMS[itemIndex][2] + "</a>]<br1>";
htmltext += "Type: " + HERO_ITEMS[itemIndex][5] + ", Patk/Matk: " + HERO_ITEMS[itemIndex][4] + "<br1>";
htmltext += "</td></tr></table>";
htmltext += "<font color=\"B09878\">" + HERO_ITEMS[itemIndex][3] + "</font>";
htmltext += "</td></tr></table><br>";
htmltext += "<img src=\"L2UI.SquareWhite\" width=270 height=1><br><br>";
htmltext += "<CENTER><button value=Back action=\"bypass -h scripts_services.HeroItems:rendershop list\" width=40 height=15 back=L2UI_CT1.Button_DF fore=L2UI_CT1.Button_DF></CENTER>";

}
show(htmltext, player, npc);
}

public void getweapon(String[] var)
{
Player player = getSelf();
if(player == null)
return;

int item = Integer.parseInt(var[0]);
if(item < 6611 && item > 6621 || item < 9388 && item > 9390)
{
System.out.println(player.getName() + " tried to obtain non hero item using hero weapon service. Ban him!");
return;
}

NpcInstance npc = getNpc();
if(npc == null)
return;

String fileName = OLYMPIAD_HTML_PATH;
if(player.isHero())
{
boolean have = false;
for(String heroItem[] : HERO_ITEMS)
{
int itemId = Integer.parseInt(heroItem[0]);
if(player.getInventory().getItemByItemId(itemId) != null)
{
fileName += "monument_weapon_have.htm";
have = true;
break;
}
}
if(!have)
{
ItemFunctions.addItem(player, item, 1, true);
fileName += "monument_weapon_give.htm";
}
}
else
fileName += "monument_weapon_no_hero.htm";

npc.showChatWindow(player, fileName);
}

public String getcir()
{
Player player = getSelf();
if(player == null)
return null;

NpcInstance npc = getNpc();
if(npc == null)
return null;

String fileName = OLYMPIAD_HTML_PATH;
if(player.isHero())
{
if(player.getInventory().getItemByItemId(6842) != null)
fileName += "monument_circlet_have.htm";
else
{
ItemFunctions.addItem(player, 6842, 1, true); //Wings of Destiny Circlet
fileName += "monument_circlet_give.htm";
}
}
else
fileName += "monument_circlet_no_hero.htm";

npc.showChatWindow(player, fileName);
return null;
}
}

Госпади упаси мои глаза, зачем сделать инстанс и в нём проверку на хиро оружия? Лучше фейк сервисов с кучей левого кода.
package services;

import java.util.ArrayList;

import core.gameserver.Config;
import core.gameserver.model.SimpleSpawner;
import core.gameserver.scripts.Functions;
import core.gameserver.scripts.ScriptFile;

public class FightClub extends Functions implements ScriptFile
{
private static final ArrayList<SimpleSpawner> _spawns_fight_club_manager = new ArrayList<SimpleSpawner>();

public static int FIGHT_CLUB_MANAGER = 13112;

private void spawnFightClub()
{
final int FIGHT_CLUB_MANAGER_SPAWN[][] = {

{ 82248, 147544, -3494, 13828 }, // Giran
{ 147480, 27288, -2228, 49151 }, // Aden
{ 82536, 53144, -1521, 0 }, // Oren
{ 16184, 144440, -3054, 16383 }, // Dion
{ 112488, 220264, -3627, 32767 }, // Heine
{ -15048, 121944, -3074, 0 }, // Gludio
{ 147384, -55352, -2759, 60699 }, // Goddard
{ 87688, -143352, -1318, 29412 }, // Shuttgard
{ -84776, 150904, -3154, 0 }, // Gludin
{ 36312, -48232, -1120, 0 }, // Rune
};

SpawnNPCs(FIGHT_CLUB_MANAGER, FIGHT_CLUB_MANAGER_SPAWN, _spawns_fight_club_manager);
}

@Override
public void onLoad()
{
if(Config.FIGHT_CLUB_ENABLED)
spawnFightClub();
}

@Override
public void onReload()
{}

@Override
public void onShutdown()
{}
}
Не легче ли создать группу спавна и сделать менеджером или в самом спавнере.
package services;

import java.util.ArrayList;
import java.util.List;

import core.gameserver.model.Creature;
import core.gameserver.model.Player;
import core.gameserver.model.base.Race;
import core.gameserver.model.instances.NpcInstance;
import core.gameserver.network.l2.s2c.MagicSkillUse;
import core.gameserver.scripts.Functions;
import core.gameserver.tables.SkillTable;

public class SupportMagic extends Functions
{
private final static int[][] _mageBuff = new int[][]{
// minlevel maxlevel skill skilllevel
{6, 75, 4322, 1}, // windwalk
{6, 75, 4323, 1}, // shield
{6, 75, 5637, 1}, // Magic Barrier 1
{6, 75, 4328, 1}, // blessthesoul
{6, 75, 4329, 1}, // acumen
{6, 75, 4330, 1}, // concentration
{6, 75, 4331, 1}, // empower
{16, 34, 4338, 1}, // life cubic
};

private final static int[][] _warrBuff = new int[][]{
// minlevel maxlevel skill
{6, 75, 4322, 1}, // windwalk
{6, 75, 4323, 1}, // shield
{6, 75, 5637, 1}, // Magic Barrier 1
{6, 75, 4324, 1}, // btb
{6, 75, 4325, 1}, // vampirerage
{6, 75, 4326, 1}, // regeneration
{6, 39, 4327, 1}, // haste 1
{40, 75, 5632, 1}, // haste 2
{16, 34, 4338, 1}, // life cubic
};

private final static int[][] _summonBuff = new int[][]{
// minlevel maxlevel skill
{6, 75, 4322, 1}, // windwalk
{6, 75, 4323, 1}, // shield
{6, 75, 5637, 1}, // Magic Barrier 1
{6, 75, 4324, 1}, // btb
{6, 75, 4325, 1}, // vampirerage
{6, 75, 4326, 1}, // regeneration
{6, 75, 4328, 1}, // blessthesoul
{6, 75, 4329, 1}, // acumen
{6, 75, 4330, 1}, // concentration
{6, 75, 4331, 1}, // empower
{6, 39, 4327, 1}, // haste 1
{40, 75, 5632, 1}, // haste 2
};


private final static int minSupLvl = 6;
private final static int maxSupLvl = 75;

public void getSupportMagic()
{
Player player = getSelf();
NpcInstance npc = getNpc();

doSupportMagic(npc, player, false);
}

public void getSupportServitorMagic()
{
Player player = getSelf();
NpcInstance npc = getNpc();

doSupportMagic(npc, player, true);
}

public void getProtectionBlessing()
{
Player player = getSelf();
NpcInstance npc = getNpc();

// Не выдаём блессиг протекшена ПКшникам.
if(player.getKarma() > 0)
return;
if(player.getLevel() > 39 || player.getClassId().getLevel() >= 3)
{
show("default/newbie_blessing_no.htm", player, npc);
return;
}
npc.doCast(SkillTable.getInstance().getInfo(5182, 1), player, true);
}

public static void doSupportMagic(NpcInstance npc, Player player, boolean servitor)
{
// Prevent a cursed weapon weilder of being buffed
if(player.isCursedWeaponEquipped())
return;
int lvl = player.getLevel();

if(servitor && (player.getPet() == null || !player.getPet().isSummon()))
{
show("default/newbie_nosupport_servitor.htm", player, npc);
return;
}
else
{
if(lvl < minSupLvl)
{
show("default/newbie_nosupport_min.htm", player, npc);
return;
}
if(lvl > maxSupLvl)
{
show("default/newbie_nosupport_max.htm", player, npc);
return;
}
}

List<Creature> target = new ArrayList<Creature>();

if(servitor)
{
target.add(player.getPet());

for(int[] buff : _summonBuff)
if(lvl >= buff[0] && lvl <= buff[1])
{
npc.broadcastPacket(new MagicSkillUse(npc, player.getPet(), buff[2], buff[3], 0, 0));
npc.callSkill(SkillTable.getInstance().getInfo(buff[2], buff[3]), target, true);
}
}
else
{
target.add(player);

if(!player.isMageClass() || player.getTemplate().race == Race.orc)
{
for(int[] buff : _warrBuff)
if(lvl >= buff[0] && lvl <= buff[1])
{
npc.broadcastPacket(new MagicSkillUse(npc, player, buff[2], buff[3], 0, 0));
npc.callSkill(SkillTable.getInstance().getInfo(buff[2], buff[3]), target, true);
}
}
else
for(int[] buff : _mageBuff)
if(lvl >= buff[0] && lvl <= buff[1])
{
npc.broadcastPacket(new MagicSkillUse(npc, player, buff[2], buff[3], 0, 0));
npc.callSkill(SkillTable.getInstance().getInfo(buff[2], buff[3]), target, true);
}
}
}

}
Реализовать инстансом религия не позволяет, наверное с проблемой много поточности не разобрался :(
package services;

import core.gameserver.Config;
import core.gameserver.model.Player;
import core.gameserver.scripts.Functions;

public class TeleToCatacomb extends Functions
{
public String DialogAppend_31212(Integer val)
{
return getHtmlAppends(val);
}

public String DialogAppend_31213(Integer val)
{
return getHtmlAppends(val);
}

public String DialogAppend_31214(Integer val)
{
return getHtmlAppends(val);
}

public String DialogAppend_31215(Integer val)
{
return getHtmlAppends(val);
}

public String DialogAppend_31216(Integer val)
{
return getHtmlAppends(val);
}

public String DialogAppend_31217(Integer val)
{
return getHtmlAppends(val);
}

public String DialogAppend_31218(Integer val)
{
return getHtmlAppends(val);
}

public String DialogAppend_31219(Integer val)
{
return getHtmlAppends(val);
}

public String DialogAppend_31220(Integer val)
{
return getHtmlAppends(val);
}

public String DialogAppend_31221(Integer val)
{
return getHtmlAppends(val);
}

public String DialogAppend_31222(Integer val)
{
return getHtmlAppends(val);
}

public String DialogAppend_31223(Integer val)
{
return getHtmlAppends(val);
}

public String DialogAppend_31224(Integer val)
{
return getHtmlAppends(val);
}

public String DialogAppend_31767(Integer val)
{
return getHtmlAppends(val);
}

public String DialogAppend_31768(Integer val)
{
return getHtmlAppends(val);
}

public String DialogAppend_32048(Integer val)
{
return getHtmlAppends(val);
}

public String getHtmlAppends(Integer val)
{
if(val != 0 || !Config.ALT_TELE_TO_CATACOMBS)
return "";

Player player = getSelf();
String append = "";

append += "<br>";

if(player.isLangRus())
{
append += "За определенную плату, вы можете переместиться в катакомбы или некрополисы.<br1> ";
append += "Список доступных локаций:<br>";
}
else
{
append += "Teleport to catacomb or necropolis.<br1> ";
append += "You may teleport to any of the following hunting locations.<br>";
}

if(player.getLevel() <= Config.GATEKEEPER_FREE)
{
append += "[scripts_Util:Gatekeeper -41567 209463 -5080 0|Necropolis of Sacrifice (20-30)]<br1>";
append += "[scripts_Util:Gatekeeper 45248 124223 -5408 0|The Pilgrim's Necropolis (30-40)]<br1>";
append += "[scripts_Util:Gatekeeper 110911 174013 -5439 0|Necropolis of Worship (40-50)]<br1>";
append += "[scripts_Util:Gatekeeper -22101 77383 -5173 0|The Patriot's Necropolis (50-60)]<br1>";
append += "[scripts_Util:Gatekeeper -52654 79149 -4741 0|Necropolis of Devotion (60-70)]<br1>";
append += "[scripts_Util:Gatekeeper 117884 132796 -4831 0|Necropolis of Martyrdom (60-70)]<br1>";
append += "[scripts_Util:Gatekeeper 82750 209250 -5401 0|The Saint's Necropolis (70-80)]<br1>";
append += "[scripts_Util:Gatekeeper 171897 -17606 -4901 0|Disciples Necropolis(70-80)]<br>";

append += "[scripts_Util:Gatekeeper 42322 143927 -5381 0|Catacomb of the Heretic (30-40)]<br1>";
append += "[scripts_Util:Gatekeeper 45841 170307 -4981 0|Catacomb of the Branded (40-50)]<br1>";
append += "[scripts_Util:Gatekeeper 77348 78445 -5125 0|Catacomb of the Apostate (50-60)]<br1>";
append += "[scripts_Util:Gatekeeper 139955 79693 -5429 0|Catacomb of the Witch (60-70)]<br1>";
append += "[scripts_Util:Gatekeeper -19827 13509 -4901 0|Catacomb of Dark Omens (70-80)]<br1>";
append += "[scripts_Util:Gatekeeper 113573 84513 -6541 0|Catacomb of the Forbidden Path (70-80)]";
}
else
{
append += "[scripts_Util:Gatekeeper -41567 209463 -5080 10000|Necropolis of Sacrifice (20-30) - 10000 Adena]<br1>";
append += "[scripts_Util:Gatekeeper 45248 124223 -5408 20000|The Pilgrim's Necropolis (30-40) - 20000 Adena]<br1>";
append += "[scripts_Util:Gatekeeper 110911 174013 -5439 30000|Necropolis of Worship (40-50) - 30000 Adena]<br1>";
append += "[scripts_Util:Gatekeeper -22101 77383 -5173 40000|The Patriot's Necropolis (50-60) - 40000 Adena]<br1>";
append += "[scripts_Util:Gatekeeper -52654 79149 -4741 50000|Necropolis of Devotion (60-70) - 50000 Adena]<br1>";
append += "[scripts_Util:Gatekeeper 117884 132796 -4831 50000|Necropolis of Martyrdom (60-70) - 50000 Adena]<br1>";
append += "[scripts_Util:Gatekeeper 82750 209250 -5401 60000|The Saint's Necropolis (70-80) - 60000 Adena]<br1>";
append += "[scripts_Util:Gatekeeper 171897 -17606 -4901 60000|Disciples Necropolis(70-80) - 60000 Adena]<br>";

append += "[scripts_Util:Gatekeeper 42322 143927 -5381 20000|Catacomb of the Heretic (30-40) - 20000 Adena]<br1>";
append += "[scripts_Util:Gatekeeper 45841 170307 -4981 30000|Catacomb of the Branded (40-50) - 30000 Adena]<br1>";
append += "[scripts_Util:Gatekeeper 77348 78445 -5125 40000|Catacomb of the Apostate (50-60) - 40000 Adena]<br1>";
append += "[scripts_Util:Gatekeeper 139955 79693 -5429 50000|Catacomb of the Witch (60-70) - 50000 Adena]<br1>";
append += "[scripts_Util:Gatekeeper -19827 13509 -4901 60000|Catacomb of Dark Omens (70-80) - 60000 Adena]<br1>";
append += "[scripts_Util:Gatekeeper 113573 84513 -6541 60000|Catacomb of the Forbidden Path (70-80) - 60000 Adena]";
}

return append;
}
}
Ну просто отличная реализация в катакомбы нечего сказать.
Остальные фейк сервисы(да да фейк, это не сервисы) я не стану расписывать т.к однотипно оно сделано, я пойду дальше в кб.
package services.community;

import java.util.StringTokenizer;

import core.gameserver.Config;
import core.gameserver.data.htm.HtmCache;
import core.gameserver.handler.bbs.CommunityBoardManager;
import core.gameserver.model.base.Element;
import core.gameserver.network.l2.s2c.ShowBoard;
import core.gameserver.scripts.Functions;
import core.gameserver.model.Player;
import core.gameserver.model.items.ItemInstance;
import core.gameserver.data.xml.holder.ItemHolder;
import core.gameserver.network.l2.s2c.InventoryUpdate;
import core.gameserver.handler.bbs.ICommunityBoardHandler;
import core.gameserver.templates.item.EtcItemTemplate;
import core.gameserver.network.l2.components.SystemMsg;
import core.gameserver.model.base.TeamType;
import core.gameserver.templates.item.ItemTemplate;
import core.gameserver.scripts.ScriptFile;
import core.gameserver.templates.item.ArmorTemplate.ArmorType;
import core.gameserver.templates.item.support.EnchantItem;
import core.gameserver.utils.BbsUtil;
import core.gameserver.utils.Log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ManageEnchant extends Functions implements ScriptFile, ICommunityBoardHandler
{
static final Logger _log = LoggerFactory.getLogger(ManageEnchant.class);
private int enchant_item = Config.COMMUNITYBOARD_ENCHANT_ITEM;
private int max_enchant = Config.COMMUNITYBOARD_MAX_ENCHANT;
private int[] enchant_level = Config.COMMUNITYBOARD_ENCHANT_LVL;
private int[] ench_price_weapon = Config.COMMUNITYBOARD_ENCHANT_PRICE_WEAPON;
private int[] ench_price_armor = Config.COMMUNITYBOARD_ENCHANT_PRICE_ARMOR;
private int[] atr_lvl_weapon = Config.COMMUNITYBOARD_ENCHANT_ATRIBUTE_LVL_WEAPON;
private int[] atr_price_weapon = Config.COMMUNITYBOARD_ENCHANT_ATRIBUTE_PRICE_WEAPON;
private int[] atr_lvl_armor = Config.COMMUNITYBOARD_ENCHANT_ATRIBUTE_LVL_ARMOR;
private int[] atr_price_armor = Config.COMMUNITYBOARD_ENCHANT_ATRIBUTE_PRICE_ARMOR;
private boolean atr_pvp = Config.COMMUNITYBOARD_ENCHANT_ATRIBUTE_PVP;

@Override
public void onLoad(){
if(Config.COMMUNITYBOARD_ENABLED)
{
_log.info("CommunityBoard: Enchant Community service loaded.");
CommunityBoardManager.getInstance().registerHandler(this);
}
}

@Override
public void onReload(){
if(Config.COMMUNITYBOARD_ENABLED)
{
CommunityBoardManager.getInstance().removeHandler(this);
}
}

@Override
public void onShutdown(){}

@Override
public String[] getBypassCommands(){
return new String[] {
"_cbbsechant",
"_cbbsechantlist",
"_cbbsechantChus",
"_cbbsechantAtr",
"_cbbsechantgo",
"_cbbsechantuseAtr"
};
}

@Override
public void onBypassCommand(Player activeChar, String bypass){
if(!CheckCondition(activeChar))
return;

if (bypass.startsWith("_cbbsechant"))
{
String name = "None Name";
String html = HtmCache.getInstance().getNotNull(Config.BBS_HOME_DIR + "pages/enchant.htm", activeChar);
name = ItemHolder.getInstance().getTemplate(enchant_item).getName();
StringBuilder sb = new StringBuilder("");
sb.append("<table width=400>");
ItemInstance[] arr = activeChar.getInventory().getItems();
int len = arr.length;
for (int i = 0; i < len; i++)
{
ItemInstance _item = arr;
if (_item == null || _item.getTemplate().isBelt() || _item.isCursed() || _item.isArrow()
|| _item.getTemplate().isBracelet() || _item.getTemplate().isCloak() || _item.isNoEnchant()
|| !_item.isEquipped() || _item.isShieldNoEnchant() || _item.getItemType() == ArmorType.SIGIL || _item.isHeroWeapon()
|| _item.getItemId() >= 7816 && _item.getItemId() <= 7831 || _item.isShadowItem()
|| _item.isCommonItem() || _item.getEnchantLevel() >= (max_enchant + 1) || !_item.canBeEnchanted(true)
|| _item.getEquipSlot() == ItemTemplate.SLOT_HAIR || _item.getEquipSlot() == ItemTemplate.SLOT_DHAIR)
continue;
sb.append(new StringBuilder("<tr><td><img src=icon." + _item.getTemplate().getIcon() + " width=32 height=32></td><td>"));
sb.append(new StringBuilder("<font color=\"LEVEL\">" + _item.getTemplate().getName() + " " + (_item.getEnchantLevel() <= 0 ? "" : new StringBuilder("</font><br1><font color=3293F3>Заточено на: +" + _item.getEnchantLevel())) + "</font><br1>"));
sb.append(new StringBuilder("Заточка за: <font color=\"LEVEL\">" + name + "</font>"));
sb.append("<img src=\"l2ui.squaregray\" width=\"170\" height=\"1\">");
sb.append("</td><td>");
if(Config.ALLOW_BBS_ENCHANT_ELEMENTAR)
sb.append(new StringBuilder("<button value=\"Обычная\" action=\"bypass _cbbsechantlist:" + _item.getObjectId() + ";\" width=75 height=18 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\">"));
sb.append("</td><td>");
if(Config.ALLOW_BBS_ENCHANT_ATT)
sb.append(new StringBuilder("<button value=\"Аттрибут\" action=\"bypass _cbbsechantChus:" + _item.getObjectId() + ";\" width=75 height=18 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\">"));
sb.append("</td></tr>");
}

sb.append("</table>");
html = html.replace("%enchanter%", sb.toString());
html = BbsUtil.htmlBuff(html, activeChar);
ShowBoard.separateAndSend(html, activeChar);
}
if (bypass.startsWith("_cbbsechantlist"))
{
StringTokenizer st2 = new StringTokenizer(bypass, ";");
String[] mBypass = st2.nextToken().split(":");
int ItemForEchantObjID = Integer.parseInt(mBypass[1]);
String name = "None Name";
String html = HtmCache.getInstance().getNotNull(Config.BBS_HOME_DIR + "pages/enchant.htm", activeChar);
name = ItemHolder.getInstance().getTemplate(enchant_item).getName();
ItemInstance EhchantItem = activeChar.getInventory().getItemByObjectId(ItemForEchantObjID);

StringBuilder sb = new StringBuilder("");
sb.append("Для обычной заточки выбрана вещь:<br1><table width=300>");
sb.append(new StringBuilder("<tr><td width=32><img src=icon." + EhchantItem.getTemplate().getIcon() + " width=32 height=32> <img src=\"l2ui.squaregray\" width=\"32\" height=\"1\"></td><td width=236><center>"));
sb.append(new StringBuilder("<font color=\"LEVEL\">" + EhchantItem.getTemplate().getName() + " " + (EhchantItem.getEnchantLevel() <= 0 ? "" : new StringBuilder("</font><br1><font color=3293F3>Заточено на: +" + EhchantItem.getEnchantLevel())) + "</font><br1>"));

sb.append(new StringBuilder("Заточка производится за: <font color=\"LEVEL\">" + name + "</font>"));
sb.append("<img src=\"l2ui.squaregray\" width=\"236\" height=\"1\"><center></td>");
sb.append(new StringBuilder("<td width=32><img src=icon." + EhchantItem.getTemplate().getIcon() + " width=32 height=32> <img src=\"l2ui.squaregray\" width=\"32\" height=\"1\"></td>"));
sb.append("</tr>");
sb.append("</table>");
sb.append("<br>");
sb.append("<br>");
sb.append("<table border=0 width=400><tr><td width=200>");
for(int i = 0; i < enchant_level.length; i++)
{
sb.append(new StringBuilder("<button value=\"На +" + enchant_level + " (Цена:" + (EhchantItem.getTemplate().isWeapon() != false ? ench_price_weapon : ench_price_armor) + " " + name + ")\" action=\"bypass _cbbsechantgo:" + enchant_level + ":" + (EhchantItem.getTemplate().isWeapon() != false ? ench_price_weapon : ench_price_armor) + ":" + ItemForEchantObjID + ";\" width=200 height=20 back=\"L2UI_CT1.Button_DF\" fore=\"L2UI_CT1.Button_DF\">"));
//sb.append("<br1>");
}
sb.append("</td></tr></table><br1><button value=\"Назад\" action=\"bypass _cbbsechant;\" width=70 height=18 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\">");
html = html.replace("%enchanter%", sb.toString());
html = BbsUtil.htmlBuff(html, activeChar);
ShowBoard.separateAndSend(html, activeChar);
}
if (bypass.startsWith("_cbbsechantChus"))
{
StringTokenizer st2 = new StringTokenizer(bypass, ";");
String[] mBypass = st2.nextToken().split(":");
int ItemForEchantObjID = Integer.parseInt(mBypass[1]);
String name = "None Name";
String html = HtmCache.getInstance().getNotNull(Config.BBS_HOME_DIR + "pages/enchant.htm", activeChar);
name = ItemHolder.getInstance().getTemplate(enchant_item).getName();
ItemInstance EhchantItem = activeChar.getInventory().getItemByObjectId(ItemForEchantObjID);

StringBuilder sb = new StringBuilder("");
sb.append("Для заточки на атрибут выбрана вещь:<br><table width=300>");
sb.append(new StringBuilder("<tr><td width=32><img src=icon." + EhchantItem.getTemplate().getIcon() + " width=32 height=32> <img src=\"l2ui.squaregray\" width=\"32\" height=\"1\"></td><td width=236><center>"));
sb.append(new StringBuilder("<font color=\"LEVEL\">" + EhchantItem.getTemplate().getName() + " " + (EhchantItem.getEnchantLevel() <= 0 ? "" : new StringBuilder("</font><br1><font color=3293F3>Заточено на: +" + EhchantItem.getEnchantLevel())) + "</font><br1>"));

sb.append(new StringBuilder("Заточка производится за: <font color=\"LEVEL\">" + name + "</font>"));
sb.append("<img src=\"l2ui.squaregray\" width=\"236\" height=\"1\"><center></td>");
sb.append(new StringBuilder("<td width=32><img src=icon." + EhchantItem.getTemplate().getIcon() + " width=32 height=32> <img src=\"l2ui.squaregray\" width=\"32\" height=\"1\"></td>"));
sb.append("</tr>");
sb.append("</table>");
sb.append("<br>");
sb.append("<br>");
sb.append("<table border=0 width=400><tr><td width=200>");
sb.append("<center><img src=icon.etc_wind_stone_i00 width=32 height=32></center><br>");
sb.append(new StringBuilder("<button value=\"Wind \" action=\"bypass _cbbsechantAtr:2:" + ItemForEchantObjID + ";\" width=200 height=20 back=\"L2UI_CT1.Button_DF\" fore=\"L2UI_CT1.Button_DF\">"));
sb.append("<br><center><img src=icon.etc_earth_stone_i00 width=32 height=32></center><br>");
sb.append(new StringBuilder("<button value=\"Earth \" action=\"bypass _cbbsechantAtr:3:" + ItemForEchantObjID + ";\" width=200 height=20 back=\"L2UI_CT1.Button_DF\" fore=\"L2UI_CT1.Button_DF\">"));
sb.append("<br><center><img src=icon.etc_fire_stone_i00 width=32 height=32></center><br>");
sb.append(new StringBuilder("<button value=\"Fire \" action=\"bypass _cbbsechantAtr:0:" + ItemForEchantObjID + ";\" width=200 height=20 back=\"L2UI_CT1.Button_DF\" fore=\"L2UI_CT1.Button_DF\">"));
sb.append("</td><td width=200>");
sb.append("<center><img src=icon.etc_water_stone_i00 width=32 height=32></center><br>");
sb.append(new StringBuilder("<button value=\"Water \" action=\"bypass _cbbsechantAtr:1:" + ItemForEchantObjID + ";\" width=200 height=20 back=\"L2UI_CT1.Button_DF\" fore=\"L2UI_CT1.Button_DF\">"));
sb.append("<br><center><img src=icon.etc_holy_stone_i00 width=32 height=32></center><br>");
sb.append(new StringBuilder("<button value=\"Divine \" action=\"bypass _cbbsechantAtr:4:" + ItemForEchantObjID + ";\" width=200 height=20 back=\"L2UI_CT1.Button_DF\" fore=\"L2UI_CT1.Button_DF\">"));
sb.append("<br><center><img src=icon.etc_unholy_stone_i00 width=32 height=32></center><br>");
sb.append(new StringBuilder("<button value=\"Dark \" action=\"bypass _cbbsechantAtr:5:" + ItemForEchantObjID + ";\" width=200 height=20 back=\"L2UI_CT1.Button_DF\" fore=\"L2UI_CT1.Button_DF\">"));
sb.append("</td></tr></table><br1><button value=\"Назад\" action=\"bypass _cbbsechant;\" width=70 height=18 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\">");
html = html.replace("%enchanter%", sb.toString());
html = BbsUtil.htmlBuff(html, activeChar);
ShowBoard.separateAndSend(html, activeChar);
}
if (bypass.startsWith("_cbbsechantAtr"))
{
StringTokenizer st2 = new StringTokenizer(bypass, ";");
String[] mBypass = st2.nextToken().split(":");
int AtributType = Integer.parseInt(mBypass[1]);
int ItemForEchantObjID = Integer.parseInt(mBypass[2]);
String ElementName = "";
if (AtributType == 0)
ElementName = "Fire";
else if (AtributType == 1)
ElementName = "Water";
else if (AtributType == 2)
ElementName = "Wind";
else if (AtributType == 3)
ElementName = "Earth";
else if (AtributType == 4)
ElementName = "Divine";
else if (AtributType == 5)
ElementName = "Dark";
String name = "None Name";
String html = HtmCache.getInstance().getNotNull(Config.BBS_HOME_DIR + "pages/enchant.htm", activeChar);
name = ItemHolder.getInstance().getTemplate(enchant_item).getName();
ItemInstance EhchantItem = activeChar.getInventory().getItemByObjectId(ItemForEchantObjID);
StringBuilder sb = new StringBuilder("");
sb.append(new StringBuilder("Выбран элемент: <font color=\"LEVEL\">" + ElementName + "</font><br1> Для заточки выбрана вещь:<br1><table width=300>"));
sb.append(new StringBuilder("<tr><td width=32><img src=icon." + EhchantItem.getTemplate().getIcon() + " width=32 height=32> <img src=\"l2ui.squaregray\" width=\"32\" height=\"1\"></td><td width=236><center>"));
sb.append(new StringBuilder("<font color=\"LEVEL\">" + EhchantItem.getTemplate().getName() + " " + (EhchantItem.getEnchantLevel() <= 0 ? "" : new StringBuilder("</font><br1><font color=3293F3>Заточено на: +" + EhchantItem.getEnchantLevel())) + "</font><br1>"));

sb.append(new StringBuilder("Заточка производится за: <font color=\"LEVEL\">" + name + "</font>"));
sb.append("<img src=\"l2ui.squaregray\" width=\"236\" height=\"1\"><center></td>");
sb.append(new StringBuilder("<td width=32><img src=icon." + EhchantItem.getTemplate().getIcon() + " width=32 height=32> <img src=\"l2ui.squaregray\" width=\"32\" height=\"1\"></td>"));
sb.append("</tr>");
sb.append("<br1>");
sb.append("<br1>");
if (EhchantItem.getTemplate().getCrystalType() == ItemTemplate.Grade.S || EhchantItem.getTemplate().getCrystalType() == ItemTemplate.Grade.S80 || EhchantItem.getTemplate().getCrystalType() == ItemTemplate.Grade.S84)
{
sb.append("<table border=0 width=400><tr><td width=200>");
for(int i = 0; i < (EhchantItem.getTemplate().isWeapon() != false ? atr_lvl_weapon.length : atr_lvl_armor.length); i++)
{
sb.append("<center><button value=\"На +");
sb.append(new StringBuilder((EhchantItem.getTemplate().isWeapon() != false ? atr_lvl_weapon : atr_lvl_armor) + " (Цена:" + (EhchantItem.getTemplate().isWeapon() != false ? atr_price_weapon : atr_price_armor) + " " + name + ")\" action=\"bypass _cbbsechantuseAtr:" + (EhchantItem.getTemplate().isWeapon() != false ? atr_lvl_weapon : atr_lvl_armor) + ":" + AtributType + ":" + (EhchantItem.getTemplate().isWeapon() != false ? atr_price_weapon : atr_price_armor) + ":" + ItemForEchantObjID + ";\" width=200 height=20 back=\"L2UI_CT1.Button_DF\" fore=\"L2UI_CT1.Button_DF\">"));
sb.append("<br1>");
}
sb.append("</td></tr></table><br1>");
}
else if (EhchantItem.getTemplate().getCrystalType() == ItemTemplate.Grade.S || EhchantItem.getTemplate().getCrystalType() == ItemTemplate.Grade.S80 || EhchantItem.getTemplate().getCrystalType() == ItemTemplate.Grade.S84)
{
sb.append("<table border=0 width=400><tr><td width=200>");
for(int i = 0; i < (EhchantItem.getTemplate().isWeapon() != false ? atr_lvl_weapon.length : atr_lvl_armor.length); i++)
{
sb.append(new StringBuilder("<center><button value=\"На +" + (EhchantItem.getTemplate().isWeapon() != false ? atr_lvl_weapon : atr_lvl_armor) + " (Цена:" + (EhchantItem.getTemplate().isWeapon() != false ? atr_price_weapon : atr_price_armor) + " " + name + ")\" action=\"bypass _cbbsechantuseAtr:" + (EhchantItem.getTemplate().isWeapon() != false ? atr_lvl_weapon : atr_lvl_armor) + ":" + AtributType + ":" + (EhchantItem.getTemplate().isWeapon() != false ? atr_price_weapon : atr_price_armor) + ":" + ItemForEchantObjID + ";\" width=200 height=20 back=\"L2UI_CT1.Button_DF\" fore=\"L2UI_CT1.Button_DF\">"));
sb.append("<br1>");
}
sb.append("</td></tr></table><br1>");
sb.append("</table>");
}
else
{
sb.append("<table border=0 width=400><tr><td width=200>");
sb.append("<br1>");
sb.append("<br1>");
sb.append("<br1>");
sb.append("<br1>");
sb.append("<center><font color=\"LEVEL\">Заточка данной вещи не возможна!</font></center>");
sb.append("<br1>");
sb.append("<br1>");
sb.append("<br1>");
sb.append("<br1>");
sb.append("</td></tr></table><br1>");
}
sb.append("<button value=\"Назад\" action=\"bypass _cbbsechant;\" width=70 height=18 back=\"L2UI_ct1.button_df\" fore=\"L2UI_ct1.button_df\">");
html = html.replace("%enchanter%", sb.toString());
html = BbsUtil.htmlBuff(html, activeChar);
ShowBoard.separateAndSend(html, activeChar);
}
if (bypass.startsWith("_cbbsechantgo"))
{
StringTokenizer st2 = new StringTokenizer(bypass, ";");
String[] mBypass = st2.nextToken().split(":");
int EchantVal = Integer.parseInt(mBypass[1]);
int EchantPrice = Integer.parseInt(mBypass[2]);
int EchantObjID = Integer.parseInt(mBypass[3]);
ItemTemplate item = ItemHolder.getInstance().getTemplate(enchant_item);
ItemInstance pay = activeChar.getInventory().getItemByItemId(item.getItemId());
ItemInstance EhchantItem = activeChar.getInventory().getItemByObjectId(EchantObjID);
if (pay != null && pay.getCount() >= EchantPrice)
{
activeChar.getInventory().destroyItem(pay, EchantPrice);
EhchantItem.setEnchantLevel(EchantVal);
activeChar.getInventory().equipItem(EhchantItem);
activeChar.sendPacket(new InventoryUpdate().addModifiedItem(EhchantItem));
activeChar.broadcastUserInfo(true);
activeChar.broadcastCharInfo();
activeChar.sendMessage(new StringBuilder("" + EhchantItem.getTemplate().getName() + " было заточено до " + EchantVal + ".").toString());
Log.add(new StringBuilder(activeChar.getName() + " enchant item:" + EhchantItem.getTemplate().getName() + " val: " + EchantVal + "").toString(), "wmzSeller");
onBypassCommand(activeChar, "_cbbsechant");
}
else
activeChar.sendPacket(SystemMsg.INCORRECT_ITEM_COUNT);
}

if (bypass.startsWith("_cbbsechantuseAtr"))
{
StringTokenizer st2 = new StringTokenizer(bypass, ";");
String[] mBypass = st2.nextToken().split(":");
int EchantVal = Integer.parseInt(mBypass[1]);
int AtrType = Integer.parseInt(mBypass[2]);
int EchantPrice = Integer.parseInt(mBypass[3]);
int EchantObjID = Integer.parseInt(mBypass[4]);
ItemTemplate item = ItemHolder.getInstance().getTemplate(enchant_item);
ItemInstance pay = activeChar.getInventory().getItemByItemId(item.getItemId());
ItemInstance EhchantItem = activeChar.getInventory().getItemByObjectId(EchantObjID);
if(EhchantItem.isWeapon()){
if (pay != null && pay.getCount() >= EchantPrice){
activeChar.getInventory().destroyItem(pay, EchantPrice);
activeChar.getInventory().unEquipItem(EhchantItem);
EhchantItem.setAttributeElement(getAttr(AtrType), EchantVal);
activeChar.getInventory().equipItem(EhchantItem);
activeChar.sendPacket(new InventoryUpdate().addModifiedItem(EhchantItem));
activeChar.broadcastUserInfo(true);
activeChar.sendMessage(new StringBuilder("Значение атрибута " + EhchantItem.getTemplate().getName() + " увеличено до " + EchantVal + ".").toString());
Log.add(new StringBuilder(activeChar.getName() + " enchant item:" + EhchantItem.getTemplate().getName() + " val: " + EchantVal + " AtributType:" + AtrType).toString(), "wmzSeller");
onBypassCommand(activeChar, "_cbbsechant");
}
else
activeChar.sendPacket(SystemMsg.INCORRECT_ITEM_COUNT);
}
else if(EhchantItem.isArmor()){
if(!canEnchantArmorAttribute(AtrType, EhchantItem)){
activeChar.sendMessage("Невозможно вставить аттрибут в броню, не соблюдены условия");
return;
}
if (pay != null && pay.getCount() >= EchantPrice){
activeChar.getInventory().destroyItem(pay, EchantPrice);
activeChar.getInventory().unEquipItem(EhchantItem);
EhchantItem.setAttributeElement(getAttr(AtrType), EchantVal);
activeChar.getInventory().equipItem(EhchantItem);
activeChar.sendPacket(new InventoryUpdate().addModifiedItem(EhchantItem));
activeChar.broadcastUserInfo(true);
activeChar.sendMessage(new StringBuilder("Значение атрибута " + EhchantItem.getTemplate().getName() + " увеличено до " + EchantVal + ".").toString());
Log.add(new StringBuilder(activeChar.getName() + " enchant item:" + EhchantItem.getTemplate().getName() + " val: " + EchantVal + " AtributType:" + AtrType).toString(), "wmzSeller");
onBypassCommand(activeChar, "_cbbsechant");
}
}
else{
if (activeChar.isLangRus())
activeChar.sendMessage("В данную вещь нельзя вставить атрибут.");
else
activeChar.sendMessage("In this thing you can not insert the attribute.");
}
}
}

public void onWriteCommand(Player player, String bypass, String arg1, String arg2, String arg3, String arg4, String arg5) {
//To change body of implemented methods use File | Settings | File Templates.
}

private boolean canEnchantArmorAttribute(int attr, ItemInstance item){
switch(attr)
{
case 0:
if(item.getDefenceWater() != 0)
return false;
break;
case 1:
if(item.getDefenceFire() != 0)
return false;
break;
case 2:
if(item.getDefenceEarth() != 0)
return false;
break;
case 3:
if(item.getDefenceWind() != 0)
return false;
break;
case 4:
if(item.getDefenceUnholy() != 0)
return false;
break;
case 5:
if(item.getDefenceHoly() != 0)
return false;
break;
}
return true;
}

private Element getAttr(int attr){
Element El = Element.NONE;
switch(attr)
{
case 0:
El = Element.FIRE;
break;
case 1:
El = Element.WATER;
break;
case 2:
El = Element.WIND;
break;
case 3:
El = Element.EARTH;
break;
case 4:
El = Element.HOLY;
break;
case 5:
El = Element.UNHOLY;
break;
}
return El;
}

private static boolean CheckCondition(Player player){
if(player == null)
return false;

if(player.isDead())
return false;

if((player.getPvpFlag() != 0 || player.isInDuel() || player.isInCombat() || player.isAttackingNow()))
{
if (player.isLangRus())
player.sendMessage("Во время боя нельзя использовать данную функцию.");
else
player.sendMessage("During combat, you can not use this feature.");
return false;
}

if (player.isInOlympiadMode())
{
if (player.isLangRus())
player.sendMessage("Во время Олимпиады нельзя использовать данную функцию.");
else
player.sendMessage("During the Olympics you can not use this feature.");
return false;
}

if (!Config.COMMUNITYBOARD_ENCHANT_ENABLED)
{
if (player.isLangRus())
player.sendMessage("Функция заточки отключена.");
else
player.sendMessage("Enchant off function.");
return false;
}

if (player.getTeam() != TeamType.NONE)
{
if (player.isLangRus())
player.sendMessage("Нельзя использовать заточку во время эвентов.");
else
player.sendMessage("You can not use the enchant during Events.");
return false;
}
return true;
}

}

А теперь берём в руки hxd редактором и ловим веселье. Код просто отменного качества, достоин почёта и уважения. Остальные скрипты кб не стоит смотреть, там чёрт ногу сломит.
services/villagemaster
services/petelove
Не смотреть сюда, опасно может убить
 
package scriptconfig;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

import core.gameserver.scripts.Functions;
import core.gameserver.scripts.ScriptFile;
import core.gameserver.utils.Util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ScriptConfig extends Functions implements ScriptFile
{
private static final Logger _log = LoggerFactory.getLogger(ScriptConfig.class);

private static final String dir = "./config/ScripsConfig";
private static ConcurrentHashMap<String, String> properties;

@Override
public void onLoad()
{
properties = new ConcurrentHashMap<String, String>();
LoadConfig();
_log.info("Loaded Service: ScripsConfig");
}

@Override
public void onReload()
{
onLoad();
}

@Override
public void onShutdown()
{}

public static void LoadConfig()
{
File files = new File(dir);
if (!files.exists())
_log.warn("WARNING! " + dir + " not exists! Config not loaded!");
else
parseFiles(files.listFiles());
}

private static void parseFiles(File[] files)
{
for (File f : files)
{
if (f.isHidden())
continue;
if (f.isDirectory() && !f.getName().contains("defaults"))
parseFiles(f.listFiles());
else if (f.getName().endsWith(".ini"))
{
try
{
InputStream is = new FileInputStream(f);
Properties p = new Properties();
p.load(is);
loadProperties(p);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}

private static void loadProperties(Properties p)
{
for (String name : p.stringPropertyNames())
{
if (properties.get(name) != null)
{
properties.replace(name, p.getProperty(name).trim());
_log.info("Duplicate properties name \"" + name + "\" replaced with new value.");
}
else if (p.getProperty(name) == null)
_log.info("Null property for key " + name);
else
properties.put(name, p.getProperty(name).trim());
}
p.clear();
}

public static String get(String name)
{
if(properties.get(name) == null)
_log.warn("ConfigSystem: Null value for key: " + name);
return properties.get(name);
}

public static float getFloat(String name)
{
return getFloat(name, Float.MAX_VALUE);
}

public static boolean getBoolean(String name)
{
return getBoolean(name, false);
}

public static int getInt(String name)
{
return getInt(name, Integer.MAX_VALUE);
}

public static int[] getIntArray(String name)
{
return getIntArray(name, new int[0]);
}

public static int getIntHex(String name)
{
return getIntHex(name, Integer.decode("0xFFFFFF"));
}

public static byte getByte(String name)
{
return getByte(name, Byte.MAX_VALUE);
}

public static long getLong(String name)
{
return getLong(name, Long.MAX_VALUE);
}

public static double getDouble(String name)
{
return getDouble(name, Double.MAX_VALUE);
}

public static String get(String name, String def)
{
return get(name) == null ? def : get(name);
}

public static float getFloat(String name, float def)
{
return Float.parseFloat(get(name, String.valueOf(def)));
}

public static boolean getBoolean(String name, boolean def)
{
return Boolean.parseBoolean(get(name, String.valueOf(def)));
}

public static int getInt(String name, int def)
{
return Integer.parseInt(get(name, String.valueOf(def)));
}

public static int[] getIntArray(String name, int[] def)
{
return get(name, null) == null ? def : Util.parseCommaSeparatedIntegerArray(get(name, null));
}

public static int getIntHex(String name, int def)
{
if(!get(name, String.valueOf(def)).trim().startsWith("0x"))
return Integer.decode("0x"+get(name, String.valueOf(def)));
else
return Integer.decode(get(name, String.valueOf(def)));
}

public static byte getByte(String name, byte def)
{
return Byte.parseByte(get(name, String.valueOf(def)));
}

public static double getDouble(String name, double def)
{
return Double.parseDouble(get(name, String.valueOf(def)));
}

public static long getLong(String name, long def)
{
return Long.parseLong(get(name, String.valueOf(def)));
}

public static void set(String name, String param)
{
properties.replace(name, param);
}

public static void set(String name, Object obj)
{
set(name, String.valueOf(obj));
}
}
WTF? Мозгов что ли нету, что бы подобную хрень впиливать в эмуль так ещё и в сервисы
 
scripts/instances
scripts/events
scripts/ai
scripts/actions
 
Квесты я не собираюсь тестить. Возьму для начала начальный квест
смотрим. Теперь проверяем и видим, что квест то не верный, награда то выдаётся одна для всех, а посмотрим теперь на квест где заявлено, что реализован весь официальный контент:
package quests;

import core.gameserver.model.base.ClassId;
import core.gameserver.model.instances.NpcInstance;
import core.gameserver.model.quest.Quest;
import core.gameserver.model.quest.QuestState;
import core.gameserver.network.l2.s2c.ExShowScreenMessage;
import core.gameserver.network.l2.s2c.ExShowScreenMessage.ScreenMessageAlign;
import core.gameserver.scripts.ScriptFile;

public class _174_SupplyCheck extends Quest implements ScriptFile
{
@Override
public void onLoad()
{
}

@Override
public void onReload()
{
}

@Override
public void onShutdown()
{
}

int Marcela = 32173;
int Benis = 32170; // warehouse keeper
int Nika = 32167; // grocerer
//int Erinu = 32164; // weapon seller
//int Casca = 32139; // vice hierarch

int WarehouseManifest = 9792;
int GroceryStoreManifest = 9793;
//int WeaponShopManifest = 9794;
//int SupplyReport = 9795;

int WoodenBreastplate = 23;
int WoodenGaiters = 2386;
int LeatherTunic = 429;
int LeatherStockings = 464;
int WoodenHelmet = 43;
int LeatherShoes = 37;
int Gloves = 49;

public _174_SupplyCheck()
{
super(false);

addStartNpc(Marcela);
addTalkId(Benis, Nika); //Erinu, Casca
addQuestItem(WarehouseManifest, GroceryStoreManifest); // WeaponShopManifest, SupplyReport
}

@Override
public String onEvent(String event, QuestState qs, NpcInstance npc)
{
String htmltext = event;
if(event.equalsIgnoreCase("zerstorer_morsell_q0174_04.htm"))
{
qs.setCond(1);
qs.setState(STARTED);
qs.playSound(SOUND_ACCEPT);
}
return htmltext;
}

@Override
public String onTalk(NpcInstance npc, QuestState st)
{
String htmltext = "noquest";
int npcId = npc.getNpcId();
int cond = st.getCond();

if(npcId == Marcela)
{
if(cond == 0)
{
if(st.getPlayer().getLevel() == 1)
{
st.exitCurrentQuest(true);
htmltext = "zerstorer_morsell_q0174_02.htm";
}
else
htmltext = "zerstorer_morsell_q0174_01.htm";
}
else if(cond == 1)
htmltext = "zerstorer_morsell_q0174_05.htm";
else if(cond == 2)
{
st.setCond(3);
st.takeItems(WarehouseManifest, -1);
htmltext = "zerstorer_morsell_q0174_06.htm";
}
else if(cond == 3)
htmltext = "zerstorer_morsell_q0174_07.htm";
else if(cond == 4)
{
if(st.getPlayer().getClassId().isMage() && !st.getPlayer().getClassId().equalsOrChildOf(ClassId.orcMage))
{
st.giveItems(LeatherTunic, 1);
st.giveItems(LeatherStockings, 1);
}
else
{
st.giveItems(WoodenBreastplate, 1);
st.giveItems(WoodenGaiters, 1);
}
st.giveItems(WoodenHelmet, 1);
st.giveItems(LeatherShoes, 1);
st.giveItems(Gloves, 1);
st.giveItems(ADENA_ID, 2466, true);
st.getPlayer().addExpAndSp(5672, 446);
if(st.getPlayer().getClassId().getLevel() == 1 && !st.getPlayer().getVarB("ng1"))
st.getPlayer().sendPacket(new ExShowScreenMessage(" Delivery duty complete.\nGo find the Newbie Guide.", 5000, ScreenMessageAlign.TOP_CENTER, true));
st.exitCurrentQuest(false);
htmltext = "zerstorer_morsell_q0174_12.htm";
}
/*
{
st.setCond(5);
st.takeItems(GroceryStoreManifest, -1);
htmltext = "zerstorer_morsell_q0174_08.htm";
}
else if(cond == 5)
htmltext = "zerstorer_morsell_q0174_09.htm";

else if(cond == 6)
{
st.setCond(7);
st.takeItems(WeaponShopManifest, -1);
st.giveItems(SupplyReport, 1);
htmltext = "zerstorer_morsell_q0174_10.htm";
}
else if(cond == 7)
htmltext = "zerstorer_morsell_q0174_11.htm";

else if(cond == 8)
{
if(st.getPlayer().getClassId().isMage() && !st.getPlayer().getClassId().equalsOrChildOf(ClassId.orcMage))
{
st.giveItems(LeatherTunic, 1);
st.giveItems(LeatherStockings, 1);
}
else
{
st.giveItems(WoodenBreastplate, 1);
st.giveItems(WoodenGaiters, 1);
}

st.giveItems(WoodenHelmet, 1);
st.giveItems(LeatherShoes, 1);
st.giveItems(Gloves, 1);
st.giveItems(ADENA_ID, 2466, true);
st.getPlayer().addExpAndSp(5672, 446, false, false);
if(st.getPlayer().getClassId().getLevel() == 1 && !st.getPlayer().getVarB("ng1"))
st.getPlayer().sendPacket(new ExShowScreenMessage(" Delivery duty complete.\nGo find the Newbie Guide.", 5000, ScreenMessageAlign.TOP_CENTER, true));
st.exitCurrentQuest(false);
htmltext = "zerstorer_morsell_q0174_12.htm";
}
*/
}

else if(npcId == Benis)
if(cond == 1)
{
st.setCond(2);
st.giveItems(WarehouseManifest, 1);
htmltext = "warehouse_keeper_benis_q0174_01.htm";
}
else
htmltext = "warehouse_keeper_benis_q0174_02.htm";

else if(npcId == Nika)
if(cond < 3)
htmltext = "subelder_casca_q0174_01.htm";
else if(cond == 3)
{
st.setCond(4);
st.giveItems(GroceryStoreManifest, 1);
htmltext = "trader_neagel_q0174_02.htm";
}
else
htmltext = "trader_neagel_q0174_03.htm";
/*
else if(npcId == Erinu)
if(cond < 5)
htmltext = "subelder_casca_q0174_01.htm";
else if(cond == 5)
{
st.setCond(6);
st.giveItems(WeaponShopManifest, 1);
htmltext = "trader_erinu_q0174_02.htm";
}
else
htmltext = "subelder_casca_q0174_03.htm";

else if(npcId == Casca)
if(cond < 7)
htmltext = "subelder_casca_q0174_01.htm";
else if(cond == 7)
{
st.setCond(8);
st.takeItems(SupplyReport, -1);
htmltext = "subelder_casca_q0174_02.htm";
}
else
htmltext = "subelder_casca_q0174_03.htm";
*/
return htmltext;
}
}
Не соответствие сказанным словам

Сборка прекрасно подходит как для низкорейтового сервера, так и для высокорейтового.
И как же подходит этот квест например для низко рейтовых серверов. И таких квестов не один
 
Веселая система валидации байпасов который гордится гринд и заявляет типо он придумал и реализовал.
Смотрим и веселимся:
package core.gameserver.enums;

public enum HtmlActionScope
{
NPC_HTML,
NPC_QUEST_HTML,
COMMUNITY_BOARD_HTML,
TUTORIAL_HTML
}
Смотрим лыжу:

Видимо лыжа украла у гринда создав машину времени и раньше залив себе. а FBIagent вообще не достоин быть автором.
Дальше смотрим его мего защиту байпассов:
package core.gameserver.utils;

import java.util.Locale;

import core.gameserver.enums.HtmlActionScope;
import core.gameserver.model.Player;

public class ActionCacheUtil
{
public static final char VAR_PARAM_START_CHAR = '$';

private static final void buildHtmlBypassCache(Player player, HtmlActionScope scope, String html)
{
String htmlLower = html.toLowerCase(Locale.ENGLISH);
int bypassEnd = 0;
int bypassStart = htmlLower.indexOf("=\"bypass ", bypassEnd);
int bypassStartEnd;
while (bypassStart != -1)
{
bypassStartEnd = bypassStart + 9;
bypassEnd = htmlLower.indexOf("\"", bypassStartEnd);
if (bypassEnd == -1)
{
break;
}

int hParamPos = htmlLower.indexOf("-h ", bypassStartEnd);
String bypass;
if ((hParamPos != -1) && (hParamPos < bypassEnd))
{
bypass = html.substring(hParamPos + 3, bypassEnd).trim();
}
else
{
bypass = html.substring(bypassStartEnd, bypassEnd).trim();
}

int firstParameterStart = bypass.indexOf(VAR_PARAM_START_CHAR);
if(firstParameterStart != -1)
{
bypass = bypass.substring(0, firstParameterStart + 1);
}

player.addHtmlAction(scope, bypass);
bypassStart = htmlLower.indexOf("=\"bypass ", bypassEnd);
}
}

public static void buildHtmlActionCache(Player player, HtmlActionScope scope, String html)
{
if(player == null || scope == null || html == null)
{
throw new IllegalArgumentException();
}

buildHtmlBypassCache(player, scope, html);
}
}
Теперь идём опять на сайт лыжи:

И ищем те же самые методы
private static final void buildHtmlBypassCache(L2PcInstance player, HtmlActionScope scope, String html)
{
String htmlLower = html.toLowerCase(Locale.ENGLISH);
int bypassEnd = 0;
int bypassStart = htmlLower.indexOf("=\"bypass ", bypassEnd);
int bypassStartEnd;
while (bypassStart != -1)
{
bypassStartEnd = bypassStart + 9;
bypassEnd = htmlLower.indexOf("\"", bypassStartEnd);
if (bypassEnd == -1)
{
break;
}

int hParamPos = htmlLower.indexOf("-h ", bypassStartEnd);
String bypass;
if ((hParamPos != -1) && (hParamPos < bypassEnd))
{
bypass = html.substring(hParamPos + 3, bypassEnd).trim();
}
else
{
bypass = html.substring(bypassStartEnd, bypassEnd).trim();
}

int firstParameterStart = bypass.indexOf(AbstractHtmlPacket.VAR_PARAM_START_CHAR);
if (firstParameterStart != -1)
{
bypass = bypass.substring(0, firstParameterStart + 1);
}

if (Config.HTML_ACTION_CACHE_DEBUG)
{
LOGGER.info("Cached html bypass(" + scope.toString() + "): '" + bypass + "'");
}
player.addHtmlAction(scope, bypass);
bypassStart = htmlLower.indexOf("=\"bypass ", bypassEnd);
}
}

/**
* Builds the html action cache for the specified scope.<br>
* An {@code npcObjId} of 0 means, the cached actions can be clicked<br>
* without beeing near an npc which is spawned in the world.
* @param player the player to build the html action cache for
* @param scope the scope to build the html action cache for
* @param npcObjId the npc object id the html actions are cached for
* @param html the html code to parse
*/
public static void buildHtmlActionCache(L2PcInstance player, HtmlActionScope scope, int npcObjId, String html)
{
if ((player == null) || (scope == null) || (npcObjId < 0) || (html == null))
{
throw new IllegalArgumentException();
}

if (Config.HTML_ACTION_CACHE_DEBUG)
{
LOGGER.info("Set html action npc(" + scope.toString() + "): " + npcObjId);
}
player.setHtmlActionOriginObjectId(scope, npcObjId);
buildHtmlBypassCache(player, scope, html);
buildHtmlLinkCache(player, scope, html);
}
Не капли не украл у лыжи всё сам реализовал. Молодец, я думаю дальше показывать его систему байпасов не стоит. И да стоит заглянуть в ласт овер или же лостворлд где гитао давно реализовал нормальную валидацию байпассов. И да посмотрим на мего ущербный пакет ещё у Grind-team
package core.gameserver.network.l2.s2c;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import core.gameserver.data.htm.HtmCache;
import core.gameserver.enums.HtmlActionScope;
import core.gameserver.model.Player;
import core.gameserver.model.entity.SevenSignsFestival.SevenSignsFestival;
import core.gameserver.model.instances.NpcInstance;
import core.gameserver.network.l2.components.NpcString;
import core.gameserver.scripts.Functions;
import core.gameserver.scripts.Scripts;
import core.gameserver.scripts.Scripts.ScriptClassAndMethod;
import core.gameserver.utils.ActionCacheUtil;
import core.gameserver.utils.HtmlUtils;
import core.gameserver.utils.Strings;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* the HTML parser in the client knowns these standard and non-standard tags and attributes
* VOLUMN
* UNKNOWN
* UL
* U
* TT
* TR
* TITLE
* TEXTCODE
* TEXTAREA
* TD
* TABLE
* SUP
* SUB
* STRIKE
* SPIN
* SELECT
* RIGHT
* PRE
* P
* OPTION
* OL
* MULTIEDIT
* LI
* LEFT
* INPUT
* IMG
* I
* HTML
* H7
* H6
* H5
* H4
* H3
* H2
* H1
* FONT
* EXTEND
* EDIT
* COMMENT
* COMBOBOX
* CENTER
* BUTTON
* BR
* BODY
* BAR
* ADDRESS
* A
* SEL
* LIST
* VAR
* FORE
* READONL
* ROWS
* VALIGN
* FIXWIDTH
* BORDERCOLORLI
* BORDERCOLORDA
* BORDERCOLOR
* BORDER
* BGCOLOR
* BACKGROUND
* ALIGN
* VALU
* READONLY
* MULTIPLE
* SELECTED
* TYP
* TYPE
* MAXLENGTH
* CHECKED
* SRC
* Y
* X
* QUERYDELAY
* NOSCROLLBAR
* IMGSRC
* B
* FG
* SIZE
* FACE
* COLOR
* DEFFON
* DEFFIXEDFONT
* WIDTH
* VALUE
* TOOLTIP
* NAME
* MIN
* MAX
* HEIGHT
* DISABLED
* ALIGN
* MSG
* LINK
* HREF
* ACTION
* ClassId
* fstring
*/
//TODO [G1ta0] пересмотреть
public class NpcHtmlMessage extends L2GameServerPacket
{
protected static final Logger _log = LoggerFactory.getLogger(NpcHtmlMessage.class);
protected static final Pattern objectId = Pattern.compile("%objectId%");
protected static final Pattern playername = Pattern.compile("%playername%");

protected int _npcObjId;
protected String _html;
protected String _file = null;
protected List<String> _replaces = new ArrayList<String>();
protected boolean have_appends = false;

public NpcHtmlMessage(Player player, int npcId, String filename, int val)
{
List<ScriptClassAndMethod> appends = Scripts.dialogAppends.get(npcId);
if(appends != null && appends.size() > 0)
{
have_appends = true;
if(filename != null && filename.equalsIgnoreCase("npcdefault.htm"))
setHtml(""); // контент задается скриптами через DialogAppend_
else
setFile(filename);

String replaces = "";

// Добавить в конец странички текст, определенный в скриптах.
Object[] script_args = new Object[] { new Integer(val) };
for(ScriptClassAndMethod append : appends)
{
Object obj = Scripts.getInstance().callScripts(player, append.className, append.methodName, script_args);
if(obj != null)
replaces += obj;
}

if(!replaces.equals(""))
replace("</body>", "\n" + Strings.bbParse(replaces) + "</body>");
}
else
setFile(filename);
}

public NpcHtmlMessage(Player player, NpcInstance npc, String filename, int val)
{
this(player, npc.getNpcId(), filename, val);

_npcObjId = npc.getObjectId();

//FIXME [G1ta0] не есть истина, исправить
player.setLastNpc(npc);

replace("%npcId%", String.valueOf(npc.getNpcId()));
replace("%npcname%", npc.getName());
replace("%festivalMins%", SevenSignsFestival.getInstance().getTimeToNextFestivalStr());
}

public NpcHtmlMessage(Player player, NpcInstance npc)
{
if(npc == null)
{
_npcObjId = 5;
player.setLastNpc(null);
}
else
{
_npcObjId = npc.getObjectId();
player.setLastNpc(npc);
}
}

public NpcHtmlMessage(int npcObjId)
{
_npcObjId = npcObjId;
}

public final NpcHtmlMessage setHtml(String text)
{
if(!text.contains("<html>"))
text = "<html><body>" + text + "</body></html>"; //<title>Message:</title> <br><br><br>
_html = text;
return this;
}

public final NpcHtmlMessage setFile(String file)
{
_file = file;
if(_file.startsWith("data/html/"))
{
_log.info("NpcHtmlMessage: need fix : " + file, new Exception());
_file = _file.replace("data/html/", "");
}
return this;
}

public NpcHtmlMessage replace(String pattern, String value)
{
if(pattern == null || value == null)
return this;
_replaces.add(pattern);
_replaces.add(value);
return this;
}

// <fstring></fstring> npcstring-?.dat
public NpcHtmlMessage replaceNpcString(String pattern, NpcString npcString, Object... arg)
{
if(pattern == null)
return this;
if(npcString.getSize() != arg.length)
throw new IllegalArgumentException("Not valid size of parameters: " + npcString);

_replaces.add(pattern);
_replaces.add(HtmlUtils.htmlNpcString(npcString, arg));
return this;
}

@Override
protected void writeImpl()
{
Player player = getClient().getActiveChar();
if(player == null)
return;

if(_file != null) //TODO может быть не очень хорошо здесь это делать...
{
if(player.isGM())
Functions.sendDebugMessage(player, "HTML: " + _file);
String content = HtmCache.getInstance().getNotNull(_file, player);
String content2 = HtmCache.getInstance().getNullable(_file, player);
if(content2 == null)
setHtml(have_appends && _file.endsWith(".htm") ? "" : content);
else
setHtml(content);
}

for(int i = 0; i < _replaces.size(); i += 2)
_html = _html.replace(_replaces.get(i), _replaces.get(i + 1));

if(_html == null)
return;

Matcher m = objectId.matcher(_html);
if(m != null)
_html = m.replaceAll(String.valueOf(_npcObjId));

_html = playername.matcher(_html).replaceAll(player.getName());

player.cleanBypasses(false);
player.clearHtmlActions(getScope());
ActionCacheUtil.buildHtmlActionCache(player, getScope(), _html);
_html = player.encodeBypasses(_html, false);

writeC(0x19);
writeD(_npcObjId);
writeS(_html);
writeD(0x00);
}

public HtmlActionScope getScope()
{
return HtmlActionScope.NPC_HTML;
}
}
 
А вот теперь задумайтесь, все его наработки так же могут быть портированы с l2j подобных сборок будьте осторожны
 
Опять таки вернёмся к реализации согласно официальному серверу. Давайте посмотрим такой механизм как Магазин(Итем-малл):
Смотрим пакеты:
package core.gameserver.network.l2.c2s;

public class RequestExBR_RecentProductList extends L2GameClientPacket
{
@Override
public void readImpl()
{
// триггер
}

@Override
public void runImpl()
{
/* L2Player activeChar = getClient().getActiveChar();

if(activeChar == null)
return;*/

//activeChar.sendMessage("triggered BrRecentProductList()");
}
}
Ага, а не реализован то пакет.
А реализации самих механизмов осталось на том же уровне, что предоставлено овером которая далеко не верная
 
Пошли по пакетам, которые до сих пор не реализованы:
public class WithdrawAlliance extends L2GameServerPacket
{
@Override
protected final void writeImpl()
{
writeC(0xAB);
//TODO d
}
}
ValidatePosition - сюда не смотреть, вы убьёте свои глаза и нервы
package core.gameserver.network.l2.s2c;

import core.gameserver.Config;
import core.gameserver.data.xml.holder.NpcHolder;
import core.gameserver.instancemanager.CursedWeaponsManager;
import core.gameserver.model.Player;
import core.gameserver.model.Skill;
import core.gameserver.model.Zone;
import core.gameserver.model.base.Element;
import core.gameserver.model.base.Experience;
import core.gameserver.model.base.TeamType;
import core.gameserver.model.entity.events.GlobalEvent;
import core.gameserver.model.items.Inventory;
import core.gameserver.model.matching.MatchingRoom;
import core.gameserver.model.pledge.Alliance;
import core.gameserver.model.pledge.Clan;
import core.gameserver.skills.effects.EffectCubic;
import core.gameserver.utils.Location;

public class UserInfo extends L2GameServerPacket
{
private boolean can_writeImpl = false, partyRoom;
private int _runSpd, _walkSpd, _swimRunSpd, _swimWalkSpd, _flRunSpd, _flWalkSpd, _flyRunSpd, _flyWalkSpd, _relation;
private double move_speed, attack_speed, col_radius, col_height;
private int[][] _inv;
private Location _loc, _fishLoc;
private int obj_id, vehicle_obj_id, _race, sex, base_class, level, curCp, maxCp, _enchant, _weaponFlag;
private long _exp;
private int curHp, maxHp, curMp, maxMp, curLoad, maxLoad, rec_left, rec_have;
private int _str, _con, _dex, _int, _wit, _men, _sp, ClanPrivs, InventoryLimit;
private int _patk, _patkspd, _pdef, evasion, accuracy, crit, _matk, _matkspd;
private int _mdef, pvp_flag, karma, hair_style, hair_color, face, gm_commands, fame, vitality;
private int clan_id, clan_crest_id, ally_id, ally_crest_id, large_clan_crest_id;
private int private_store, can_crystalize, pk_kills, pvp_kills, class_id, agathion;
private int _abnormalEffect, _abnormalEffect2, noble, hero, mount_id, cw_level;
private int name_color, running, pledge_class, pledge_type, title_color, transformation;
private int defenceFire, defenceWater, defenceWind, defenceEarth, defenceHoly, defenceUnholy;
private int mount_type;
private String _name, title;
private EffectCubic[] cubics;
private Element attackElement;
private int attackElementValue;
private boolean isFlying, _allowMap;
private int talismans;
private boolean openCloak;
private double _expPercent;
private TeamType _team;

public UserInfo(Player player)
{
if(player.getTransformationName() != null)
{
_name = player.getTransformationName();
title = "";
clan_crest_id = 0;
ally_crest_id = 0;
large_clan_crest_id = 0;
cw_level = CursedWeaponsManager.getInstance().getLevel(player.getCursedWeaponEquippedId());
}
else
{
_name = player.getName();

Clan clan = player.getClan();
Alliance alliance = clan == null ? null : clan.getAlliance();
//
clan_id = clan == null ? 0 : clan.getClanId();
clan_crest_id = clan == null ? 0 : clan.getCrestId();
large_clan_crest_id = clan == null ? 0 : clan.getCrestLargeId();
//
ally_id = alliance == null ? 0 : alliance.getAllyId();
ally_crest_id = alliance == null ? 0 : alliance.getAllyCrestId();

cw_level = 0;
title = player.getTitle();
}

if(player.getPlayerAccess().GodMode && player.isInvisible())
title += "";
if(player.isPolymorphed())
if(NpcHolder.getInstance().getTemplate(player.getPolyId()) != null)
title += " - " + NpcHolder.getInstance().getTemplate(player.getPolyId()).name;
else
title += " - Polymorphed";

if(player.isMounted())
{
_enchant = 0;
mount_id = player.getMountNpcId() + 1000000;
mount_type = player.getMountType();
}
else
{
_enchant = player.getEnchantEffect();
mount_id = 0;
mount_type = 0;
}

_weaponFlag = player.getActiveWeaponInstance() == null ? 0x14 : 0x28;

move_speed = player.getMovementSpeedMultiplier();
_runSpd = (int) (player.getRunSpeed() / move_speed);
_walkSpd = (int) (player.getWalkSpeed() / move_speed);

_flRunSpd = 0; // TODO
_flWalkSpd = 0; // TODO

if(player.isFlying())
{
_flyRunSpd = _runSpd;
_flyWalkSpd = _walkSpd;
}
else
{
_flyRunSpd = 0;
_flyWalkSpd = 0;
}

_swimRunSpd = player.getSwimSpeed();
_swimWalkSpd = player.getSwimSpeed();

_inv = new int[Inventory.PAPERDOLL_MAX][3];
for(int PAPERDOLL_ID : Inventory.PAPERDOLL_ORDER)
{
_inv[PAPERDOLL_ID][0] = player.getInventory().getPaperdollObjectId(PAPERDOLL_ID);
_inv[PAPERDOLL_ID][1] = player.getInventory().getPaperdollItemId(PAPERDOLL_ID);
_inv[PAPERDOLL_ID][2] = player.getInventory().getPaperdollAugmentationId(PAPERDOLL_ID);
}

_relation = player.isClanLeader() ? 0x40 : 0;
for(GlobalEvent e : player.getEvents())
_relation = e.getUserRelation(player, _relation);

_loc = player.getLoc();
obj_id = player.getObjectId();
vehicle_obj_id = player.isInBoat() ? player.getBoat().getObjectId() : 0x00;
_race = player.getRace().ordinal();
sex = player.getSex();
base_class = player.getBaseClassId();
level = player.getLevel();
_exp = player.getExp();
_expPercent = Experience.getExpPercent(player.getLevel(), player.getExp());
_str = player.getSTR();
_dex = player.getDEX();
_con = player.getCON();
_int = player.getINT();
_wit = player.getWIT();
_men = player.getMEN();
curHp = (int) player.getCurrentHp();
maxHp = player.getMaxHp();
curMp = (int) player.getCurrentMp();
maxMp = player.getMaxMp();
curLoad = player.getCurrentLoad();
maxLoad = player.getMaxLoad();
_sp = player.getIntSp();
_patk = player.getPAtk(null);
_patkspd = player.getPAtkSpd();
_pdef = player.getPDef(null);
evasion = player.getEvasionRate(null);
accuracy = player.getAccuracy();
crit = player.getCriticalHit(null, null);
_matk = player.getMAtk(null, null);
_matkspd = player.getMAtkSpd();
_mdef = player.getMDef(null, null);
pvp_flag = Config.RVRMODE_ENABLE ? 0 : player.getPvpFlag(); // 0=white, 1=purple, 2=purpleblink
karma = player.getKarma();
attack_speed = player.getAttackSpeedMultiplier();
col_radius = player.getColRadius();
col_height = player.getColHeight();
if(player.isBeautyShopWearing() && player.getWearHairStyle() != -1)
hair_style = player.getWearHairStyle();
else
hair_style = player.getHairStyle();
if(player.isBeautyShopWearing() && player.getWearHairColor() != -1)
hair_color = player.getWearHairColor();
else
hair_color = player.getHairColor();
if(player.isBeautyShopWearing() && player.getWearFace() != -1)
face = player.getWearFace();
else
face = player.getFace();
gm_commands = player.isGM() || player.getPlayerAccess().CanUseGMCommand ? 1 : 0;
// builder level активирует в клиенте админские команды
clan_id = player.getClanId();
ally_id = player.getAllyId();
private_store = player.getPrivateStoreType();
can_crystalize = player.getSkillLevel(Skill.SKILL_CRYSTALLIZE) > 0 ? 1 : 0;
pk_kills = player.getPkKills();
pvp_kills = player.getPvpKills();
cubics = player.getCubics().toArray(new EffectCubic[player.getCubics().size()]);
_abnormalEffect = player.getAbnormalEffect();
_abnormalEffect2 = player.getAbnormalEffect2();
ClanPrivs = player.getClanPrivileges();
rec_left = player.getRecomLeft(); //c2 recommendations remaining
rec_have = player.getRecomHave(); //c2 recommendations received
InventoryLimit = player.getInventoryLimit();
class_id = player.getClassId().getId();
maxCp = player.getMaxCp();
curCp = (int) player.getCurrentCp();
_team = player.getTeam();
noble = player.isNoble() || player.isGM() && Config.GM_HERO_AURA ? 1 : 0; //0x01: symbol on char menu ctrl+I
hero = player.isHero() || player.isFakeHero() || player.isGM() && Config.GM_HERO_AURA ? 1 : 0; //0x01: Hero Aura and symbol
//fishing = _cha.isFishing() ? 1 : 0; // Fishing Mode
_fishLoc = player.getFishLoc();
name_color = player.getNameColor();
running = player.isRunning() ? 0x01 : 0x00; //changes the Speed display on Status Window
pledge_class = player.getPledgeClass();
pledge_type = player.getPledgeType();
title_color = player.getTitleColor();
transformation = player.getTransformation();
attackElement = player.getAttackElement();
attackElementValue = player.getAttack(attackElement);
defenceFire = player.getDefence(Element.FIRE);
defenceWater = player.getDefence(Element.WATER);
defenceWind = player.getDefence(Element.WIND);
defenceEarth = player.getDefence(Element.EARTH);
defenceHoly = player.getDefence(Element.HOLY);
defenceUnholy = player.getDefence(Element.UNHOLY);
agathion = player.getAgathionId();
fame = player.getFame();
vitality = player.getNevitSystem().isBlessingActive() ? Config.VITALITY_LEVELS[4] : (int) player.getVitality();
partyRoom = player.getMatchingRoom() != null && player.getMatchingRoom().getType() == MatchingRoom.PARTY_MATCHING && player.getMatchingRoom().getLeader() == player;
isFlying = player.isInFlyingTransform();
talismans = player.getTalismanCount();
openCloak = player.getOpenCloak();
_allowMap = player.isActionBlocked(Zone.BLOCKED_ACTION_MINIMAP);

can_writeImpl = true;
}

@Override
protected final void writeImpl()
{
if(!can_writeImpl)
return;

writeC(0x32);

writeD(_loc.x);
writeD(_loc.y);
writeD(_loc.z + Config.CLIENT_Z_SHIFT);
writeD(vehicle_obj_id);
writeD(obj_id);
writeS(_name);
writeD(_race);
writeD(sex);
writeD(base_class);
writeD(level);
writeQ(_exp);
writeF(_expPercent);
writeD(_str);
writeD(_dex);
writeD(_con);
writeD(_int);
writeD(_wit);
writeD(_men);
writeD(maxHp);
writeD(curHp);
writeD(maxMp);
writeD(curMp);
writeD(_sp);
writeD(curLoad);
writeD(maxLoad);
writeD(_weaponFlag);

for(int PAPERDOLL_ID : Inventory.PAPERDOLL_ORDER)
writeD(_inv[PAPERDOLL_ID][0]);

for(int PAPERDOLL_ID : Inventory.PAPERDOLL_ORDER)
writeD(_inv[PAPERDOLL_ID][1]);

for(int PAPERDOLL_ID : Inventory.PAPERDOLL_ORDER)
writeD(_inv[PAPERDOLL_ID][2]);

writeD(talismans);
writeD(openCloak ? 0x01 : 0x00);

writeD(_patk);
writeD(_patkspd);
writeD(_pdef);
writeD(evasion);
writeD(accuracy);
writeD(crit);
writeD(_matk);
writeD(_matkspd);
writeD(_patkspd);
writeD(_mdef);
writeD(pvp_flag);
writeD(karma);
writeD(_runSpd);
writeD(_walkSpd);
writeD(_swimRunSpd); // swimspeed
writeD(_swimWalkSpd); // swimspeed
writeD(_flRunSpd);
writeD(_flWalkSpd);
writeD(_flyRunSpd);
writeD(_flyWalkSpd);
writeF(move_speed);
writeF(attack_speed);
writeF(col_radius);
writeF(col_height);
writeD(hair_style);
writeD(hair_color);
writeD(face);
writeD(gm_commands);
writeS(title);
writeD(clan_id);
writeD(clan_crest_id);
writeD(ally_id);
writeD(ally_crest_id);
// 0x40 leader rights
// siege flags: attacker - 0x180 sword over name, defender - 0x80 shield, 0xC0 crown (|leader), 0x1C0 flag (|leader)
writeD(_relation);
writeC(mount_type); // mount type
writeC(private_store);
writeC(can_crystalize);
writeD(pk_kills);
writeD(pvp_kills);
writeH(cubics.length);
for(EffectCubic cubic : cubics)
writeH(cubic == null ? 0 : cubic.getId());
writeC(partyRoom ? 0x01 : 0x00); //1-find party members
writeD(_abnormalEffect);
writeC(isFlying ? 0x02 : 0x00);
writeD(ClanPrivs);
writeH(rec_left);
writeH(rec_have);
writeD(mount_id);
writeH(InventoryLimit);
writeD(class_id);
writeD(0x00); // special effects? circles around player...
writeD(maxCp);
writeD(curCp);
writeC(_enchant);
writeC(_team.ordinal());
writeD(large_clan_crest_id);
writeC(noble);
writeC(hero);
writeC(0x00);
writeD(_fishLoc.x);
writeD(_fishLoc.y);
writeD(_fishLoc.z);
writeD(name_color);
writeC(running);
writeD(pledge_class);
writeD(pledge_type);
writeD(title_color);
writeD(cw_level);
writeD(transformation); // Transformation id

// AttackElement (0 - Fire, 1 - Water, 2 - Wind, 3 - Earth, 4 - Holy, 5 - Dark, -2 - None)
writeH(attackElement.getId());
writeH(attackElementValue); // AttackElementValue
writeH(defenceFire); // DefAttrFire
writeH(defenceWater); // DefAttrWater
writeH(defenceWind); // DefAttrWind
writeH(defenceEarth); // DefAttrEarth
writeH(defenceHoly); // DefAttrHoly
writeH(defenceUnholy); // DefAttrUnholy

writeD(agathion);

// T2 Starts
writeD(fame); // Fame
writeD(_allowMap ? 1 : 0); // Minimap on Hellbound

writeD(vitality); // Vitality Points
writeD(_abnormalEffect2);
}
}

UserInfo.java - Откуда там нули? Ведь все реализовано согласно официальному серверу
package core.gameserver.network.l2.s2c;

import core.gameserver.model.Player;
import core.gameserver.model.instances.DoorInstance;
import core.gameserver.model.instances.StaticObjectInstance;

public class StaticObject extends L2GameServerPacket
{
private final int _staticObjectId;
private final int _objectId;
private final int _type;
private final int _isTargetable;
private final int _meshIndex;
private final int _isClosed;
private final int _isEnemy;
private final int _maxHp;
private final int _currentHp;
private final int _showHp;
private final int _damageGrade;

public StaticObject(StaticObjectInstance obj)
{
_staticObjectId = obj.getUId();
_objectId = obj.getObjectId();
_type = 0;
_isTargetable = 1;
_meshIndex = obj.getMeshIndex();
_isClosed = 0;
_isEnemy = 0;
_maxHp = 0;
_currentHp = 0;
_showHp = 0;
_damageGrade = 0;
}

public StaticObject(DoorInstance door, Player player)
{
_staticObjectId = door.getDoorId();
_objectId = door.getObjectId();
_type = 1;
_isTargetable = door.getTemplate().isTargetable() ? 1 : 0;
_meshIndex = 1;
_isClosed = door.isOpen() ? 0 : 1; //opened 0 /closed 1
_isEnemy = door.isAutoAttackable(player) ? 1 : 0;
_currentHp = (int) door.getCurrentHp();
_maxHp = door.getMaxHp();
_showHp = door.isHPVisible() ? 1 : 0; //TODO [G1ta0] статус двери для осаждающих
_damageGrade = door.getDamage();
}

@Override
protected final void writeImpl()
{
writeC(0x9f);
writeD(_staticObjectId);
writeD(_objectId);
writeD(_type);
writeD(_isTargetable);
writeD(_meshIndex);
writeD(_isClosed);
writeD(_isEnemy);
writeD(_currentHp);
writeD(_maxHp);
writeD(_showHp);
writeD(_damageGrade);
}
}
Всё так же не доделан статус двери для осаждающих
package core.gameserver.network.l2.s2c;

public class SkillRemainSec extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeC(0xD8);
//TODO ddddddd
}
}
Ну классные пакеты.
package core.gameserver.network.l2.s2c;

public class ShowRadar extends L2GameServerPacket
{
@Override
protected final void writeImpl()
{
writeC(0xAA);
//TODO ddddd
}
}

ShopPreviewList - Опять через жопу работает:
public static int getWearPrice(ItemTemplate item)
{
for(int costume : ItemTemplate.ITEM_ID_FORMAL_WEAR)
if(item.getItemId() == costume)
return 10000;
switch(item.getItemGrade())
{
case D:
return 50;
case C:
return 100;
//TODO: Не известно сколько на оффе стоит примерка B - S84 ранга.
case B:
return 200;
case A:
return 500;
case S:
return 1000;
case S80:
return 2000;
case S84:
return 2500;
default:
return 10;
}
}
И данный человек с 2011 года толком и ничего не сделал
package core.gameserver.network.l2.s2c;

/**
* Пример дампа:
* 0000: 92 2c 05 10 58 77 bb 0f 00 00 00 00 00 00 00 00 .,..Xw..........
* 0010: 54 ff ff b0 42 fe ff 14 ff ff ff 00 00 00 00 00 T...B...........
* 0020: 00 00 00 00 00 f0 3f 00 00 00 00 00 00 f0 3f 00 ......?.......?.
* 0030: 00 00 00 00 00 3e 40 00 00 00 00 00 00 3e 40 00 .....>@......>@.
* 0040: 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 ...............
*/
public class ServerObjectInfo extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeC(0x92);
// TODO ddSdddddffffdddd ServerObjectInfo ID:%d, ClassID:%d, CanBeAttacked:%d, X:%d, Y:%d, Z:%d
}
}
Не ну реализация оставляет желать лучшего. И это можно считать реализован весь официальный контент? Нет. Завтра дополню темам по пакетам.
 
Я вот помню, мне написал пойнтер(zcxv):
Вы никогда не задумывались какой максимальный размер у пакета в л2? Ну хотя бы приблизительно :) Подумайте над этим, а после этого скажите есть ли резон выделять по 64 кб на главный буфер и вспомогательные (принадлежащие конкретно клиентам). Так же, подумайте, чем отличается директ буфер от хип буфера в джаве и как директ буфер работает с сетевой картой и какой его размер наиболее эффективен. Так же рекомендую задуматься, как начинает работать селектор при количестве коннектов более 1000. Ну и конечно же провести микро-тесты, я уверяю, что Вы откроете много нового для себя. И это разьяснение только по одной, малой части, из мною перечисленного
Так вот сеть осталась та же ниошная ничем не изменилась у этих исходников. А теперь смотрим например даже эту тему DDOS гейм порта Классный эмулятор, достойный. Завтра продолжу писать про пакеты, и думаю многим разработчикам станет интересны некоторые офф фишки
 
Продолжаем про пакеты говорить:
package core.gameserver.network.l2.s2c;

public class RequestTimeCheck extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeC(0xC1);
//TODO d
}
}

package core.gameserver.network.l2.c2s;

public class RequestTimeCheck extends L2GameClientPacket
{
private int unk, unk2;

/**
* format: dd
*/
@Override
protected void readImpl()
{
unk = readD();
unk2 = readD();
}

@Override
protected void runImpl()
{
//TODO not implemented
}
}
А где реализация пакета? Да нету зачем, ведь у нас реализовано согласно официальному контенту, а этот пакет наверное масоны придумали но ладно.
package core.gameserver.network.l2.c2s;

public class RequestTeleport extends L2GameClientPacket
{
private int unk, _type, unk2, unk3, unk4;

@Override
protected void readImpl()
{
unk = readD();
_type = readD();
if(_type == 2)
{
unk2 = readD();
unk3 = readD();
}
else if(_type == 3)
{
unk2 = readD();
unk3 = readD();
unk4 = readD();
}
}

@Override
protected void runImpl()
{
//TODO not implemented
}
}
Реализовано от бога просто, с унками которые так объясняют, что там сказано
package core.gameserver.network.l2.c2s;

public class RequestRemainTime extends L2GameClientPacket
{
@Override
protected void readImpl()
{

}

@Override
protected void runImpl()
{
//TODO not implemented
}
}
Чудо трава отпусти меня.
package core.gameserver.network.l2.c2s;

/**
* format: chS
*/
public class RequestPCCafeCouponUse extends L2GameClientPacket
{
// format: (ch)S
private String _unknown;

@Override
protected void readImpl()
{
_unknown = readS();
}

@Override
protected void runImpl()
{
//TODO not implemented
}
}
Опа, а как же так одна из глобальных механик официального сервера и не реализовано, ну да зачем нам работа Pc Cafe купонов и не только нужна верная, ведь и так мы можем заявить типо у нас эмулятор реализован согласно официальному серверу
 
Немного отвлечемя от пакетов и посмотри на ивенты официального сервера, ну у гринда же типо всё по официальному серверу и смотрим:
April Fools -
Evas Inferno -
Hallowen Event -
Raising Rudolph -
Lovers Jubilee
April Fools 10
Так вот где они реализованы у человека которого всё согласно официальному серверу? Да нигде а теперь смотрим пакетку этих вещей:
public class RequestExBR_EventRankerList extends L2GameClientPacket
{
private int unk, unk2, unk3;

/**
* format: ddd
*/
@Override
protected void readImpl()
{
unk = readD();
unk2 = readD();
unk3 = readD();
}

@Override
protected void runImpl()
{
//TODO not implemented
}

}
Ну классный пакет для ивента по офф, но он не сделал.
package org.mmocore.gameserver.network.l2.s2c;

public class ExBR_BuffEventState extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0xDB);
// TODO dddd
}
}
Ну что же опять не реализовано :(, но у нас же всё согласно официальному серверу.
package core.gameserver.network.l2.s2c;

public class ExBR_LoadEventTopRankers extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0xBD);
// TODO ddddd
}
}
Опять :( нету важного пакета для официального сервера.
Вот так вот у нас реализован официальный контент.
 
Последнее редактирование:
RequestEnchantItem.java - Сюда не смотреть там творится полный ад.
package core.gameserver.network.l2.c2s;

import core.gameserver.model.Player;
import core.gameserver.network.l2.s2c.ExGetBookMarkInfo;

public class RequestDeleteBookMarkSlot extends L2GameClientPacket
{
private int slot;

@Override
protected void readImpl()
{
slot = readD();
}

@Override
protected void runImpl()
{
Player activeChar = getClient().getActiveChar();
if(activeChar != null)
{
//TODO Msg.THE_SAVED_TELEPORT_LOCATION_WILL_BE_DELETED_DO_YOU_WISH_TO_CONTINUE
activeChar.bookmarks.remove(slot);
activeChar.sendPacket(new ExGetBookMarkInfo(activeChar));
}
}
}
До сих пор остался тот шлак Msg.java :(. И даже сообщение не нашли верное для реализации :(
package core.gameserver.network.l2.s2c;

public class PledgeExtendedInfo extends L2GameServerPacket
{
@Override
protected final void writeImpl()
{
writeC(0x8A);
//TODO SddSddddddddSd
}
}
Ну вот опять почему не реализовано? Ну наверное, что было овером реализовано так и осталось.
package core.gameserver.network.l2.s2c;

public class OustAllianceMemberPledge extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeC(0xAC);
//TODO d
}
}
Где реализация пакета? ГДЕ?
package core.gameserver.network.l2.s2c;

import org.apache.commons.lang3.StringUtils;
import core.gameserver.Config;
import core.gameserver.model.base.TeamType;
import core.gameserver.model.pledge.Alliance;
import core.gameserver.model.Creature;
import core.gameserver.model.pledge.Clan;
import core.gameserver.model.Summon;
import core.gameserver.model.instances.NpcInstance;
import core.gameserver.network.l2.components.NpcString;
import core.gameserver.utils.Location;

public class NpcInfo extends L2GameServerPacket
{
private boolean can_writeImpl = false;
private int _npcObjId, _npcId, running, incombat, dead, _showSpawnAnimation;
private int _runSpd, _walkSpd, _mAtkSpd, _pAtkSpd, _rhand, _lhand, _enchantEffect;
private int karma, pvp_flag, _abnormalEffect, _abnormalEffect2, clan_id, clan_crest_id, ally_id, ally_crest_id, _formId, _titleColor;
private double colHeight, colRadius, currentColHeight, currentColRadius;
private boolean _isAttackable, _isNameAbove, isFlying;
private Location _loc;
private String _name = StringUtils.EMPTY;
private String _title = StringUtils.EMPTY;
private boolean _showName;
private int _state;
private NpcString _nameNpcString = NpcString.NONE;
private NpcString _titleNpcString = NpcString.NONE;
private TeamType _team;

public NpcInfo(NpcInstance cha, Creature attacker)
{
_npcId = cha.getDisplayId() != 0 ? cha.getDisplayId() : cha.getTemplate().npcId;
_isAttackable = attacker != null && cha.isAutoAttackable(attacker);
_rhand = cha.getRightHandItem();
_lhand = cha.getLeftHandItem();
_enchantEffect = cha.getEnchantEffect();
if(Config.SERVER_SIDE_NPC_NAME || cha.getTemplate().displayId != 0 || cha.getName() != cha.getTemplate().name)
_name = cha.getName();
if(Config.SERVER_SIDE_NPC_TITLE || cha.getTemplate().displayId != 0 || cha.getTitle() != cha.getTemplate().title)
_title = cha.getTitle();

_showSpawnAnimation = cha.getSpawnAnimation();
_showName = cha.isShowName();
_state = cha.getNpcState();
_nameNpcString = cha.getNameNpcString();
_titleNpcString = cha.getTitleNpcString();

common(cha);
}

public NpcInfo(Summon cha, Creature attacker)
{
if(cha.getPlayer() != null && cha.getPlayer().isInvisible())
return;

_npcId = cha.getTemplate().npcId;
_isAttackable = cha.isAutoAttackable(attacker);
_rhand = 0;
_lhand = 0;
_enchantEffect = 0;
_showName = true;
_name = cha.getName();
_title = cha.getTitle();
_showSpawnAnimation = cha.getSpawnAnimation();

common(cha);
}

private void common(Creature cha)
{
colHeight = cha.getColHeight();
colRadius = cha.getColRadius();
currentColHeight = cha.getColHeight();
currentColRadius = cha.getColRadius();
_npcObjId = cha.getObjectId();
_loc = cha.getLoc();
_mAtkSpd = cha.getMAtkSpd();
//
Clan clan = cha.getClan();
Alliance alliance = clan == null ? null : clan.getAlliance();
//
clan_id = clan == null ? 0 : clan.getClanId();
clan_crest_id = clan == null ? 0 : clan.getCrestId();
//
ally_id = alliance == null ? 0 : alliance.getAllyId();
ally_crest_id = alliance == null ? 0 : alliance.getAllyCrestId();

_runSpd = cha.getRunSpeed();
_walkSpd = cha.getWalkSpeed();
karma = cha.getKarma();
pvp_flag = Config.RVRMODE_ENABLE ? 0 : cha.getPvpFlag();
_pAtkSpd = cha.getPAtkSpd();
running = cha.isRunning() ? 1 : 0;
incombat = cha.isInCombat() ? 1 : 0;
dead = cha.isAlikeDead() ? 1 : 0;
_abnormalEffect = cha.getAbnormalEffect();
_abnormalEffect2 = cha.getAbnormalEffect2();
isFlying = cha.isFlying();
_team = cha.getTeam();
_formId = cha.getFormId();
_isNameAbove = cha.isNameAbove();
_titleColor = (cha.isSummon() || cha.isPet()) ? 1 : 0;

can_writeImpl = true;
}

public NpcInfo update()
{
_showSpawnAnimation = 1;
return this;
}

@Override
protected final void writeImpl()
{
if(!can_writeImpl)
return;

writeC(0x0c);
//ddddddddddddddddddffffdddcccccSSddddddddccffddddccd
writeD(_npcObjId);
writeD(_npcId + 1000000); // npctype id c4
writeD(_isAttackable ? 1 : 0);
writeD(_loc.x);
writeD(_loc.y);
writeD(_loc.z + Config.CLIENT_Z_SHIFT);
writeD(_loc.h);
writeD(0x00);
writeD(_mAtkSpd);
writeD(_pAtkSpd);
writeD(_runSpd);
writeD(_walkSpd);
writeD(_runSpd /*_swimRunSpd*//*0x32*/); // swimspeed
writeD(_walkSpd/*_swimWalkSpd*//*0x32*/); // swimspeed
writeD(_runSpd/*_flRunSpd*/);
writeD(_walkSpd/*_flWalkSpd*/);
writeD(_runSpd/*_flyRunSpd*/);
writeD(_walkSpd/*_flyWalkSpd*/);
writeF(1.100000023841858); // взято из клиента
writeF(_pAtkSpd / 277.478340719);
writeF(colRadius);
writeF(colHeight);
writeD(_rhand); // right hand weapon
writeD(0); //TODO chest
writeD(_lhand); // left hand weapon
writeC(_isNameAbove ? 1 : 0); // 2.2: name above char 1=true ... ??; 2.3: 1 - normal, 2 - dead
writeC(running);
writeC(incombat);
writeC(dead);
writeC(_showSpawnAnimation); // invisible ?? 0=false 1=true 2=summoned (only works if model has a summon animation)
writeD(_nameNpcString.getId());
writeS(_name);
writeD(_titleNpcString.getId());
writeS(_title);
writeD(_titleColor); // 0- светло зеленый титул(моб), 1 - светло синий(пет)/отображение текущего МП
writeD(pvp_flag);
writeD(karma); // hmm karma ??
writeD(_abnormalEffect); // C2
writeD(clan_id);
writeD(clan_crest_id);
writeD(ally_id);
writeD(ally_crest_id);
writeC(isFlying ? 2 : 0); // C2
writeC(_team.ordinal()); // team aura 1-blue, 2-red
writeF(currentColRadius); // тут что-то связанное с colRadius
writeF(currentColHeight); // тут что-то связанное с colHeight
writeD(_enchantEffect); // C4
writeD(0x00); // writeD(_npc.isFlying() ? 1 : 0); // C6
writeD(0x00);
writeD(_formId);// great wolf type
writeC(_showName ? 0x01 : 0x00); // show name
writeC(_showName ? 0x01 : 0x00); // show title
writeD(_abnormalEffect2);
writeD(_state);
}
}
Опа, а почему тут присутствуют нули? Ведь всё реализовано согласно официальному серверу.
package core.gameserver.network.l2.c2s;

/**
* Format: (c) ddd
* d: dx
* d: dy
* d: dz
*/
public class MoveWithDelta extends L2GameClientPacket
{
@SuppressWarnings("unused")
private int _dx, _dy, _dz;

@Override
protected void readImpl()
{
_dx = readD();
_dy = readD();
_dz = readD();
}

@Override
protected void runImpl()
{
// TODO this
}
}
А потом вылазиют такие сообщения, админ у меня косячит движение и посмотрев пакет выше Validate Position можно вешаться.
Ну давайте посмотри все пакет GamePacketHandler:
package core.gameserver.network.l2;

import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;

import core.commons.net.nio.impl.IClientFactory;
import core.commons.net.nio.impl.IMMOExecutor;
import core.commons.net.nio.impl.IPacketHandler;
import core.commons.net.nio.impl.MMOConnection;
import core.commons.net.nio.impl.ReceivablePacket;
import core.gameserver.Config;
import core.gameserver.ThreadPoolManager;
import core.gameserver.network.l2.c2s.*;

//import GameGuard.network.l2.c2s.GameGuardReply;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class GamePacketHandler implements IPacketHandler<GameClient>, IClientFactory<GameClient>, IMMOExecutor<GameClient>
{
private static final Logger _log = LoggerFactory.getLogger(GamePacketHandler.class);

@SuppressWarnings("static-access")
@Override
public ReceivablePacket<GameClient> handlePacket(ByteBuffer buf, GameClient client)
{
int id = buf.get() & 0xFF;

ReceivablePacket<GameClient> msg = null;

try
{
int id2 = 0;
switch(client.getState())
{
case CONNECTED:
switch(id)
{
case 0x00:
msg = new RequestStatus();
break;
case 0x0e:
msg = new ProtocolVersion();
break;
case 0x2b:
msg = new AuthLogin();
break;
case 0xCB:
//msg = new GameGuardReply();
break;

default:
client.onUnknownPacket();
break;
}
break;
case AUTHED:
switch(id)
{
case 0x00:
msg = new Logout();
break;
case 0x0c:
msg = new CharacterCreate(); //RequestCharacterCreate();
break;
case 0x0d:
msg = new CharacterDelete(); //RequestCharacterDelete();
break;
case 0x12:
msg = new CharacterSelected(); //CharacterSelect();
break;
case 0x13:
msg = new NewCharacter(); //RequestNewCharacter();
break;
case 0x7b:
msg = new CharacterRestore(); //RequestCharacterRestore();
break;
case 0xCB:
//msg = new GameGuardReply();
break;

case 0xd0:
int id3 = buf.getShort() & 0xffff;
switch(id3)
{
case 0x36:
msg = new GotoLobby();
break;
case 0x93:
msg = new RequestEx2ndPasswordCheck();
break;
case 0x94:
msg = new RequestEx2ndPasswordVerify();
break;
case 0x95:
msg = new RequestEx2ndPasswordReq();
break;
default:
client.onUnknownPacket();
break;
}
break;
default:
client.onUnknownPacket();
break;
}
break;
case IN_GAME:
switch(id)
{
case 0x00:
msg = new Logout();
break;
case 0x01:
msg = new AttackRequest();
break;
case 0x02:
// msg = new ?();
break;

case 0x03:
msg = new RequestStartPledgeWar();
break;
case 0x04:
// msg = new ?();
break;

case 0x05:
msg = new RequestStopPledgeWar();
break;
case 0x06:
// msg = RequestSCCheck(); // ? Format: cdx
break;

case 0x07:
// msg = new ReplyGameGuardQuery();
//здесь совсем другой пакет ResponseAuthGameGuard[cddddd] (c) Drin
break;
case 0x08:
// msg = new ?();
break;

case 0x09:
msg = new RequestSetPledgeCrest();
break;
case 0x0a:
// msg = new ?();
break;

case 0x0b:
msg = new RequestGiveNickName();
break;
case 0x0c:
// wtf???
break;
case 0x0d:
// wtf???
break;

case 0x0f:
msg = new MoveBackwardToLocation();
break;
case 0x10:
// msg = new Say(); Format: cS // старый ?
break;

case 0x11:
msg = new EnterWorld();
break;
case 0x12:
// wtf???
break;

case 0x14:
msg = new RequestItemList();
break;
case 0x15:
// msg = new RequestEquipItem(); // старый?
// Format: cdd server id = %d Slot = %d
break;

case 0x16:
//msg = new RequestUnEquipItem();
break;
case 0x17:
msg = new RequestDropItem();
break;
case 0x18:
// msg = new ?();
break;

case 0x19:
msg = new UseItem();
break;
case 0x1a:
msg = new TradeRequest();
break;
case 0x1b:
msg = new AddTradeItem();
break;
case 0x1c:
msg = new TradeDone();
break;
case 0x1d:
// msg = new ?();
break;
case 0x1e:
// msg = new ?();
break;

case 0x1f:
msg = new Action();
break;
case 0x20:
// msg = new ?();
break;
case 0x21:
// msg = new ?();
break;

case 0x22:
// msg = new RequestLinkHtml();
break;
case 0x23:
msg = new RequestBypassToServer();
break;
case 0x24:
msg = new RequestBBSwrite(); //RequestBBSWrite();
break;
case 0x25:
msg = new RequestCreatePledge();
break;
case 0x26:
msg = new RequestJoinPledge();
break;
case 0x27:
msg = new RequestAnswerJoinPledge();
break;
case 0x28:
msg = new RequestWithdrawalPledge();
break;
case 0x29:
msg = new RequestOustPledgeMember();
break;
case 0x2a:
// msg = new ?();
break;

case 0x2c:
msg = new RequestGetItemFromPet();
break;
case 0x2d:
// RequestDismissParty
break;

case 0x2e:
msg = new RequestAllyInfo();
break;
case 0x2f:
msg = new RequestCrystallizeItem();
break;
case 0x30:
// RequestPrivateStoreManage, устарел
break;
case 0x31:
msg = new SetPrivateStoreSellList();
break;
case 0x32:
// RequestPrivateStoreManageCancel, устарел
break;

case 0x33:
msg = new RequestTeleport();
break;
case 0x34:
//msg = new RequestSocialAction();
break;
case 0x35:
// ChangeMoveType, устарел
break;
case 0x36:
// ChangeWaitType, устарел
break;

case 0x37:
msg = new RequestSellItem();
break;
case 0x38:
msg = new RequestMagicSkillList();
break;
case 0x39:
msg = new RequestMagicSkillUse();
break;
case 0x3a:
msg = new Appearing(); //Appering();
break;
case 0x3b:
if(Config.ALLOW_WAREHOUSE)
msg = new SendWareHouseDepositList();
break;
case 0x3c:
msg = new SendWareHouseWithDrawList();
break;
case 0x3d:
msg = new RequestShortCutReg();
break;
case 0x3e:
// msg = new RequestShortCutUse(); // Format: cddc ?
break;

case 0x3f:
msg = new RequestShortCutDel();
break;
case 0x40:
msg = new RequestBuyItem();
break;
case 0x41:
// msg = new RequestDismissPledge(); //Format: c ?
break;

case 0x42:
msg = new RequestJoinParty();
break;
case 0x43:
msg = new RequestAnswerJoinParty();
break;
case 0x44:
msg = new RequestWithDrawalParty();
break;
case 0x45:
msg = new RequestOustPartyMember();
break;
case 0x46:
msg = new RequestDismissParty();
break;
case 0x47:
msg = new CannotMoveAnymore();
break;
case 0x48:
msg = new RequestTargetCanceld();
break;
case 0x49:
msg = new Say2C();
break;
// -- maybe GM packet's
case 0x4a:
id2 = buf.get() & 0xff;
switch(id2)
{
case 0x00:
// msg = new SendCharacterInfo(); // Format: S
break;
case 0x01:
// msg = new SendSummonCmd(); // Format: S
break;
case 0x02:
// msg = new SendServerStatus(); // Format: (noargs)
break;
case 0x03:
// msg = new SendL2ParamSetting(); // Format: dd
break;
default:
client.onUnknownPacket();
break;
}
break;

case 0x4b:
// msg = new ?();
break;
case 0x4c:
// msg = new ?();
break;

case 0x4d:
msg = new RequestPledgeMemberList();
break;
case 0x4e:
// msg = new ?();
break;
case 0x4f:
// msg = new RequestMagicItem(); // Format: c ?
break;

case 0x50:
msg = new RequestSkillList(); // trigger
break;
case 0x51:
// msg = new ?();
break;

case 0x52:
msg = new MoveWithDelta();
break;
case 0x53:
msg = new RequestGetOnVehicle();
break;
case 0x54:
msg = new RequestGetOffVehicle();
break;
case 0x55:
msg = new AnswerTradeRequest();
break;
case 0x56:
msg = new RequestActionUse();
break;
case 0x57:
msg = new RequestRestart();
break;
case 0x58:
msg = new RequestSiegeInfo();
break;
case 0x59:
msg = new ValidatePosition();
break;
case 0x5a:
msg = new RequestSEKCustom();
break;
case 0x5b:
msg = new StartRotatingC();
break;
case 0x5c:
msg = new FinishRotatingC();
break;
case 0x5d:
// msg = new ?();
break;

case 0x5e:
msg = new RequestShowBoard();
break;
case 0x5f:
msg = new RequestEnchantItem();
break;
case 0x60:
msg = new RequestDestroyItem();
break;
case 0x61:
// msg = new ?();
break;

case 0x62:
msg = new RequestQuestList();
break;
case 0x63:
msg = new RequestQuestAbort(); //RequestDestroyQuest();
break;
case 0x64:
// msg = new ?();
break;

case 0x65:
msg = new RequestPledgeInfo();
break;
case 0x66:
msg = new RequestPledgeExtendedInfo();
break;
case 0x67:
msg = new RequestPledgeCrest();
break;
case 0x68:
// msg = new ?();
break;
case 0x69:
// msg = new ?();
break;
case 0x6a:
// msg = new ?();
break;

case 0x6b:
msg = new RequestSendL2FriendSay();
break;
case 0x6c:
msg = new RequestShowMiniMap(); //RequestOpenMinimap();
break;
case 0x6d:
msg = new RequestSendMsnChatLog();
break;
case 0x6e:
msg = new RequestReload(); // record video
break;
case 0x6f:
msg = new RequestHennaEquip();
break;
case 0x70:
msg = new RequestHennaUnequipList();
break;
case 0x71:
msg = new RequestHennaUnequipInfo();
break;
case 0x72:
msg = new RequestHennaUnequip();
break;
case 0x73:
msg = new RequestAquireSkillInfo(); //RequestAcquireSkillInfo();
break;
case 0x74:
msg = new SendBypassBuildCmd();
break;
case 0x75:
msg = new RequestMoveToLocationInVehicle();
break;
case 0x76:
msg = new CannotMoveAnymoreInVehicle();
break;
case 0x77:
msg = new RequestFriendInvite();
break;
case 0x78:
msg = new RequestFriendAddReply();
break;
case 0x79:
msg = new RequestFriendList();
break;
case 0x7a:
msg = new RequestFriendDel();
break;
case 0x7c:
msg = new RequestAquireSkill();
break;
case 0x7d:
msg = new RequestRestartPoint();
break;
case 0x7e:
msg = new RequestGMCommand();
break;
case 0x7f:
msg = new RequestPartyMatchConfig();
break;
case 0x80:
msg = new RequestPartyMatchList();
break;
case 0x81:
msg = new RequestPartyMatchDetail();
break;
case 0x82:
msg = new RequestPrivateStoreList();
break;
case 0x83:
msg = new RequestPrivateStoreBuy();
break;
case 0x84:
// msg = new ReviveReply(); // format: cd ?
break;

case 0x85:
msg = new RequestTutorialLinkHtml();
break;
case 0x86:
msg = new RequestTutorialPassCmdToServer();
break;
case 0x87:
msg = new RequestTutorialQuestionMark(); //RequestTutorialQuestionMarkPressed();
break;
case 0x88:
msg = new RequestTutorialClientEvent();
break;
case 0x89:
msg = new RequestPetition();
break;
case 0x8a:
msg = new RequestPetitionCancel();
break;
case 0x8b:
msg = new RequestGmList();
break;
case 0x8c:
msg = new RequestJoinAlly();
break;
case 0x8d:
msg = new RequestAnswerJoinAlly();
break;
case 0x8e:
// Команда /allyleave - выйти из альянса
msg = new RequestWithdrawAlly();
break;
case 0x8f:
// Команда /allydismiss - выгнать клан из альянса
msg = new RequestOustAlly();
break;
case 0x90:
// Команда /allydissolve - распустить альянс
msg = new RequestDismissAlly();
break;
case 0x91:
msg = new RequestSetAllyCrest();
break;
case 0x92:
msg = new RequestAllyCrest();
break;
case 0x93:
msg = new RequestChangePetName();
break;
case 0x94:
msg = new RequestPetUseItem();
break;
case 0x95:
msg = new RequestGiveItemToPet();
break;
case 0x96:
msg = new RequestPrivateStoreQuitSell();
break;
case 0x97:
msg = new SetPrivateStoreMsgSell();
break;
case 0x98:
msg = new RequestPetGetItem();
break;
case 0x99:
msg = new RequestPrivateStoreBuyManage();
break;
case 0x9a:
msg = new SetPrivateStoreBuyList();
break;
case 0x9b:
//
break;

case 0x9c:
msg = new RequestPrivateStoreQuitBuy();
break;
case 0x9d:
msg = new SetPrivateStoreMsgBuy();
break;
case 0x9e:
//
break;

case 0x9f:
msg = new RequestPrivateStoreBuySellList();
break;
case 0xa0:
msg = new RequestTimeCheck();
break;
case 0xa1:
// msg = new ?();
break;
case 0xa2:
// msg = new ?();
break;
case 0xa3:
// msg = new ?();
break;
case 0xa4:
// msg = new ?();
break;
case 0xa5:
// msg = new ?();
break;

case 0xa6:
//msg = new RequestSkillCoolTime(); //Deprecated ?
break;
case 0xa7:
msg = new RequestPackageSendableItemList();
break;
case 0xa8:
msg = new RequestPackageSend();
break;
case 0xa9:
msg = new RequestBlock();
break;
case 0xaa:
// msg = new RequestCastleSiegeInfo(); // format: cd ?
break;

case 0xab:
msg = new RequestCastleSiegeAttackerList();
break;
case 0xac:
msg = new RequestCastleSiegeDefenderList();
break;
case 0xad:
msg = new RequestJoinCastleSiege();
break;
case 0xae:
msg = new RequestConfirmCastleSiegeWaitingList();
break;
case 0xaf:
msg = new RequestSetCastleSiegeTime();
break;
case 0xb0:
msg = new RequestMultiSellChoose();
break;
case 0xb1:
msg = new NetPing();
break;
case 0xb2:
msg = new RequestRemainTime();
break;
case 0xb3:
msg = new BypassUserCmd();
break;
case 0xb4:
msg = new SnoopQuit();
break;
case 0xb5:
msg = new RequestRecipeBookOpen();
break;
case 0xb6:
msg = new RequestRecipeItemDelete();
break;
case 0xb7:
msg = new RequestRecipeItemMakeInfo();
break;
case 0xb8:
msg = new RequestRecipeItemMakeSelf();
break;
case 0xb9:
// msg = new RequestRecipeShopManageList(); deprecated // format: c
break;

case 0xba:
msg = new RequestRecipeShopMessageSet();
break;
case 0xbb:
msg = new RequestRecipeShopListSet();
break;
case 0xbc:
msg = new RequestRecipeShopManageQuit();
break;
case 0xbd:
msg = new RequestRecipeShopManageCancel();
break;
case 0xbe:
msg = new RequestRecipeShopMakeInfo();
break;
case 0xbf:
msg = new RequestRecipeShopMakeDo();
break;
case 0xc0:
msg = new RequestRecipeShopSellList();
break;
case 0xc1:
msg = new RequestObserverEnd();
break;
case 0xc2:
//msg = new VoteSociality(); // Recommend
break;

case 0xc3:
msg = new RequestHennaList(); //RequestHennaItemList();
break;
case 0xc4:
msg = new RequestHennaItemInfo();
break;
case 0xc5:
msg = new RequestBuySeed();
break;
case 0xc6:
msg = new ConfirmDlg();
break;
case 0xc7:
msg = new RequestPreviewItem();
break;
case 0xc8:
msg = new RequestSSQStatus();
break;
case 0xc9:
msg = new PetitionVote();
break;
case 0xca:
// msg = new ?();
break;
case 0xcb:
//msg = new GameGuardReply();
break;

case 0xcc:
msg = new RequestPledgePower();
break;
case 0xcd:
msg = new RequestMakeMacro();
break;
case 0xce:
msg = new RequestDeleteMacro();
break;
case 0xcf:
msg = new RequestProcureCrop(); // ?
break;
case 0xd0:
int id3 = buf.getShort() & 0xffff;
switch(id3)
{
case 0x00:
// msg = new ?();
break;

case 0x01:
msg = new RequestManorList();
break;
case 0x02:
msg = new RequestProcureCropList();
break;
case 0x03:
msg = new RequestSetSeed();
break;
case 0x04:
msg = new RequestSetCrop();
break;
case 0x05:
msg = new RequestWriteHeroWords();
break;
case 0x06:
msg = new RequestExMPCCAskJoin(); //RequestExAskJoinMPCC();
break;
case 0x07:
msg = new RequestExMPCCAcceptJoin(); //RequestExAcceptJoinMPCC();
break;
case 0x08:
msg = new RequestExOustFromMPCC();
break;
case 0x09:
msg = new RequestOustFromPartyRoom();
break;
case 0x0a:
msg = new RequestDismissPartyRoom();
break;
case 0x0b:
msg = new RequestWithdrawPartyRoom();
break;
case 0x0c:
msg = new RequestHandOverPartyMaster();
break;
case 0x0d:
msg = new RequestAutoSoulShot();
break;
case 0x0e:
msg = new RequestExEnchantSkillInfo();
break;
case 0x0f:
msg = new RequestExEnchantSkill();
break;
case 0x10:
msg = new RequestPledgeCrestLarge();
break;
case 0x11:
msg = new RequestSetPledgeCrestLarge();
break;
case 0x12:
msg = new RequestPledgeSetAcademyMaster();
break;
case 0x13:
msg = new RequestPledgePowerGradeList();
break;
case 0x14:
msg = new RequestPledgeMemberPowerInfo();
break;
case 0x15:
msg = new RequestPledgeSetMemberPowerGrade();
break;
case 0x16:
msg = new RequestPledgeMemberInfo();
break;
case 0x17:
msg = new RequestPledgeWarList();
break;
case 0x18:
msg = new RequestExFishRanking();
break;
case 0x19:
msg = new RequestPCCafeCouponUse();
break;
case 0x1a:
// msg = new ?();
// format: (ch)b, b - array размером в 64 байта
break;

case 0x1b:
msg = new RequestDuelStart();
break;
case 0x1c:
msg = new RequestDuelAnswerStart();
break;
case 0x1d:
msg = new RequestTutorialClientEvent(); //RequestExSetTutorial();
// Format: d / требует отладки, ИМХО, это совсем другой пакет (с) Drin
break;

case 0x1e:
msg = new RequestExRqItemLink(); // chat item links
break;
case 0x1f:
// CanNotMoveAnymore(AirShip)
// format: (ch)ddddd
break;

case 0x20:
msg = new RequestExMoveToLocationInAirShip();
break;
case 0x21:
msg = new RequestKeyMapping();
break;
case 0x22:
msg = new RequestSaveKeyMapping();
break;
case 0x23:
msg = new RequestExRemoveItemAttribute();
break;
case 0x24:
msg = new RequestSaveInventoryOrder(); // сохранение порядка инвентаря
break;
case 0x25:
msg = new RequestExitPartyMatchingWaitingRoom();
break;
case 0x26:
msg = new RequestConfirmTargetItem();
break;
case 0x27:
msg = new RequestConfirmRefinerItem();
break;
case 0x28:
msg = new RequestConfirmGemStone();
break;
case 0x29:
msg = new RequestOlympiadObserverEnd();
break;
case 0x2a:
msg = new RequestCursedWeaponList();
break;
case 0x2b:
msg = new RequestCursedWeaponLocation();
break;
case 0x2c:
msg = new RequestPledgeReorganizeMember();
break;
case 0x2d:
msg = new RequestExMPCCShowPartyMembersInfo();
break;
case 0x2e:
msg = new RequestExOlympiadObserverEnd(); // не уверен (в клиенте называется RequestOlympiadMatchList)
break;
case 0x2f:
msg = new RequestAskJoinPartyRoom();
break;
case 0x30:
msg = new AnswerJoinPartyRoom();
break;
case 0x31:
msg = new RequestListPartyMatchingWaitingRoom();
break;
case 0x32:
msg = new RequestExEnchantSkillSafe();
break;
case 0x33:
msg = new RequestExEnchantSkillUntrain();
break;
case 0x34:
msg = new RequestExEnchantSkillRouteChange();
break;
case 0x35:
msg = new RequestEnchantItemAttribute();
break;
case 0x36:
//RequestGotoLobby - случается при многократном нажатии кнопки "вход"
break;

case 0x38:
msg = new RequestExMoveToLocationAirShip();
break;
case 0x39:
msg = new RequestBidItemAuction();
break;
case 0x3a:
msg = new RequestInfoItemAuction();
break;
case 0x3b:
msg = new RequestExChangeName();
break;
case 0x3c:
msg = new RequestAllCastleInfo();
break;
case 0x3d:
msg = new RequestAllFortressInfo();
break;
case 0x3e:
msg = new RequestAllAgitInfo();
break;
case 0x3f:
msg = new RequestFortressSiegeInfo();
break;
case 0x40:
msg = new RequestGetBossRecord();
break;
case 0x41:
msg = new RequestRefine();
break;
case 0x42:
msg = new RequestConfirmCancelItem();
break;
case 0x43:
msg = new RequestRefineCancel();
break;
case 0x44:
msg = new RequestExMagicSkillUseGround();
break;
case 0x45:
msg = new RequestDuelSurrender();
break;
case 0x46:
msg = new RequestExEnchantSkillInfoDetail();
break;
/*case 0x47: ?*/
case 0x48:
msg = new RequestFortressMapInfo();
break;
case 0x49:
msg = new RequestPVPMatchRecord();
break;
case 0x4a:
msg = new SetPrivateStoreWholeMsg();
break;
case 0x4b:
msg = new RequestDispel();
break;
case 0x4c:
msg = new RequestExTryToPutEnchantTargetItem();
break;
case 0x4d:
msg = new RequestExTryToPutEnchantSupportItem();
break;
case 0x4e:
msg = new RequestExCancelEnchantItem();
break;
case 0x4f:
msg = new RequestChangeNicknameColor();
break;
case 0x50:
msg = new RequestResetNickname();
break;
case 0x51:
int id4 = buf.getInt();
switch(id4)
{
case 0x00:
msg = new RequestBookMarkSlotInfo();
break;
case 0x01:
msg = new RequestSaveBookMarkSlot();
break;
case 0x02:
msg = new RequestModifyBookMarkSlot();
break;
case 0x03:
msg = new RequestDeleteBookMarkSlot();
break;
case 0x04:
msg = new RequestTeleportBookMark();
break;
case 0x05:
msg = new RequestChangeBookMarkSlot();
break;
default:
client.onUnknownPacket();
break;
}
break;
case 0x52:
msg = new RequestWithDrawPremiumItem();
break;
case 0x53:
msg = new RequestExJump();
break;
case 0x54:
msg = new RequestExStartShowCrataeCubeRank();
break;
case 0x55:
msg = new RequestExStopShowCrataeCubeRank();
break;
case 0x56:
msg = new NotifyStartMiniGame();
break;
case 0x57:
msg = new RequestExJoinDominionWar();
break;
case 0x58:
msg = new RequestExDominionInfo();
break;
case 0x59:
msg = new RequestExCleftEnter();
break;
case 0x5A:
msg = new RequestExCubeGameChangeTeam();
break;
case 0x5B:
msg = new RequestExEndScenePlayer();
break;
case 0x5C:
msg = new RequestExCubeGameReadyAnswer();
break;
case 0x5D:
msg = new RequestExListMpccWaiting();
break;
case 0x5E:
msg = new RequestExManageMpccRoom();
break;
case 0x5F:
msg = new RequestExJoinMpccRoom();
break;
case 0x60:
msg = new RequestExOustFromMpccRoom();
break;
case 0x61:
msg = new RequestExDismissMpccRoom();
break;
case 0x62:
msg = new RequestExWithdrawMpccRoom();
break;
case 0x63:
msg = new RequestExSeedPhase();
break;
case 0x64:
msg = new RequestExMpccPartymasterList();
break;
case 0x65:
msg = new RequestExPostItemList();
break;
case 0x66:
msg = new RequestExSendPost();
break;
case 0x67:
msg = new RequestExRequestReceivedPostList();
break;
case 0x68:
msg = new RequestExDeleteReceivedPost();
break;
case 0x69:
msg = new RequestExRequestReceivedPost();
break;
case 0x6A:
msg = new RequestExReceivePost();
break;
case 0x6B:
msg = new RequestExRejectPost();
break;
case 0x6C:
msg = new RequestExRequestSentPostList();
break;
case 0x6D:
msg = new RequestExDeleteSentPost();
break;
case 0x6E:
msg = new RequestExRequestSentPost();
break;
case 0x6F:
msg = new RequestExCancelSentPost();
break;
case 0x70:
msg = new RequestExShowNewUserPetition();
break;
case 0x71:
msg = new RequestExShowStepTwo();
break;
case 0x72:
msg = new RequestExShowStepThree();
break;
case 0x73:
//msg = new ExRaidReserveResult();
break;

case 0x75:
msg = new RequestExRefundItem();
break;
case 0x76:
msg = new RequestExBuySellUIClose();
break;
case 0x77:
msg = new RequestExEventMatchObserverEnd();
break;
case 0x78:
msg = new RequestPartyLootModification();
break;
case 0x79:
msg = new AnswerPartyLootModification();
break;
case 0x7A:
msg = new AnswerCoupleAction();
break;
case 0x7B:
msg = new RequestExBR_EventRankerList();
break;
case 0x7C:
//msg = new RequestAskMemberShip();
break;

case 0x7D:
msg = new RequestAddExpandQuestAlarm();
break;
case 0x7E:
msg = new RequestVoteNew();
break;
case 0x7F:
_log.info("D0:7F");
break;
case 0x80:
_log.info("D0:80");
break;
case 0x81:
_log.info("D0:81");
break;
case 0x82:
_log.info("D0:82");
break;
case 0x83:
int id5 = buf.getInt();
switch(id5)
{
/* TODO:
case 0x01:
//msg = new RequestExAgitInitialize chd 0x01
break;
case 0x02:
//msg = new RequestExAgitDetailInfo chdcd 0x02
break;
case 0x03:
//msg = new RequestExMyAgitState chd 0x03
break;
case 0x04:
//msg = new RequestExRegisterAgitForBidStep1 chd 0x04
break;
case 0x05:
//msg = new RequestExRegisterAgitForBidStep2 chddQd 0x05
//msg = new RequestExRegisterAgitForBidStep3 chddQd 0x05 -no error? 0x05
break;
case 0x07:
//msg = new RequestExConfirmCancelRegisteringAgit chd 0x07
break;
case 0x08:
//msg = new RequestExProceedCancelRegisteringAgit chd 0x08
break;
case 0x09:
//msg = new RequestExConfirmCancelAgitBid chdd 0x09
break;
case 0x10:
//msg = new RequestExReBid chdd 0x10
break;
case 0x11:
//msg = new RequestExAgitListForLot chd 0x11
break;
case 0x12:
//msg = new RequestExApplyForAgitLotStep1 chdc 0x12
break;
case 0x13:
//msg = new RequestExApplyForAgitLotStep2 chdc 0x13
break;
case 0x14:
//msg = new RequestExAgitListForBid chdd 0x14
break;
case 0x0D:
//msg = new RequestExApplyForBidStep1 chdd 0x0D
break;
case 0x0E:
//msg = new RequestExApplyForBidStep2 chddQ 0x0E
break;
case 0x0F:
//msg = new RequestExApplyForBidStep3 chddQ 0x0F
break;
case 0x09:
//msg = new RequestExConfirmCancelAgitLot chdc 0x09
break;
case 0x0A:
//msg = new RequestExProceedCancelAgitLot chdc 0x0A
break;
case 0x0A:
//msg = new RequestExProceedCancelAgitBid chdd 0x0A
break;
*/
}
break;

case 0x84:
msg = new RequestExAddPostFriendForPostBox();
break;
case 0x85:
msg = new RequestExDeletePostFriendForPostBox();
break;
case 0x86:
msg = new RequestExShowPostFriendListForPostBox();
break;
case 0x87:
msg = new RequestExFriendListForPostBox();
break;
case 0x88:
msg = new RequestOlympiadMatchList();
break;
case 0x89:
msg = new RequestExBR_GamePoint();
break;
case 0x8A:
msg = new RequestExBR_ProductList();
break;
case 0x8B:
msg = new RequestExBR_ProductInfo();
break;
case 0x8C:
msg = new RequestExBR_BuyProduct();
break;
case 0x8D:
msg = new RequestExBR_RecentProductList();
break;
case 0x8E:
msg = new RequestBR_MiniGameLoadScores();
break;
case 0x8F:
msg = new RequestBR_MiniGameInsertScore();
break;
case 0x90:
msg = new RequestExBR_LectureMark();
break;
case 0x91:
msg = new RequestGoodsInventoryInfo();
break;
case 0x92:
//msg = new RequestUseGoodsInventoryItem();
break;

default:
client.onUnknownPacket();
break;
}
break;

default:
{
client.onUnknownPacket();
break;
}
}
break;
}
}
catch(BufferUnderflowException e)
{
client.onPacketReadFail();
}
return msg;
}

@Override
public GameClient create(MMOConnection<GameClient> con)
{
return new GameClient(con);
}

@Override
public void execute(Runnable r)
{
ThreadPoolManager.getInstance().execute(r);
}
}
Красным выделил, зачем комментить если это и так в сборке есть
Синим выделил, какая классная реализация пакетки, что закоменчено. P.S там их больше ещё пакетов для реализации надо. Но при этом заявление, реализация согласно официальному контенту.
И вообще данную вещь можно было переписать по нормальному.
 
Продолжаем дальше рассматривать пакетку:
package core.gameserver.network.l2.s2c;

public class FlySelfDestination extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0x43);
// TODO dddd
}
}
И опять не реализованный пакет, мне это уже начинает надоедать.
package core.gameserver.network.l2.s2c;

public class ExTutorialList extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0x6B);
// todo writeB(new byte[128]);
}
}
И опять, не доделано :(
package core.gameserver.network.l2.s2c;

public class ExShowTerritory extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0x89);
// TODO ddd[dd]
}
}
Опять не сделано
package core.gameserver.network.l2.s2c;

public class ExShowPetitionHtml extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0xB1);
// TODO dx[dcS]
}
}
Опять не работает
package core.gameserver.network.l2.s2c;

public class ExShowLines extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0xA5);
// TODO hdcc cx[ddd]
}
}
Чёрт, да сколько то можно.
package core.gameserver.network.l2.s2c;

public class ExSetMpccRouting extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0x37);
// TODO d
}
}
Когда я увижу нормальную реализацию, всё согласно официальному серверу.
package core.gameserver.network.l2.s2c;

public class ExServerPrimitive extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0x11);
// TODO Sdddddd {[c(Sdddd ddd ddd|)] Sddddddd}
}
}
🤦
package core.gameserver.network.l2.s2c;

public class ExRaidReserveResult extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0xB6);
// TODO dx[dddd]
}
}
Боже мой, а реализации то нету.
package core.gameserver.network.l2.s2c;

public class ExPVPMatchRecord extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0x7E);
// TODO ddddd d[Sdd] d[Sdd] (currentState:%d blueTeamTotalKillCnt:%d, redTeamTotalKillCnt:%d)
}
}
:ROAD SO FAR: тут уже пора плакать, один из важных моментов официального сервера, а у нас тут такое творится.
package core.gameserver.network.l2.s2c;

public class ExPartyMemberRenamed extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0xA6);
// TODO ddd
}
}
Чёрт, где пакет реализованный?
package core.gameserver.network.l2.s2c;

public class ExEventMatchUserInfo extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0x02);
// TODO dSdddddddd
}
}
public class ExEventMatchTeamUnlocked extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0x06);
// TODO dc
}
}
package core.gameserver.network.l2.s2c;

import java.util.ArrayList;
import java.util.List;

import core.gameserver.model.Player;
import core.gameserver.model.Summon;


public class ExEventMatchTeamInfo extends L2GameServerPacket
{
@SuppressWarnings("unused")
private int leader_id, loot;
private List<EventMatchTeamInfo> members = new ArrayList<EventMatchTeamInfo>();

public ExEventMatchTeamInfo(List<Player> party, Player exclude)
{
leader_id = party.get(0).getObjectId();
loot = party.get(0).getParty().getLootDistribution();

for(Player member : party)
if(!member.equals(exclude))
members.add(new EventMatchTeamInfo(member));
}

@Override
protected void writeImpl()
{
writeEx(0x1C);
// TODO dcd[dSdddddddddd]
}

public static class EventMatchTeamInfo
{
public String _name, pet_Name;
public int _id, curCp, maxCp, curHp, maxHp, curMp, maxMp, level, class_id, race_id;
public int pet_id, pet_NpcId, pet_curHp, pet_maxHp, pet_curMp, pet_maxMp, pet_level;

public EventMatchTeamInfo(Player member)
{
_name = member.getName();
_id = member.getObjectId();
curCp = (int) member.getCurrentCp();
maxCp = member.getMaxCp();
curHp = (int) member.getCurrentHp();
maxHp = member.getMaxHp();
curMp = (int) member.getCurrentMp();
maxMp = member.getMaxMp();
level = member.getLevel();
class_id = member.getClassId().getId();
race_id = member.getRace().ordinal();

Summon pet = member.getPet();
if(pet != null)
{
pet_id = pet.getObjectId();
pet_NpcId = pet.getNpcId() + 1000000;
pet_Name = pet.getName();
pet_curHp = (int) pet.getCurrentHp();
pet_maxHp = pet.getMaxHp();
pet_curMp = (int) pet.getCurrentMp();
pet_maxMp = pet.getMaxMp();
pet_level = pet.getLevel();
}
else
pet_id = 0;
}
}
}
package core.gameserver.network.l2.s2c;

public class ExEventMatchScore extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0x10);
// TODO ddd
}
}
package core.gameserver.network.l2.s2c;

public class ExEventMatchObserver extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0x0E);
// TODO dccSS
}
}
package core.gameserver.network.l2.s2c;

public class ExEventMatchMessage extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0x0F);
// TODO cS
}
}
package core.gameserver.network.l2.s2c;

public class ExEventMatchManage extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0x30);
// TODO dccScScd[ccdSdd]
}
}
package core.gameserver.network.l2.s2c;

public class ExEventMatchFirecracker extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0x05);
// TODO d
}
}
package core.gameserver.network.l2.s2c;

public class ExEventMatchCreate extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0x1D);
// TODO d
}
}
Вот это да супер реализация, механики официального сервера. Ну у нас же "Всё как на офф".
package core.gameserver.network.l2.s2c;

public class ExEventMatchLockResult extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0x0B);
// TODO пока не реализован даже в клиенте
}
}
package core.gameserver.network.l2.s2c;

public class ExEventMatchList extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0x0D);
// TODO пока не реализован даже в коиенте
}
}
Отмазался то как он, ну вообще то HF 5 есть эти пакеты
 
Продолжаем рассматривать пакеты:
package core.gameserver.network.l2.s2c;

public class ExCleftState extends L2GameServerPacket
{
public static final int CleftState_Total = 0;
public static final int CleftState_TowerDestroy = 1;
public static final int CleftState_CatUpdate = 2;
public static final int CleftState_Result = 3;
public static final int CleftState_PvPKill = 4;

private int CleftState = 0; //TODO

@Override
protected void writeImpl()
{
writeEx(0x95);
writeD(CleftState);
switch(CleftState)
{
case CleftState_Total:
//dddddSS - BTeam Point:%d CatID:%d CatName:%s RemainSec:%d RTeam Point:%d CatID:%d CatName:%s RemainSec:%d
//BlueTeam: d[dddd] - Total List TeamID:%d PlayerID:%d Kill:%d Death:%d Tower:%d
//RedTeam: d[dddd] - Total List TeamID:%d PlayerID:%d Kill:%d Death:%d Tower:%d
break;
case CleftState_TowerDestroy:
//ddddddddd - RemainSec:%d BlueTeamPt:%d RedTeamPt:%d TeamID:%d TowerType:%d PlayerID:%d CleftTowerCount:%d KillCount:%d DeathCount:%d
break;
case CleftState_CatUpdate:
//dddS - RemainSec:%d TeamID:%d CatID:%d CatName:%s
break;
case CleftState_Result:
//dd - WinTeamID:%d LoseTeamID:%d
break;
case CleftState_PvPKill:
//ddd - BTeamPoint:%d RTeamPoint:%d
//ddddd - PvPKill01 TeamID:%d PlayerID:%d CleftTowerCount:%d Kill:%d Death:%d RemainSec:%d
//ddddd - PvPKill02 TeamID:%d PlayerID:%d CleftTowerCount:%d Kill:%d Death:%d
break;
}
}
}
package core.gameserver.network.l2.s2c;

public class ExCleftList extends L2GameServerPacket
{
public static final int CleftType_Close = -1;
public static final int CleftType_Total = 0;
public static final int CleftType_Add = 1;
public static final int CleftType_Remove = 2;
public static final int CleftType_TeamChange = 3;

private int CleftType = 0; //TODO

@Override
protected void writeImpl()
{
writeEx(0x94);
writeD(CleftType);
switch(CleftType)
{
case CleftType_Total:
//dd (MinMemberCount:%d bBalancedMatch:%d)
// BlueTeam: d[dS] (PlayerID:%d PlayerName:%s)
// RedTeam: d[dS] (PlayerID:%d PlayerName:%s)
break;
case CleftType_Add:
//ddS - TeamID:%d PlayerID:%d PlayerName:%s
break;
case CleftType_Remove:
//dd - TeamID:%d PlayerID:%d
break;
case CleftType_TeamChange:
//ddd - PlayerID:%d From:%d To:%d
break;
case CleftType_Close:
break;
}
}
}
Как так то, у нас же всё согласно официальному серверу :(.
 
Вернусь обратно на немного к Магазину(Итем-маллу) и подкину ещё один супер пакет:
package core.gameserver.network.l2.s2c;

public class ExBR_RecentProductListPacket extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeEx(0xDC);
// TODO dx[dhddddcccccdd]
}
}
Так вот покажи мне официальную механику даже такой вещи
 
package core.gameserver.network.l2.s2c;

public class ExBlockUpSetState extends L2GameServerPacket
{
private int BlockUpStateType = 0; //TODO

@Override
protected void writeImpl()
{
writeEx(0x98);
writeD(BlockUpStateType);
switch(BlockUpStateType)
{
case 0:
//dddddd
break;
case 1:
//dd
break;
case 2:
//ddd
break;
}
}
}
package core.gameserver.network.l2.s2c;

public class ExBlockUpSetList extends L2GameServerPacket
{
private int BlockUpType = 0; //TODO

@Override
protected void writeImpl()
{
writeEx(0x97);
writeD(BlockUpType);
switch(BlockUpType)
{
case 0:
//dd
//d[dS]
//d[dS]
break;
case 1:
//dddS
break;
case 2:
//ddd
break;
case 3:
//d
break;
case 4: //nothing
break;
case 5:
//ddd
break;
case -1: //nothing
break;
}
}
}
Вот это да, а как он будет слать таблицы правильные, но всё как на официальном сервере было заявлено, я не вижу.
package core.gameserver.network.l2.s2c;

public class DismissAlliance extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeC(0xAD);
//TODO d
}
}
А где реализация?
package core.gameserver.network.l2.s2c;

public class DeleteRadar extends L2GameServerPacket
{
@Override
protected final void writeImpl()
{
writeC(0xB8);
//TODO ddd
}
}
Опять ничего не реализовано.
package core.gameserver.network.l2.s2c;

public class ClientAction extends L2GameServerPacket
{
@Override
protected void writeImpl()
{
writeC(0x8F);
//TODO d
}
}
Круто. Молодец отлично реализовано, нет слов. Согласно официальному серверу.
package core.gameserver.network.l2.s2c;

import core.gameserver.Config;
import core.gameserver.instancemanager.CursedWeaponsManager;
import core.gameserver.instancemanager.ReflectionManager;
import core.gameserver.model.Creature;
import core.gameserver.model.Player;
import core.gameserver.model.base.TeamType;
import core.gameserver.model.instances.DecoyInstance;
import core.gameserver.model.items.Inventory;
import core.gameserver.model.items.PcInventory;
import core.gameserver.model.matching.MatchingRoom;
import core.gameserver.model.pledge.Alliance;
import core.gameserver.model.pledge.Clan;
import core.gameserver.skills.effects.EffectCubic;
import core.gameserver.utils.Location;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CharInfo extends L2GameServerPacket
{
private static final Logger _log = LoggerFactory.getLogger(CharInfo.class);

private int[][] _inv;
private int _mAtkSpd, _pAtkSpd;
private int _runSpd, _walkSpd, _swimSpd, _flRunSpd, _flWalkSpd, _flyRunSpd, _flyWalkSpd;
private Location _loc, _fishLoc;
private String _name, _title;
private int _objId, _race, _sex, base_class, pvp_flag, karma, rec_have;
private double speed_move, speed_atack, col_radius, col_height;
private int hair_style, hair_color, face, _abnormalEffect, _abnormalEffect2;
private int clan_id, clan_crest_id, large_clan_crest_id, ally_id, ally_crest_id, class_id;
private int _sit, _run, _combat, _dead, private_store, _enchant;
private int _noble, _hero, _fishing, mount_type;
private int plg_class, pledge_type, clan_rep_score, cw_level, mount_id;
private int _nameColor, _title_color, _transform, _agathion, _clanBoatObjectId;
private EffectCubic[] cubics;
private boolean _isPartyRoomLeader, _isFlying;
private TeamType _team;

public CharInfo(Player cha)
{
this((Creature) cha);
}

public CharInfo(DecoyInstance cha)
{
this((Creature) cha);
}

public CharInfo(Creature cha)
{
if(cha == null)
{
System.out.println("CharInfo: cha is null!");
Thread.dumpStack();
return;
}

if(cha.isInvisible())
return;

if(cha.isDeleted())
return;

Player player = cha.getPlayer();
if(player == null)
return;

if(player.isInBoat())
{
_loc = player.getInBoatPosition();
if(player.isClanAirShipDriver())
{
_clanBoatObjectId = player.getBoat().getObjectId();
}
}

if (_loc == null)
_loc = cha.getLoc();

_objId = cha.getObjectId();

// Проклятое оружие и трансформации для ТВ скрывают имя и все остальные опознавательные знаки
if(player.getTransformationName() != null || (player.getReflection() == ReflectionManager.GIRAN_HARBOR || player.getReflection() == ReflectionManager.PARNASSUS) && player.getPrivateStoreType() != Player.STORE_PRIVATE_NONE)
{
_name = player.getTransformationName() != null ? player.getTransformationName() : player.getName();
_title = "";
clan_id = 0;
clan_crest_id = 0;
ally_id = 0;
ally_crest_id = 0;
large_clan_crest_id = 0;
if(player.isCursedWeaponEquipped())
cw_level = CursedWeaponsManager.getInstance().getLevel(player.getCursedWeaponEquippedId());
}
else
{
_name = player.getName();
if(player.getPrivateStoreType() != Player.STORE_PRIVATE_NONE)
_title = "";
else if(!player.isConnected() && !player.isPhantom())
{
_title = Config.DEFAULT_LANG.equalsIgnoreCase("ru") ? "РАЗЪЕДИНЕН" : "DISCONNECTED";
_title_color = 255;
}
else
{
_title = player.getTitle();
_title_color = player.getTitleColor();
}

Clan clan = player.getClan();
Alliance alliance = clan == null ? null : clan.getAlliance();
//
clan_id = clan == null ? 0 : clan.getClanId();
clan_crest_id = clan == null ? 0 : clan.getCrestId();
large_clan_crest_id = clan == null ? 0 : clan.getCrestLargeId();
//
ally_id = alliance == null ? 0 : alliance.getAllyId();
ally_crest_id = alliance == null ? 0 : alliance.getAllyCrestId();

cw_level = 0;
}

if(player.isMounted())
{
_enchant = 0;
mount_id = player.getMountNpcId() + 1000000;
mount_type = player.getMountType();
}
else
{
_enchant = player.getEnchantEffect();
mount_id = 0;
mount_type = 0;
}

_inv = new int[PcInventory.PAPERDOLL_MAX][2];
for(int PAPERDOLL_ID : PAPERDOLL_ORDER)
{
_inv[PAPERDOLL_ID][0] = player.getInventory().getPaperdollItemId(PAPERDOLL_ID);
_inv[PAPERDOLL_ID][1] = player.getInventory().getPaperdollAugmentationId(PAPERDOLL_ID);
}

_mAtkSpd = player.getMAtkSpd();
_pAtkSpd = player.getPAtkSpd();
speed_move = player.getMovementSpeedMultiplier();
_runSpd = (int) (player.getRunSpeed() / speed_move);
_walkSpd = (int) (player.getWalkSpeed() / speed_move);

_flRunSpd = 0; // TODO
_flWalkSpd = 0; // TODO

if(player.isFlying())
{
_flyRunSpd = _runSpd;
_flyWalkSpd = _walkSpd;
}
else
{
_flyRunSpd = 0;
_flyWalkSpd = 0;
}

_swimSpd = player.getSwimSpeed();
_race = player.getBaseTemplate().race.ordinal();
_sex = player.getSex();
base_class = player.getBaseClassId();
pvp_flag = Config.RVRMODE_ENABLE ? 0 : player.getPvpFlag();
karma = player.getKarma();

speed_atack = player.getAttackSpeedMultiplier();
col_radius = player.getColRadius();
col_height = player.getColHeight();
hair_style = player.getHairStyle();
hair_color = player.getHairColor();
face = player.getFace();
if(clan_id > 0 && player.getClan() != null)
clan_rep_score = player.getClan().getReputationScore();
else
clan_rep_score = 0;
_sit = player.isSitting() ? 0 : 1; // standing = 1 sitting = 0
_run = player.isRunning() ? 1 : 0; // running = 1 walking = 0
_combat = player.isInCombat() ? 1 : 0;
_dead = player.isAlikeDead() ? 1 : 0;
private_store = player.isInObserverMode() ? Player.STORE_OBSERVING_GAMES : player.getPrivateStoreType();
cubics = player.getCubics().toArray(new EffectCubic[player.getCubics().size()]);
_abnormalEffect = player.getAbnormalEffect();
_abnormalEffect2 = player.getAbnormalEffect2();
rec_have = player.isGM() ? 0 : player.getRecomHave();
class_id = player.getClassId().getId();
_team = player.getTeam();

_noble = player.isNoble() ? 1 : 0; // 0x01: symbol on char menu ctrl+I
_hero = player.isHero() || player.isFakeHero() || player.isGM() && Config.GM_HERO_AURA ? 1 : 0; // 0x01: Hero Aura
_fishing = player.isFishing() ? 1 : 0;
_fishLoc = player.getFishLoc();
_nameColor = player.getNameColor(); // New C5
plg_class = player.getPledgeClass();
pledge_type = player.getPledgeType();
_transform = player.getTransformation();
_agathion = player.getAgathionId();
_isPartyRoomLeader = player.getMatchingRoom() != null && player.getMatchingRoom().getType() == MatchingRoom.PARTY_MATCHING && player.getMatchingRoom().getLeader() == player;
_isFlying = player.isInFlyingTransform();
}

@Override
protected final void writeImpl()
{
Player activeChar = getClient().getActiveChar();
if(activeChar == null)
return;

if(_objId == 0){ return; }

if(activeChar.getObjectId() == _objId)
{
_log.error("You cant send CharInfo about his character to active user!!!");
return;
}

writeC(0x31);
writeD(_loc.x);
writeD(_loc.y);
writeD(_loc.z + Config.CLIENT_Z_SHIFT);
writeD(_clanBoatObjectId);
writeD(_objId);
writeS(_name);
writeD(_race);
writeD(_sex);
writeD(base_class);

for(int PAPERDOLL_ID : PAPERDOLL_ORDER)
writeD(_inv[PAPERDOLL_ID][0]);

for(int PAPERDOLL_ID : PAPERDOLL_ORDER)
writeD(_inv[PAPERDOLL_ID][1]);

writeD(0x01); //TODO talisman count(VISTALL)
writeD(0x00); //TODO cloak status(VISTALL)

writeD(pvp_flag);
writeD(karma);

writeD(_mAtkSpd);
writeD(_pAtkSpd);

writeD(0x00);

writeD(_runSpd);
writeD(_walkSpd);
writeD(_swimSpd);
writeD(_swimSpd);
writeD(_flRunSpd);
writeD(_flWalkSpd);
writeD(_flyRunSpd);
writeD(_flyWalkSpd);

writeF(speed_move); // _cha.getProperMultiplier()
writeF(speed_atack); // _cha.getAttackSpeedMultiplier()
writeF(col_radius);
writeF(col_height);
writeD(hair_style);
writeD(hair_color);
writeD(face);
writeS(_title);
writeD(clan_id);
writeD(clan_crest_id);
writeD(ally_id);
writeD(ally_crest_id);

writeC(_sit);
writeC(_run);
writeC(_combat);
writeC(_dead);
writeC(0x00); // is invisible
writeC(mount_type); // 1-on Strider, 2-on Wyvern, 3-on Great Wolf, 0-no mount
writeC(private_store);
writeH(cubics.length);
for(EffectCubic cubic : cubics)
writeH(cubic == null ? 0 : cubic.getId());
writeC(_isPartyRoomLeader ? 0x01 : 0x00); // find party members
writeD(_abnormalEffect);
writeC(_isFlying ? 0x02 : 0x00);
writeH(rec_have);
writeD(mount_id);
writeD(class_id);
writeD(0x00);
writeC(_enchant);

writeC(_team.ordinal()); // team circle around feet 1 = Blue, 2 = red

writeD(large_clan_crest_id);
writeC(_noble);
writeC(_hero);

writeC(_fishing);
writeD(_fishLoc.x);
writeD(_fishLoc.y);
writeD(_fishLoc.z);

writeD(_nameColor);
writeD(_loc.h);
writeD(plg_class);
writeD(pledge_type);
writeD(_title_color);
writeD(cw_level);
writeD(clan_rep_score);
writeD(_transform);
writeD(_agathion);

writeD(0x01); // T2

writeD(_abnormalEffect2);
}

public static final int[] PAPERDOLL_ORDER =
{
Inventory.PAPERDOLL_UNDER,
Inventory.PAPERDOLL_HEAD,
Inventory.PAPERDOLL_RHAND,
Inventory.PAPERDOLL_LHAND,
Inventory.PAPERDOLL_GLOVES,
Inventory.PAPERDOLL_CHEST,
Inventory.PAPERDOLL_LEGS,
Inventory.PAPERDOLL_FEET,
Inventory.PAPERDOLL_BACK,
Inventory.PAPERDOLL_LRHAND,
Inventory.PAPERDOLL_HAIR,
Inventory.PAPERDOLL_DHAIR,
Inventory.PAPERDOLL_RBRACELET,
Inventory.PAPERDOLL_LBRACELET,
Inventory.PAPERDOLL_DECO1,
Inventory.PAPERDOLL_DECO2,
Inventory.PAPERDOLL_DECO3,
Inventory.PAPERDOLL_DECO4,
Inventory.PAPERDOLL_DECO5,
Inventory.PAPERDOLL_DECO6,
Inventory.PAPERDOLL_BELT
};
}
Опять нули в пакетке, да как же так. А когда я увижу реализацию согласно официальному серверу?
package core.gameserver.network.l2.s2c;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import core.commons.dbutils.DbUtils;
import core.gameserver.Config;
import core.gameserver.dao.CharacterDAO;
import core.gameserver.data.xml.holder.CharTemplateHolder;
import core.gameserver.database.DatabaseFactory;
import core.gameserver.model.CharSelectInfoPackage;
import core.gameserver.model.base.Experience;
import core.gameserver.model.items.Inventory;
import core.gameserver.templates.PlayerTemplate;
import core.gameserver.utils.AutoBan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CharacterSelectionInfo extends L2GameServerPacket
{
// d (SdSddddddddddffdQdddddddddddddddddddddddddddddddddddddddffdddchhd)
private static final Logger _log = LoggerFactory.getLogger(CharacterSelectionInfo.class);

private String _loginName;

private int _sessionId;

private CharSelectInfoPackage[] _characterPackages;

public CharacterSelectionInfo(String loginName, int sessionId)
{
_sessionId = sessionId;
_loginName = loginName;
_characterPackages = loadCharacterSelectInfo(loginName);
}

public CharSelectInfoPackage[] getCharInfo()
{
return _characterPackages;
}

@Override
protected final void writeImpl()
{
int size = _characterPackages != null ? _characterPackages.length : 0;

writeC(0x09);
writeD(size);
writeD(0x07); //Kamael, 0x07 ?
writeC(0); //разрешает или запрещает создание игроков

long lastAccess = -1L;
int lastUsed = -1;
for(int i = 0; i < size; i++)
if(lastAccess < _characterPackages.getLastAccess())
{
lastAccess = _characterPackages.getLastAccess();
lastUsed = i;
}

for(int i = 0; i < size; i++)
{
CharSelectInfoPackage charInfoPackage = _characterPackages;

writeS(charInfoPackage.getName());
writeD(charInfoPackage.getCharId()); // ?
writeS(_loginName);
writeD(_sessionId);
writeD(charInfoPackage.getClanId());
writeD(0x00); // ??

writeD(charInfoPackage.getSex());
writeD(charInfoPackage.getRace());
writeD(charInfoPackage.getBaseClassId());

writeD(0x01); // active ??

writeD(charInfoPackage.getX());
writeD(charInfoPackage.getY());
writeD(charInfoPackage.getZ());

writeF(charInfoPackage.getCurrentHp());
writeF(charInfoPackage.getCurrentMp());

writeD(charInfoPackage.getSp());
writeQ(charInfoPackage.getExp());
int lvl = charInfoPackage.getLevel();
writeF(Experience.getExpPercent(lvl, charInfoPackage.getExp()));
writeD(lvl);

writeD(charInfoPackage.getKarma());
writeD(charInfoPackage.getPk());
writeD(charInfoPackage.getPvP());

writeD(0x00);
writeD(0x00);
writeD(0x00);
writeD(0x00);
writeD(0x00);
writeD(0x00);
writeD(0x00);

for(int PAPERDOLL_ID : Inventory.PAPERDOLL_ORDER)
writeD(charInfoPackage.getPaperdollItemId(PAPERDOLL_ID));

writeD(charInfoPackage.getHairStyle());
writeD(charInfoPackage.getHairColor());
writeD(charInfoPackage.getFace());

writeF(charInfoPackage.getMaxHp()); // hp max
writeF(charInfoPackage.getMaxMp()); // mp max

writeD(charInfoPackage.getAccessLevel() > -100 ? charInfoPackage.getDeleteTimer() : -1);
writeD(charInfoPackage.getClassId());
writeD(i == lastUsed ? 1 : 0);

writeC(Math.min(charInfoPackage.getPaperdollEnchantEffect(Inventory.PAPERDOLL_RHAND), 127));
writeD(charInfoPackage.getPaperdollAugmentationId(Inventory.PAPERDOLL_RHAND));
int weaponId = charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_RHAND);
if(weaponId == 8190) // Transform id (на оффе отображаются только КВ трансформации или вообще не отображаются ;)
writeD(301);
else if(weaponId == 8689)
writeD(302);
else
writeD(0x00);

//TODO: Pet info?
writeD(0x00);
writeD(0x00);
writeD(0x00);
writeD(0x00);
writeF(0x00);
writeF(0x00);

writeD(charInfoPackage.getVitalityPoints());
}
}

public static CharSelectInfoPackage[] loadCharacterSelectInfo(String loginName)
{
CharSelectInfoPackage charInfopackage;
List<CharSelectInfoPackage> characterList = new ArrayList<CharSelectInfoPackage>();

Connection con = null;
PreparedStatement statement = null;
ResultSet rset = null;
try
{
con = DatabaseFactory.getInstance().getConnection();
statement = con.prepareStatement("SELECT * FROM characters AS c LEFT JOIN character_subclasses AS cs ON (c.obj_Id=cs.char_obj_id AND cs.active=1) WHERE account_name=? LIMIT 7");
statement.setString(1, loginName);
rset = statement.executeQuery();
while(rset.next()) // fills the package
{
charInfopackage = restoreChar(rset);
if(charInfopackage != null)
characterList.add(charInfopackage);
}
}
catch(Exception e)
{
_log.error("could not restore charinfo:", e);
}
finally
{
DbUtils.closeQuietly(con, statement, rset);
}

return characterList.toArray(new CharSelectInfoPackage[characterList.size()]);
}

private static int restoreBaseClassId(int objId)
{
int classId = 0;

Connection con = null;
PreparedStatement statement = null;
ResultSet rset = null;
try
{
con = DatabaseFactory.getInstance().getConnection();
statement = con.prepareStatement("SELECT class_id FROM character_subclasses WHERE char_obj_id=? AND isBase=1");
statement.setInt(1, objId);
rset = statement.executeQuery();
while(rset.next())
classId = rset.getInt("class_id");
}
catch(Exception e)
{
_log.error("could not restore base class id:", e);
}
finally
{
DbUtils.closeQuietly(con, statement, rset);
}

return classId;
}

private static CharSelectInfoPackage restoreChar(ResultSet chardata)
{
CharSelectInfoPackage charInfopackage = null;
try
{
int objectId = chardata.getInt("obj_Id");
int classid = chardata.getInt("class_id");
int baseClassId = classid;
boolean useBaseClass = chardata.getInt("isBase") > 0;
if(!useBaseClass)
baseClassId = restoreBaseClassId(objectId);
boolean female = chardata.getInt("sex") == 1;
PlayerTemplate templ = CharTemplateHolder.getInstance().getTemplate(baseClassId, female);
if(templ == null)
{
_log.error("restoreChar fail | templ == null | objectId: " + objectId + " | classid: " + baseClassId + " | female: " + female);
return null;
}
String name = chardata.getString("char_name");
charInfopackage = new CharSelectInfoPackage(objectId, name);
charInfopackage.setLevel(chardata.getInt("level"));
charInfopackage.setMaxHp(chardata.getInt("maxHp"));
charInfopackage.setCurrentHp(chardata.getDouble("curHp"));
charInfopackage.setMaxMp(chardata.getInt("maxMp"));
charInfopackage.setCurrentMp(chardata.getDouble("curMp"));

charInfopackage.setX(chardata.getInt("x"));
charInfopackage.setY(chardata.getInt("y"));
charInfopackage.setZ(chardata.getInt("z"));
charInfopackage.setPk(chardata.getInt("pkkills"));
charInfopackage.setPvP(chardata.getInt("pvpkills"));

charInfopackage.setFace(chardata.getInt("face"));
charInfopackage.setHairStyle(chardata.getInt("hairstyle"));
charInfopackage.setHairColor(chardata.getInt("haircolor"));
charInfopackage.setSex(female ? 1 : 0);

charInfopackage.setExp(chardata.getLong("exp"));
charInfopackage.setSp(chardata.getInt("sp"));
charInfopackage.setClanId(chardata.getInt("clanid"));

charInfopackage.setKarma(chardata.getInt("karma"));
charInfopackage.setRace(templ.race.ordinal());
charInfopackage.setClassId(classid);
charInfopackage.setBaseClassId(baseClassId);
long deletetime = chardata.getLong("deletetime");
int deletedays = 0;
if(Config.DELETE_DAYS > 0)
if(deletetime > 0)
{
deletetime = (int) (System.currentTimeMillis() / 1000 - deletetime);
deletedays = (int) (deletetime / 3600 / 24);
if(deletedays >= Config.DELETE_DAYS)
{
CharacterDAO.getInstance().deleteCharByObjId(objectId);
return null;
}
deletetime = Config.DELETE_DAYS * 3600 * 24 - deletetime;
}
else
deletetime = 0;
charInfopackage.setDeleteTimer((int) deletetime);
charInfopackage.setLastAccess(chardata.getLong("lastAccess") * 1000L);
charInfopackage.setAccessLevel(chardata.getInt("accesslevel"));
int points = chardata.getInt("vitality") + (int) ((System.currentTimeMillis() - charInfopackage.getLastAccess()) / 15.);
if(points > 20000)
points = 20000;
else if(points < 0)
points = 0;
charInfopackage.setVitalityPoints(points);

if(charInfopackage.getAccessLevel() < 0 && !AutoBan.isBanned(objectId))
charInfopackage.setAccessLevel(0);
}
catch(Exception e)
{
_log.error("", e);
}

return charInfopackage;
}
}

И опять нули в пакетке.
Думаю пора заканчивать с пакеткой и пошли дальше
 
package core.gameserver.utils;

import gnu.trove.map.hash.TIntIntHashMap;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

import core.gameserver.model.quest.Quest;
import core.gameserver.utils.Util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AddonsConfig
{
private static final Logger log = LoggerFactory.getLogger(AddonsConfig.class);
private static final String dir = "./config/Addons";
private static ConcurrentHashMap<String, String> properties = new ConcurrentHashMap<String, String>();
private static ConcurrentHashMap<Integer, Double> questRewardRates = new ConcurrentHashMap<Integer, Double>();
private static ConcurrentHashMap<Integer, Double> questDropRates = new ConcurrentHashMap<Integer, Double>();

public static void load()
{
File files = new File(dir);
if (!files.exists())
log.warn("WARNING! " + dir + " not exists! Config not loaded!");
else
parseFiles(files.listFiles());
}

public static void reload()
{
synchronized(properties)
{
synchronized(questRewardRates)
{
synchronized(questDropRates)
{
properties = new ConcurrentHashMap<String, String>();
questRewardRates = new ConcurrentHashMap<Integer, Double>();
questDropRates = new ConcurrentHashMap<Integer, Double>();
load();
}
}
}
}

private static void parseFiles(File[] files)
{
for (File f : files)
{
if (f.isHidden())
continue;
if (f.isDirectory() && !f.getName().contains("defaults"))
parseFiles(f.listFiles());
if (f.getName().startsWith("quest_reward_rates"))
{
try
{
InputStream is = new FileInputStream(f);
Properties p = new Properties();
p.load(is);
loadQuestRewardRates(p);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
else if (f.getName().startsWith("quest_drop_rates"))
{
try
{
InputStream is = new FileInputStream(f);
Properties p = new Properties();
p.load(is);
loadQuestDropRates(p);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
else if (f.getName().endsWith(".ini"))
{
try
{
InputStream is = new FileInputStream(f);
Properties p = new Properties();
p.load(is);
loadProperties(p);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}

private static void loadQuestRewardRates(Properties p)
{
for (String name : p.stringPropertyNames())
{
int id;
try
{
id = Integer.parseInt(name);
}
catch (NumberFormatException nfe)
{
continue;
}
if(questRewardRates.get(id) != null)
{
questRewardRates.replace(id, Double.parseDouble(p.getProperty(name).trim()));
log.info("Duplicate quest id \"" + name + "\"");
}
else if (p.getProperty(name) == null)
log.info("Null property for quest id " + name);
else
questRewardRates.put(id, Double.parseDouble(p.getProperty(name).trim()));
}
p.clear();
}

private static void loadQuestDropRates(Properties p)
{
for (String name : p.stringPropertyNames())
{
int id;
try
{
id = Integer.parseInt(name);
} catch (NumberFormatException nfe)
{
continue;
}
if (questDropRates.get(id) != null)
{
questDropRates.replace(id, Double.parseDouble(p.getProperty(name).trim()));
log.info("Duplicate quest id \"" + name + "\"");
}
else if (p.getProperty(name) == null)
log.info("Null property for quest id " + name);
else
questDropRates.put(id, Double.parseDouble(p.getProperty(name).trim()));
}
p.clear();
}


private static void loadProperties(Properties p)
{
for (String name : p.stringPropertyNames())
{
if (properties.get(name) != null)
{
properties.replace(name, p.getProperty(name).trim());
log.info("Duplicate properties name \"" + name + "\" replaced with new value.");
}
else if (p.getProperty(name) == null)
log.info("Null property for key " + name);
else
properties.put(name, p.getProperty(name).trim());
}
p.clear();
}

public static double getQuestRewardRates(Quest q)
{
return questRewardRates.containsKey(q.getQuestIntId()) ? questRewardRates.get(q.getQuestIntId()) : 1.0;
}

public static double getQuestDropRates(Quest q)
{
return questDropRates.containsKey(q.getQuestIntId()) ? questDropRates.get(q.getQuestIntId()) : 1.0;
}

public static String get(String name)
{
if(properties.get(name) == null)
log.warn("ConfigSystem: Null value for key: " + name);
return properties.get(name);
}

public static float getFloat(String name)
{
return getFloat(name, Float.MAX_VALUE);
}

public static boolean getBoolean(String name)
{
return getBoolean(name, false);
}

public static int getInt(String name)
{
return getInt(name, Integer.MAX_VALUE);
}

public static int[] getIntArray(String name)
{
return getIntArray(name, new int[0]);
}

public static int getIntHex(String name)
{
return getIntHex(name, Integer.decode("0xFFFFFF"));
}

public static byte getByte(String name)
{
return getByte(name, Byte.MAX_VALUE);
}

public static long getLong(String name)
{
return getLong(name, Long.MAX_VALUE);
}

public static double getDouble(String name)
{
return getDouble(name, Double.MAX_VALUE);
}

public static String get(String name, String def)
{
return get(name) == null ? def : get(name);
}

public static float getFloat(String name, float def)
{
return Float.parseFloat(get(name, String.valueOf(def)));
}

public static boolean getBoolean(String name, boolean def)
{
return Boolean.parseBoolean(get(name, String.valueOf(def)));
}

public static int getInt(String name, int def)
{
return Integer.parseInt(get(name, String.valueOf(def)));
}

public static int[] getIntArray(String name, int[] def)
{
return get(name, null) == null ? def : Util.parseCommaSeparatedIntegerArray(get(name, null));
}

public static int getIntHex(String name, int def)
{
if(!get(name, String.valueOf(def)).trim().startsWith("0x"))
return Integer.decode("0x"+get(name, String.valueOf(def)));
else
return Integer.decode(get(name, String.valueOf(def)));
}

public static byte getByte(String name, byte def)
{
return Byte.parseByte(get(name, String.valueOf(def)));
}

public static double getDouble(String name, double def)
{
return Double.parseDouble(get(name, String.valueOf(def)));
}

public static long getLong(String name, long def)
{
return Long.parseLong(get(name, String.valueOf(def)));
}

public static void set(String name, String param)
{
properties.replace(name, param);
}

public static void set(String name, Object obj)
{
set(name, String.valueOf(obj));
}

public static TIntIntHashMap SKILL_DURATION_LIST;
public static TIntIntHashMap SKILL_REUSE_LIST;

public static void loadSkillDurationList()
{
if(getBoolean("EnableModifySkillDuration"))
{
String[] propertySplit = get("SkillDurationList").split(";");
SKILL_DURATION_LIST = new TIntIntHashMap(propertySplit.length);
for (String skill : propertySplit)
{
String[] skillSplit = skill.split(",");
if(skillSplit.length != 2)
log.warn(concat("[SkillDurationList]: invalid config property -> SkillDurationList \"", skill, "\""));
else
{
try
{
SKILL_DURATION_LIST.put(Integer.parseInt(skillSplit[0]), Integer.parseInt(skillSplit[1]));
}
catch (NumberFormatException nfe)
{
if (!skill.isEmpty())
{
log.warn(concat("[SkillDurationList]: invalid config property -> SkillList \"", skillSplit[0], "\"", skillSplit[1]));
}
}
}
}
}
}

public static void loadSkillReuseList()
{
if(getBoolean("EnableModifySkillReuse"))
{
String[] propertySplit = get("SkillReuseList").split(";");
SKILL_REUSE_LIST = new TIntIntHashMap(propertySplit.length);
for (String skill : propertySplit)
{
String[] skillSplit = skill.split(",");
if (skillSplit.length != 2)
log.warn(concat("[SkillReuseList]: invalid config property -> SkillReuseList \"", skill, "\""));
else
{
try
{
SKILL_REUSE_LIST.put(Integer.valueOf(skillSplit[0]), Integer.valueOf(skillSplit[1]));
}
catch (NumberFormatException nfe)
{
if (!skill.isEmpty())
log.warn(concat("[SkillReuseList]: invalid config property -> SkillList \"", skillSplit[0], "\"", skillSplit[1]));
}
}
}
}
}

public static String concat(final String... strings)
{
final StringBuilder sbString = new StringBuilder(getLength(strings));
for (final String string : strings)
{
sbString.append(string);
}
return sbString.toString();
}

private static int getLength(final String[] strings)
{
int length = 0;
for (final String string : strings)
{
length += string.length();
}
return length;
}
}
Госпади, а зачем он ещё впиливал ScriptConfig. Одно другого хуже не разобрался как наверное реализовать по нормальному решил впилить шлак. Гавнокод в работе.
package core.gameserver.utils;

import core.gameserver.Config;
import core.gameserver.model.items.ItemInstance;
import core.gameserver.model.Player;
import core.gameserver.network.l2.s2c.InventoryUpdate;

public class FixEnchantOlympiad
{
public static void storeEnchantItemsOly(Player player)
{
ItemInstance[] arr = player.getInventory().getItems();
int len = arr.length;
StringBuilder items = new StringBuilder();

for (int i = 0; i < len; i+:)
{
ItemInstance _item = arr;

if(isMaxEnchant(_item))
{
items.append(_item.getObjectId()).append(";").append(_item.getEnchantLevel()).append(":");

if(_item.isWeapon())
_item.setEnchantLevel(Config.OLY_ENCHANT_LIMIT_WEAPON);
if(_item.isArmor())
_item.setEnchantLevel(Config.OLY_ENCHANT_LIMIT_ARMOR);
if(_item.isAccessory())
_item.setEnchantLevel(Config.OLY_ENCHANT_LIMIT_JEWEL);

player.sendPacket(new InventoryUpdate().addModifiedItem(_item));
player.broadcastUserInfo(true);
player.broadcastCharInfo();
player.setVar("EnItemOlyRec", items.toString(), -1);
}
}
}

private static boolean isMaxEnchant(ItemInstance item)
{
if((item.isWeapon() && item.getEnchantLevel() > Config.OLY_ENCHANT_LIMIT_WEAPON)
|| (item.isArmor() && item.getEnchantLevel() > Config.OLY_ENCHANT_LIMIT_ARMOR)
|| (item.isAccessory() && item.getEnchantLevel() > Config.OLY_ENCHANT_LIMIT_JEWEL))
return true;
return false;
}

public static void restoreEnchantItemsOly(Player player)
{
if(player.getVar("EnItemOlyRec") == null)
return;

String var;
var = player.getVar("EnItemOlyRec");
if(var != null)
{
String[] items = var.split(":");
for(String item : items)
{
if(item.equals(""))
continue;
String[] values = item.split(";");
if(values.length < 2)
continue;

int oId = Integer.parseInt(values[0]);
int enchant = Integer.parseInt(values[1]);

ItemInstance itemToEnchant = player.getInventory().getItemByObjectId(oId);
if(itemToEnchant == null)
continue;

itemToEnchant.setEnchantLevel(enchant);
player.sendPacket(new InventoryUpdate().addModifiedItem(itemToEnchant));
player.broadcastUserInfo(true);
player.broadcastCharInfo();
}
}

player.unsetVar("EnItemOlyRec");
}
}[/I]
Госпади упаси, в ItemInstance есть метод getEnchantLevel где можно нормально реализовать, да даже можно не трогая данный метод. Гавнокод в работе
package core.gameserver.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import core.gameserver.Config;
import core.gameserver.model.Player;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Files
{
private static final Logger _log = LoggerFactory.getLogger(Files.class);

/**
* Сохраняет строку в файл в кодировке UTF-8.<br>
* Если такой файл существует, то перезаписывает его.
* @param path путь к файлу
* @param string сохраняемая строка
*/
public static void writeFile(String path, String string)
{
try
{
FileUtils.writeStringToFile(new File(path), string, "UTF-8");
}
catch(IOException e)
{
_log.error("Error while saving file : " + path, e);
}
}

public static boolean copyFile(String srcFile, String destFile)
{
try
{
FileUtils.copyFile(new File(srcFile), new File(destFile), false);
return true;
}
catch(IOException e)
{
_log.error("Error while copying file : " + srcFile + " to " + destFile, e);
}

return false;
}

public static String read(String name)
{
if(name == null)
return null;

File file = new File("./" + name);

if(!file.exists())
return null;

String content = null;

BufferedReader br = null;
try
{
br = new BufferedReader(new UnicodeReader(new FileInputStream(file), "UTF-8"));
StringBuffer sb = new StringBuffer();
String s = "";
while((s = br.readLine()) != null)
sb.append(s).append("\n");
content = sb.toString();
sb = null;
}
catch(Exception e)
{}
finally
{
try
{
if(br != null)
br.close();
}
catch(Exception e1)
{}
}

return content;
}

/**
* Сохраняет строку в файл в кодировке UTF-8.<br>
* Если такой файл существует, то перезаписывает его.
*
* @param path путь к файлу
* @param string сохраняемая строка
*/
public static void writeFile1(String path, String string) {
if (string == null || string.length() == 0)
return;

File target = new File(path);

if (!target.exists())
try {
target.createNewFile();
} catch (IOException e) {
e.printStackTrace(System.err);
}

try {
FileOutputStream fos = new FileOutputStream(target);
fos.write(string.getBytes("UTF-8"));
fos.close();
} catch (IOException e) {
e.printStackTrace(System.err);
}
}

public static String read(String name, Player player) {
if (player == null)
return "";
return read(name, player.getLang());
}

public static String read(String name, String lang) {
String tmp = langFileName(name, lang);

long last_modif = lastModified(tmp); // время модификации локализованного файла
if (last_modif > 0) // если он существует
{
if (last_modif >= lastModified(name)) // и новее оригинального файла
return Strings.bbParse(read(tmp)); // то вернуть локализованный

_log.warn("Last modify of " + name + " more then " + tmp); // если он существует но устарел - выругаться в лог
}

return Strings.bbParse(read(name)); // если локализованный файл отсутствует вернуть оригинальный
}

public static String langFileName(String name, String lang) {
if (lang == null || lang.equalsIgnoreCase("en"))
lang = "";

String tmp;

tmp = name.replaceAll("(.:)(\\.htm)", "$1-" + lang + "$2");
if (!tmp.equals(name) && lastModified(tmp) > 0)
return tmp;

tmp = name.replaceAll("(.:)(/[^/].+\\.htm)", "$1/" + lang + "$2");
if (!tmp.equals(name) && lastModified(tmp) > 0)
return tmp;

tmp = name.replaceAll("(.+?/html)/", "$1-" + lang + "/");
if (!tmp.equals(name) && lastModified(tmp) > 0)
return tmp;

if (lastModified(name) > 0)
return name;

return null;
}

public static long lastModified(String name) {
if (name == null)
return 0;

return new File(name).lastModified();
}
}
Госпади упаси от этого бреда. GameStats.java аналогично
А вот дальше пойдёт полная жопа.
package core.gameserver.utils;

import java.util.Arrays;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;

import core.commons.util.Rnd;

/**
* Полный аналог ArrayList, но намного быстрее удаляет. <br />
* Вместо сдвига всего массива перемещает последний элемент списка на место удаленного. <br />
* Побочный эффект - размер массива при удалении элемента не меняется, но можно использовать clear. <br /> <br />
*
* Базовая версия.
*
* @see core.Util.GCArray - конкуррентнобезопасная версия
* @see core.Util.GSArray - синхронизированная версия
* @see core.Util.GCSArray - конкуррентнобезопасная синхронизированная версия
*/
public class GArray<E> implements Collection<E>
{
protected transient E[] elementData;
protected transient int modCount = 0;
protected int size;

@SuppressWarnings("unchecked")
public GArray(int initialCapacity)
{
if(initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
elementData = (E[]) new Object[initialCapacity];
}

public GArray()
{
this(10);
}

public int getCapacity()
{
return elementData.length;
}

public int getRandom()
{
return Rnd.get(elementData.length);
}


public void ensureCapacity(int minCapacity)
{
modCount++;
int oldCapacity = elementData.length;
if(minCapacity > oldCapacity)
{
int newCapacity = oldCapacity * 3 / 2 + 1;
if(newCapacity < minCapacity)
newCapacity = minCapacity;
elementData = Arrays.copyOf(elementData, newCapacity);
}
}

public int size()
{
return size;
}

public boolean isEmpty()
{
return size == 0;
}

public E[] toNativeArray()
{
return Arrays.copyOf(elementData, size);
}

public Object[] toArray()
{
return Arrays.copyOf(elementData, size);
}

@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a)
{
if(a.length < size)
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if(a.length > size)
a[size] = null;
return a;
}

public E get(int index)
{
RangeCheck(index);
return elementData[index];
}

@SuppressWarnings("unchecked")
public boolean add(E e)
{
ensureCapacity(size + 1);
elementData[size++] = e;
return true;
}

public E getRandomize()
{
if (isEmpty())
return null;
int index = Rnd.get(size);
RangeCheck(index);
return elementData[index];
}

public boolean remove(Object o)
{
if(o == null)
{
for(int index = 0; index < size; index+:)
if(elementData[index] == null)
{
remove(index);
return true;
}
}
else
for(int index = 0; index < size; index+:)
if(o.equals(elementData[index]))
{
remove(index);
return true;
}
return false;
}

public E remove(int index)
{
modCount++;
RangeCheck(index);
E old = elementData[index];
elementData[index] = elementData[size - 1];
elementData[--size] = null;
return old;
}

public E removeFirst()
{
return size > 0 ? remove(0) : null;
}

public E removeLast()
{
if(size > 0)
{
modCount++;
size--;
E old = elementData[size];
elementData[size] = null;
return old;
}
return null;
}

public E set(int index, E element)
{
RangeCheck(index);
E oldValue = elementData[index];
elementData[index] = element;
return oldValue;
}

public int indexOf(Object o)
{
if(o == null)
{
for(int i = 0; i < size; i+:)
if(elementData == null)
return i;
}
else
for(int i = 0; i < size; i+:)
if(o.equals(elementData))
return i;
return -1;
}

public boolean contains(Object o)
{
if(o == null)
{
for(int i = 0; i < size; i+:)
if(elementData == null)
return true;
}
else
for(int i = 0; i < size; i+:)
if(o.equals(elementData))
return true;
return false;
}

public boolean addAll(Collection<? extends E> c)
{
if(c == null)
return false;
boolean modified = false;
Iterator<? extends E> e = c.iterator();
while(e.hasNext())
if(add(e.next()))
modified = true;
return modified;
}

public boolean removeAll(Collection<?> c)
{
boolean modified = false;
for(int i = 0; i < size; i+:)
if(c.contains(elementData))
{
modCount++;
elementData = elementData[size - 1];
elementData[--size] = null;
modified = true;
}
return modified;
}

public boolean retainAll(Collection<?> c)
{
boolean modified = false;
for(int i = 0; i < size; i+:)
if(!c.contains(elementData))
{
modCount++;
elementData = elementData[size - 1];
elementData[--size] = null;
modified = true;
}
return modified;
}

public boolean containsAll(Collection<?> c)
{
for(int i = 0; i < size; i+:)
if(!contains(elementData))
return false;
return true;
}

private void RangeCheck(int index)
{
if(index >= size)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}

@SuppressWarnings("unchecked")
public void clear()
{
modCount++;
int oldSize = size;
size = 0;
if(oldSize > 1000)
elementData = (E[]) new Object[10];
else
for(int i = 0; i < oldSize; i+:)
elementData = null;
size = 0;
}

/**
* Осторожно, при таком очищении в массиве могут оставаться ссылки на обьекты,
* удерживающие эти обьекты в памяти!
*/
public void clearSize()
{
modCount++;
size = 0;
}

public Iterator<E> iterator()
{
return new Itr();
}

private class Itr implements Iterator<E>
{
int cursor = 0;
int lastRet = -1;
int expectedModCount = modCount;

public boolean hasNext()
{
return cursor < size();
}

public E next()
{
checkForComodification();
try
{
E next = get(cursor);
lastRet = cursor++;
return next;
}
catch(IndexOutOfBoundsException e)
{
checkForComodification();
throw new NoSuchElementException();
}
}

public void remove()
{
if(lastRet == -1)
throw new IllegalStateException();
checkForComodification();

try
{
GArray.this.remove(lastRet);
if(lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
}
catch(IndexOutOfBoundsException e)
{
throw new ConcurrentModificationException();
}
}

final void checkForComodification()
{
if(modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}

@Override
public String toString()
{
StringBuffer bufer = new StringBuffer();
for(int i = 0; i < size; i+:)
{
if(i != 0)
bufer.append(", ");
bufer.append(elementData);
}
return "<" + bufer + ">";
}

@SuppressWarnings("unchecked")
public void sort()
{
Object tmp[] = toArray();
Arrays.sort(tmp);
elementData = (E[]) tmp;
}

public boolean addIfNotContains(E e)
{
if (contains(e))
return false;
return add(e);
}
}[/I]
package core.gameserver.utils;

import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
* Аналог ArrayList, ArrayList, но намного быстрее удаляет. <br />
* Вместо сдвига всего массива перемещает последний элемент списка на место удаленного. <br />
* Побочный эффект - размер массива при удалении элемента не меняется, но можно использовать clear. <br /> <br />
*
* Конкуррентнобезопасная версия, для итерации создается копия списка. <br />
* Метод remove для итератора не работает и возвращает IllegalStateException.
*
* @see core.Util.GArray - базовая версия
* @see core.Util.GSArray - синхронизированная версия
* @see core.Util.GCSArray - конкуррентнобезопасная синхронизированная версия
*/
public class GCArray<E> implements Collection<E>
{
private transient E[] elementData;
private int size;

@SuppressWarnings("unchecked")
public GCArray(int initialCapacity)
{
super();
if(initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
this.elementData = (E[]) new Object[initialCapacity];
}

public GCArray()
{
this(10);
}

public void ensureCapacity(int minCapacity)
{
int oldCapacity = elementData.length;
if(minCapacity > oldCapacity)
{
int newCapacity = oldCapacity * 3 / 2 + 1;
if(newCapacity < minCapacity)
newCapacity = minCapacity;
elementData = Arrays.copyOf(elementData, newCapacity);
}
}

public int size()
{
return size;
}

public boolean isEmpty()
{
return size == 0;
}

public E[] toNativeArray()
{
return Arrays.copyOf(elementData, size);
}

public Object[] toArray()
{
return Arrays.copyOf(elementData, size);
}

@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a)
{
if(a.length < size)
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if(a.length > size)
a[size] = null;
return a;
}

public E get(int index)
{
RangeCheck(index);
return elementData[index];
}

public boolean add(E e)
{
ensureCapacity(size + 1);
elementData[size++] = e;
return true;
}

public boolean remove(Object o)
{
if(o == null)
{
for(int index = 0; index < size; index+:)
if(elementData[index] == null)
{
remove(index);
return true;
}
}
else
for(int index = 0; index < size; index+:)
if(o.equals(elementData[index]))
{
remove(index);
return true;
}
return false;
}

public E remove(int index)
{
RangeCheck(index);
E old = elementData[index];
elementData[index] = elementData[size - 1];
elementData[--size] = null;
return old;
}

public E set(int index, E element)
{
RangeCheck(index);
E oldValue = elementData[index];
elementData[index] = element;
return oldValue;
}

public int indexOf(Object o)
{
if(o == null)
{
for(int i = 0; i < size; i+:)
if(elementData == null)
return i;
}
else
for(int i = 0; i < size; i+:)
if(o.equals(elementData))
return i;
return -1;
}

public boolean contains(Object o)
{
if(o == null)
{
for(int i = 0; i < size; i+:)
if(elementData == null)
return true;
}
else
for(int i = 0; i < size; i+:)
if(o.equals(elementData))
return true;
return false;
}

public boolean addAll(Collection<? extends E> c)
{
boolean modified = false;
Iterator<? extends E> e = c.iterator();
while(e.hasNext())
if(add(e.next()))
modified = true;
return modified;
}

public boolean removeAll(Collection<?> c)
{
boolean modified = false;
for(int i = 0; i < size; i+:)
if(c.contains(elementData))
{
elementData = elementData[size - 1];
elementData[--size] = null;
modified = true;
}
return modified;
}

public boolean retainAll(Collection<?> c)
{
boolean modified = false;
for(int i = 0; i < size; i+:)
if(!c.contains(elementData))
{
elementData = elementData[size - 1];
elementData[--size] = null;
modified = true;
}
return modified;
}

public boolean containsAll(Collection<?> c)
{
for(int i = 0; i < size; i+:)
if(!contains(elementData))
return false;
return true;
}

private void RangeCheck(int index)
{
if(index >= size)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}

@SuppressWarnings("unchecked")
public void clear()
{
int oldSize = size;
size = 0;
if(oldSize > 1000)
elementData = (E[]) new Object[10];
else
for(int i = 0; i < oldSize; i+:)
elementData = null;
size = 0;
}

/**
* Осторожно, при таком очищении в массиве могут оставаться ссылки на обьекты,
* удерживающие эти обьекты в памяти!
*/
public void clearSize()
{
size = 0;
}

public Iterator<E> iterator()
{
return new Itr();
}

private class Itr implements Iterator<E>
{
E[] data = toNativeArray();
int size = data.length;
int cursor = 0;

public boolean hasNext()
{
return cursor != size;
}

public E next()
{
try
{
return data[cursor++];
}
catch(IndexOutOfBoundsException e)
{
throw new NoSuchElementException();
}
}

/**
* НЕ РАБОТАЕТ!
*/
public void remove()
{
throw new IllegalStateException();
}
}
}
package core.gameserver.utils;

import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
* Аналог ArrayList, но намного быстрее удаляет. <br />
* Вместо сдвига всего массива перемещает последний элемент списка на место удаленного. <br />
* Побочный эффект - размер массива при удалении элемента не меняется, но можно использовать clear. <br />
*
* Конкуррентнобезопасная синхронизированная версия, для итерации создается копия списка. <br />
* Метод remove для итератора не работает и возвращает IllegalStateException.
*
* @see core.Util.GArray - базовая версия
* @see core.Util.GCArray - конкуррентнобезопасная версия
* @see core.Util.GSArray - синхронизированная версия
*/
public class GCSArray<E> implements Collection<E>
{
private transient E[] elementData;
private int size;

@SuppressWarnings("unchecked")
public GCSArray(int initialCapacity)
{
super();
if(initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
this.elementData = (E[]) new Object[initialCapacity];
}

public GCSArray()
{
this(10);
}

public synchronized void ensureCapacity(int minCapacity)
{
int oldCapacity = elementData.length;
if(minCapacity > oldCapacity)
{
int newCapacity = oldCapacity * 3 / 2 + 1;
if(newCapacity < minCapacity)
newCapacity = minCapacity;
elementData = Arrays.copyOf(elementData, newCapacity);
}
}

public int size()
{
return size;
}

public boolean isEmpty()
{
return size == 0;
}

public synchronized E[] toNativeArray()
{
return Arrays.copyOf(elementData, size);
}

public synchronized Object[] toArray()
{
return Arrays.copyOf(elementData, size);
}

@SuppressWarnings("unchecked")
public synchronized <T> T[] toArray(T[] a)
{
if(a.length < size)
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if(a.length > size)
a[size] = null;
return a;
}

public synchronized E get(int index)
{
RangeCheck(index);
return elementData[index];
}

public synchronized boolean add(E e)
{
ensureCapacity(size + 1);
elementData[size++] = e;
return true;
}

public synchronized boolean remove(Object o)
{
if(o == null)
{
for(int index = 0; index < size; index+:)
if(elementData[index] == null)
{
remove(index);
return true;
}
}
else
for(int index = 0; index < size; index+:)
if(o.equals(elementData[index]))
{
remove(index);
return true;
}
return false;
}

public synchronized E remove(int index)
{
RangeCheck(index);
E old = elementData[index];
elementData[index] = elementData[size - 1];
elementData[--size] = null;
return old;
}

public synchronized E set(int index, E element)
{
RangeCheck(index);
E oldValue = elementData[index];
elementData[index] = element;
return oldValue;
}

public synchronized int indexOf(Object o)
{
if(o == null)
{
for(int i = 0; i < size; i+:)
if(elementData == null)
return i;
}
else
for(int i = 0; i < size; i+:)
if(o.equals(elementData))
return i;
return -1;
}

public synchronized boolean contains(Object o)
{
if(o == null)
{
for(int i = 0; i < size; i+:)
if(elementData == null)
return true;
}
else
for(int i = 0; i < size; i+:)
if(o.equals(elementData))
return true;
return false;
}

public synchronized boolean addAll(Collection<? extends E> c)
{
boolean modified = false;
Iterator<? extends E> e = c.iterator();
while(e.hasNext())
if(add(e.next()))
modified = true;
return modified;
}

public synchronized boolean removeAll(Collection<?> c)
{
boolean modified = false;
for(int i = 0; i < size; i+:)
if(c.contains(elementData))
{
elementData = elementData[size - 1];
elementData[--size] = null;
modified = true;
}
return modified;
}

public synchronized boolean retainAll(Collection<?> c)
{
boolean modified = false;
for(int i = 0; i < size; i+:)
if(!c.contains(elementData))
{
elementData = elementData[size - 1];
elementData[--size] = null;
modified = true;
}
return modified;
}

public synchronized boolean containsAll(Collection<?> c)
{
for(int i = 0; i < size; i+:)
if(!contains(elementData))
return false;
return true;
}

private void RangeCheck(int index)
{
if(index >= size)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}

@SuppressWarnings("unchecked")
public synchronized void clear()
{
int oldSize = size;
size = 0;
if(oldSize > 1000)
elementData = (E[]) new Object[10];
else
for(int i = 0; i < oldSize; i+:)
elementData = null;
size = 0;
}

/**
* Осторожно, при таком очищении в массиве могут оставаться ссылки на обьекты,
* удерживающие эти обьекты в памяти!
*/
public synchronized void clearSize()
{
size = 0;
}

public synchronized Iterator<E> iterator()
{
return new Itr();
}

private class Itr implements Iterator<E>
{
E[] data = toNativeArray();
int size = data.length;
int cursor = 0;

public boolean hasNext()
{
return cursor != size;
}

public E next()
{
try
{
return data[cursor++];
}
catch(IndexOutOfBoundsException e)
{
throw new NoSuchElementException();
}
}

/**
* НЕ РАБОТАЕТ!
*/
public void remove()
{
throw new IllegalStateException();
}
}
}
package core.gameserver.utils;

import java.util.Arrays;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
* Аналог ArrayList, но намного быстрее удаляет. <br />
* Вместо сдвига всего массива перемещает последний элемент списка на место удаленного. <br />
* Побочный эффект - размер массива при удалении элемента не меняется, но можно использовать clear. <br /> <br />
*
* Синхронизированная версия.
*
* @see core.Util.GArray - базовая версия
* @see core.Util.GCArray - конкуррентнобезопасная версия
* @see core.Util.GCSArray - конкуррентнобезопасная синхронизированная версия
*/
public class GSArray<E> implements Collection<E>
{
private transient E[] elementData;
private transient int modCount = 0;
private int size;

@SuppressWarnings("unchecked")
public GSArray(int initialCapacity)
{
super();
if(initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
this.elementData = (E[]) new Object[initialCapacity];
}

public GSArray()
{
this(10);
}

public synchronized void ensureCapacity(int minCapacity)
{
modCount++;
int oldCapacity = elementData.length;
if(minCapacity > oldCapacity)
{
int newCapacity = oldCapacity * 3 / 2 + 1;
if(newCapacity < minCapacity)
newCapacity = minCapacity;
elementData = Arrays.copyOf(elementData, newCapacity);
}
}

public int size()
{
return size;
}

public boolean isEmpty()
{
return size == 0;
}

public synchronized E[] toNativeArray()
{
return Arrays.copyOf(elementData, size);
}

public synchronized Object[] toArray()
{
return Arrays.copyOf(elementData, size);
}

@SuppressWarnings("unchecked")
public synchronized <T> T[] toArray(T[] a)
{
if(a.length < size)
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if(a.length > size)
a[size] = null;
return a;
}

public synchronized E get(int index)
{
RangeCheck(index);
return elementData[index];
}

public synchronized boolean add(E e)
{
ensureCapacity(size + 1);
elementData[size++] = e;
return true;
}

public synchronized boolean remove(Object o)
{
if(o == null)
{
for(int index = 0; index < size; index+:)
if(elementData[index] == null)
{
remove(index);
return true;
}
}
else
for(int index = 0; index < size; index+:)
if(o.equals(elementData[index]))
{
remove(index);
return true;
}
return false;
}

public synchronized E remove(int index)
{
RangeCheck(index);
modCount++;
E old = elementData[index];
elementData[index] = elementData[size - 1];
elementData[--size] = null;
return old;
}

public synchronized E set(int index, E element)
{
RangeCheck(index);
E oldValue = elementData[index];
elementData[index] = element;
return oldValue;
}

public synchronized int indexOf(Object o)
{
if(o == null)
{
for(int i = 0; i < size; i+:)
if(elementData == null)
return i;
}
else
for(int i = 0; i < size; i+:)
if(o.equals(elementData))
return i;
return -1;
}

public synchronized boolean contains(Object o)
{
if(o == null)
{
for(int i = 0; i < size; i+:)
if(elementData == null)
return true;
}
else
for(int i = 0; i < size; i+:)
if(o.equals(elementData))
return true;
return false;
}

public synchronized boolean addAll(Collection<? extends E> c)
{
boolean modified = false;
Iterator<? extends E> e = c.iterator();
while(e.hasNext())
if(add(e.next()))
modified = true;
return modified;
}

public synchronized boolean removeAll(Collection<?> c)
{
boolean modified = false;
for(int i = 0; i < size; i+:)
if(c.contains(elementData))
{
modCount++;
elementData = elementData[size - 1];
elementData[--size] = null;
modified = true;
}
return modified;
}

public synchronized boolean retainAll(Collection<?> c)
{
boolean modified = false;
for(int i = 0; i < size; i+:)
if(!c.contains(elementData))
{
modCount++;
elementData = elementData[size - 1];
elementData[--size] = null;
modified = true;
}
return modified;
}

public synchronized boolean containsAll(Collection<?> c)
{
for(int i = 0; i < size; i+:)
if(!contains(elementData))
return false;
return true;
}

private void RangeCheck(int index)
{
if(index >= size)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}

@SuppressWarnings("unchecked")
public synchronized void clear()
{
modCount++;
int oldSize = size;
size = 0;
if(oldSize > 1000)
elementData = (E[]) new Object[10];
else
for(int i = 0; i < oldSize; i+:)
elementData = null;
size = 0;
}

/**
* Осторожно, при таком очищении в массиве могут оставаться ссылки на обьекты,
* удерживающие эти обьекты в памяти!
*/
public synchronized void clearSize()
{
modCount++;
size = 0;
}

public synchronized Iterator<E> iterator()
{
return new Itr();
}

private class Itr implements Iterator<E>
{
int cursor = 0;
int lastRet = -1;
int expectedModCount = modCount;

public boolean hasNext()
{
return cursor != size();
}

public E next()
{
checkForComodification();
try
{
E next = get(cursor);
lastRet = cursor++;
return next;
}
catch(IndexOutOfBoundsException e)
{
checkForComodification();
throw new NoSuchElementException();
}
}

public void remove()
{
if(lastRet == -1)
throw new IllegalStateException();
checkForComodification();

try
{
GSArray.this.remove(lastRet);
if(lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
}
catch(IndexOutOfBoundsException e)
{
throw new ConcurrentModificationException();
}
}

final void checkForComodification()
{
if(modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
}

package core.gameserver.utils;

import java.net.HttpURLConnection;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class GetIP
{
private static final Logger _log = LoggerFactory.getLogger(GetIP.class);
private static String IpAddress;
private static void setIpAdd()
{
try
{
java.net.URL URL = new java.net.URL(" ");
java.net.HttpURLConnection Conn = (HttpURLConnection)URL.openConnection();
java.io.InputStream InStream = Conn.getInputStream();
java.io.InputStreamReader Isr = new java.io.InputStreamReader(InStream);
java.io.BufferedReader Br = new java.io.BufferedReader(Isr);
//System.out.print("Your IP address is " + Br.readLine());
//JOptionPane.showMessageDialog(null, "IP is: " + Br.readLine() );
IpAddress = Br.readLine();
}
catch(Exception e)
{
_log.info("IP service not active");
}
}
public static String getIpAddress()
{
setIpAdd();
return IpAddress;
}
}

package core.gameserver.utils;

public class GrindTeam
{
public static void info()
{
System.out.println("================================================================================");
System.out.println(" ");
System.out.println("================================================================================");
System.out.println("### ### ############ ");
System.out.println("### ### ### ############ ");
System.out.println("### ### ### ### ");
System.out.println("############ ### ###### ####### ########## ### ### ### #########");
System.out.println("############ ### ### ### ### ### ######### ### ### ### #########");
System.out.println("### ### ### ### ### ### ### ### ### ### ### ###== ");
System.out.println("### ### ### ####### ### ### ### ### ##### #########");
System.out.println("### ### ### ### ### ### ### ### ### #########");
System.out.println(" ###### ");
System.out.println("================================================================================");
}
}
Не всунешь коопирайт ты лох тогда.
package core.gameserver.utils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.sql.ResultSet;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import javolution.util.FastMap;

import core.commons.dbutils.DbUtils;

import GameGuard.GGConfig;

import core.gameserver.database.DatabaseFactory;
import core.gameserver.database.mysql;
import core.gameserver.model.GameObjectsStorage;
import core.gameserver.model.Player;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HWID
{
private static final Logger _log = LoggerFactory.getLogger(HWID.class);

private static final GArray<HardwareID> banned_hwids = new GArray<HardwareID>();
private static final GSArray<Entry<HardwareID, FastMap<String, Integer>>> bonus_hwids = new GSArray<Entry<HardwareID, FastMap<String, Integer>>>();

public static final HWIDComparator DefaultComparator = new HWIDComparator();
public static final HWIDComparator BAN_Comparator = new HWIDComparator();

public static final String SELECT_HWID = "SELECT HWID FROM " + GGConfig.HWID_BANS_TABLE;
public static final String REPLACE_HWID = "REPLACE INTO " + GGConfig.HWID_BANS_TABLE + " (hwid,comments) VALUES (?,?)";
public static final String DELETE_HWID = "DELETE FROM " + GGConfig.HWID_BANS_TABLE + " WHERE hwid=?";

public static void reloadBannedHWIDs()
{
synchronized (banned_hwids)
{
banned_hwids.clear();
}

Connection con = null;
PreparedStatement st = null;
ResultSet rs = null;
try
{
con = DatabaseFactory.getInstance().getConnection();
st = con.prepareStatement(SELECT_HWID);
rs = st.executeQuery();
synchronized (banned_hwids)
{
while (rs.next())
banned_hwids.add(new HardwareID(rs.getString("HWID")));
}

_log.info("Protection: Loaded " + banned_hwids.size() + " banned HWIDs");
}
catch(final Exception e)
{
_log.warn("Protection: Failed to load banned HWIDs", e);
}
finally
{
DbUtils.closeQuietly(con, st, rs);
}
}

public static boolean checkHWIDBanned(final HardwareID hwid)
{
synchronized (banned_hwids)
{
return hwid != null && BAN_Comparator.contains(hwid, banned_hwids);
}
}

public static String handleBanHWID(final String[] argv)
{
if(!GGConfig.ALLOW_GUARD_SYSTEM || !GGConfig.PROTECT_GS_ENABLE_HWID_BANS)
return "HWID bans feature disabled";

if(argv == null || argv.length < 2)
return "USAGE: banhwid char_name|hwid [kick:true|false] [reason]";

String hwid = argv[1]; // либо HWID, либо имя чара
if(hwid.length() != 32)
{
final Player player = GameObjectsStorage.getPlayer(hwid);
if(player == null)
return "Player " + hwid + " not found in world";
if(!player.hasHWID())
return "Player " + hwid + " not connected (offline trade)";
hwid = player.getHWID().Full;
}

if(argv.length == 2)
BanHWID(hwid, "", true);
else
{
boolean kick = true;
String reason = "";
if(argv[2].equalsIgnoreCase("true") || argv[2].equalsIgnoreCase("false"))
{
kick = Boolean.parseBoolean(argv[2]);
if(argv.length > 3)
{
for(int i = 3; i < argv.length; i+:)
reason += argv + " ";
reason = reason.trim();
}
}
// значит комменты
else
{
for(int i = 2; i < argv.length; i+:)
reason += argv + " ";
reason = reason.trim();
}
BanHWID(hwid, reason, kick);
}
return "HWID " + hwid + " banned";
}

public static boolean BanHWID(final String hwid, final String comment)
{
return BanHWID(hwid, comment, false);
}

public static boolean BanHWID(final String hwid, final String comment, final boolean kick)
{
if(!GGConfig.ALLOW_GUARD_SYSTEM || !GGConfig.PROTECT_GS_ENABLE_HWID_BANS || hwid == null || hwid.isEmpty())
return false;
return BanHWID(new HardwareID(hwid), comment, kick);
}

public static boolean BanHWID(final HardwareID hwid, final String comment, final boolean kick)
{
if(!GGConfig.ALLOW_GUARD_SYSTEM || !GGConfig.PROTECT_GS_ENABLE_HWID_BANS || hwid == null)
return false;

if(checkHWIDBanned(hwid))
{
_log.info("Protection: HWID: " + hwid + " already banned");
return true;
}

Connection con = null;
PreparedStatement st = null;
try
{
con = DatabaseFactory.getInstance().getConnection();
st = con.prepareStatement(REPLACE_HWID);
st.setString(1, hwid.Full);
st.setString(2, comment);
st.execute();

synchronized (banned_hwids)
{
banned_hwids.add(hwid);
}
Log.add("Banned HWID: " + hwid, "protect");

if(kick)
for(final Player cha : getPlayersByHWID(hwid))
cha.logout();
}
catch(final Exception e)
{
_log.warn("Protection: Failed to ban HWID: " + hwid, e);
}
finally
{
DbUtils.closeQuietly(con, st);
}

return checkHWIDBanned(hwid);
}

public static boolean UnbanHWID(final String hwid)
{
if(!GGConfig.ALLOW_GUARD_SYSTEM || !GGConfig.PROTECT_GS_ENABLE_HWID_BANS || hwid == null || hwid.isEmpty())
return false;
return UnbanHWID(new HardwareID(hwid));
}

public static boolean UnbanHWID(final HardwareID hwid)
{
if(!GGConfig.ALLOW_GUARD_SYSTEM || !GGConfig.PROTECT_GS_ENABLE_HWID_BANS || hwid == null)
return false;

if(!checkHWIDBanned(hwid))
{
_log.info("Protection: HWID: " + hwid + " already not banned");
return true;
}

Connection con = null;
PreparedStatement st = null;
try
{
con = DatabaseFactory.getInstance().getConnection();
st = con.prepareStatement(DELETE_HWID);
st.setString(1, hwid.Full);
st.execute();

synchronized (banned_hwids)
{
BAN_Comparator.remove(hwid, banned_hwids);
}
Log.add("Unbanned HWID: " + hwid, "protect");
}
catch(final Exception e)
{
_log.warn("Protection: Failed to unban HWID: " + hwid, e);
}
finally
{
DbUtils.closeQuietly(con, st);
}
return !checkHWIDBanned(hwid);
}

public static GArray<Player> getPlayersByHWID(final HardwareID hwid)
{
final GArray<Player> result = new GArray<Player>();
if(hwid != null)
for(final Player cha : GameObjectsStorage.getAllPlayers())
if(!cha.isInOfflineMode() && cha.getNetConnection() != null && cha.getNetConnection().protect_used && hwid.equals(cha.getHWID()))
result.add(cha);
return result;
}

/**
* Возвращает список всех HWID, кторые попадают под условия компаратора.
*/
public static GArray<Entry<HardwareID, FastMap<String, Integer>>> getAllMatches(final HardwareID hwid, final HWIDComparator comparator)
{
final GArray<Entry<HardwareID, FastMap<String, Integer>>> ret = new GArray<Entry<HardwareID, FastMap<String, Integer>>>();
synchronized (bonus_hwids)
{
for(final Entry<HardwareID, FastMap<String, Integer>> entry : bonus_hwids)
if(comparator.compare(entry.getKey(), hwid) == HWIDComparator.EQUALS)
ret.add(entry);
}
return ret;
}

public static class HardwareID
{
public final String Full;

public HardwareID(final String s)
{
Full = s;
}

@Override
public int hashCode()
{
return Full.hashCode();
}

@Override
public boolean equals(final Object obj)
{
if(obj == null || !(obj instanceof HardwareID))
return false;
return DefaultComparator.compare(this, (HardwareID) obj) == HWIDComparator.EQUALS;
}

@Override
public String toString()
{
return String.format("%s", Full);
}
}

public static class HWIDComparator implements Comparator<HardwareID>
{
public static final int EQUALS = 0;
public static final int NOT_EQUALS = 1;
public HWIDComparator()
{}
@Override
public int compare(final HardwareID o1, final HardwareID o2)
{
if(o1 == null || o2 == null)
return o1 == o2 ? EQUALS : NOT_EQUALS;
return EQUALS;
}

public int find(final HardwareID hwid, final List<HardwareID> in)
{
for(int i = 0; i < in.size(); i+:)
if(compare(hwid, in.get(i)) == EQUALS)
return i;
return -1;
}

public boolean contains(final HardwareID hwid, final List<HardwareID> in)
{
return find(hwid, in) != -1;
}

public boolean remove(final HardwareID hwid, final List<HardwareID> in)
{
final int i = find(hwid, in);
return i == -1 ? false : in.remove(i) != null;
}

public int find(final HardwareID hwid, final GArray<HardwareID> in)
{
for(int i = 0; i < in.size(); i+:)
if(compare(hwid, in.get(i)) == EQUALS)
return i;
return -1;
}

public boolean contains(final HardwareID hwid, final GArray<HardwareID> in)
{
return find(hwid, in) != -1;
}

public boolean remove(final HardwareID hwid, final GArray<HardwareID> in)
{
final int i = find(hwid, in);
return i == -1 ? false : in.remove(i) != null;
}

@Override
public String toString()
{
return "HWIDComparator";
}
}

private static final class Entry<K, V> implements Map.Entry<K, V>
{
private final K _key;
private V _value;

public Entry(final K key, final V value)
{
_key = key;
_value = value;
}

@Override
public K getKey()
{
return _key;
}

@Override
public V getValue()
{
return _value;
}

@Override
public V setValue(final V value)
{
return _value = value;
}
}
}
 
ItemFunctions.java приведу маленькие вырезки из кода:
public final static boolean isClanApellaItem(int itemId)
{
return itemId >= 7860 && itemId <= 7879 || itemId >= 9830 && itemId <= 9839;
}
/**
* Проверяет возможность носить эту вещь.
*
* Return null, если вещь носить можно, либо SystemMessage, который можно показать игроку
*/
public final static L2GameServerPacket checkIfCanEquip(Player player, ItemInstance item)
{
//FIXME [G1ta0] черезмерный хардкод, переделать на условия
int itemId = item.getItemId();
int targetSlot = item.getTemplate().getBodyPart();
Clan clan = player.getClan();

// RvRMode Kamael adapting
boolean isKamaelClass = false;
for(PlayerClass KamaelClassId : PlayerClass.getRaceSet(Race.kamael))
if(player.getActiveClassId() == KamaelClassId.ordinal())
{
isKamaelClass = true;
break;
}

// Геройское оружие и Wings of Destiny Circlet
if((item.isHeroWeapon() || item.getItemId() == 6842) && !player.isHero())
return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);

// камаэли и хеви/робы/щиты/сигилы
if(isKamaelClass && (item.getItemType() == ArmorType.HEAVY || item.getItemType() == ArmorType.MAGIC || item.getItemType() == ArmorType.SIGIL || item.getItemType() == WeaponType.NONE))
return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);

// не камаэли и рапиры/арбалеты/древние мечи
if(!isKamaelClass && (item.getItemType() == WeaponType.CROSSBOW || item.getItemType() == WeaponType.RAPIER || item.getItemType() == WeaponType.ANCIENTSWORD))
return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);

if(itemId >= 7850 && itemId <= 7859 && player.getLvlJoinedAcademy() == 0) // Clan Oath Armor
return new SystemMessage2(SystemMsg.THIS_ITEM_CAN_ONLY_BE_WORN_BY_A_MEMBER_OF_THE_CLAN_ACADEMY);

if(isClanApellaItem(itemId) && player.getPledgeClass() < Player.RANK_WISEMAN)
return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);

if(item.getItemType() == WeaponType.DUALDAGGER && player.getSkillLevel(923) < 1)
return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);

// Замковые короны, доступные для всех членов клана
if(ArrayUtils.contains(ItemTemplate.ITEM_ID_CASTLE_CIRCLET, itemId) && (clan == null || itemId != ItemTemplate.ITEM_ID_CASTLE_CIRCLET[clan.getCastle()]))
return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);

// Корона лидера клана, владеющего замком
if(itemId == 6841 && (clan == null || !player.isClanLeader() || clan.getCastle() == 0))
return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);

// Нельзя одевать оружие, если уже одето проклятое оружие. Проверка двумя способами, для надежности.
if(targetSlot == ItemTemplate.SLOT_LR_HAND || targetSlot == ItemTemplate.SLOT_L_HAND || targetSlot == ItemTemplate.SLOT_R_HAND)
{
if(itemId != player.getInventory().getPaperdollItemId(Inventory.PAPERDOLL_RHAND) && CursedWeaponsManager.getInstance().isCursed(player.getInventory().getPaperdollItemId(Inventory.PAPERDOLL_RHAND)))
return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
if(player.isCursedWeaponEquipped() && itemId != player.getCursedWeaponEquippedId())
return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
// Ивентовые флаги в руках
if(player._event != null && player._event.getName().equalsIgnoreCase("Capture The Flag") && player.getVar("CtF_Flag") != null)
return new SystemMessage2(SystemMsg.THIS_ITEM_CANNOT_BE_MOVED);
}

// Плащи
if(item.getTemplate().isCloak())
{
// Can be worn by Knights or higher ranks who own castle
if(item.getName().contains("Knight") && (player.getPledgeClass() < Player.RANK_KNIGHT || player.getCastle() == null))
return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);

// Плащи для камаэлей
if(item.getName().contains("Kamael") && player.getRace() != Race.kamael)
return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);

// Плащи можно носить только с S80 или S84 сетом
if(!player.getOpenCloak())
return new SystemMessage2(SystemMsg.THE_CLOAK_CANNOT_BE_EQUIPPED_BECAUSE_A_NECESSARY_ITEM_IS_NOT_EQUIPPED);
}

if(targetSlot == ItemTemplate.SLOT_DECO)
{
int count = player.getTalismanCount();
if(count <= 0)
return new SystemMessage2(SystemMsg.YOU_CANNOT_WEAR_S1_BECAUSE_YOU_ARE_NOT_WEARING_A_BRACELET).addItemName(itemId);

ItemInstance deco;
for(int slot = Inventory.PAPERDOLL_DECO1; slot <= Inventory.PAPERDOLL_DECO6; slot++)
{
deco = player.getInventory().getPaperdollItem(slot);
if(deco != null)
{
if(deco == item)
return null; // талисман уже одет и количество слотов больше нуля
// Проверяем на количество слотов и одинаковые талисманы
if(--count <= 0 || deco.getItemId() == itemId)
return new SystemMessage2(SystemMsg.YOU_CANNOT_EQUIP_S1_BECAUSE_YOU_DO_NOT_HAVE_ANY_AVAILABLE_SLOTS).addItemName(itemId);
}
}
}
return null;
}
/**
* Enchant
*/

/**
* При фейле эти свитки не ломают вещь, но сбрасывают заточку
*/
public final static boolean isBlessedEnchantScroll(int itemId)
{
switch(itemId)
{
case 6575: // Wpn D
case 6576: // Arm D
case 6573: // Wpn C
case 6574: // Arm C
case 6571: // Wpn B
case 6572: // Arm B
case 6569: // Wpn A
case 6570: // Arm A
case 6577: // Wpn S
case 6578: // Arm S
case 21582: // Blessed Enchant Scroll T'Shirt
return true;
}
return false;
}

/**
* При фейле эти свитки не имеют побочных эффектов
*/
public final static boolean isAncientEnchantScroll(int itemId)
{
switch(itemId)
{
case 22014: // Wpn B
case 22016: // Arm B
case 22015: // Wpn A
case 22017: // Arm A
case 20519: // Wpn S
case 20520: // Arm S
return true;
}
return false;
}

/**
* HF5: При неудачной модификации предмет не исчезает и сохраняет уровень модификации за счет силы Богини Разрушения. Не действует на предметы выше +15.
*/
public final static boolean isDestructionWpnEnchantScroll(int itemId)
{
switch(itemId)
{
case 22221:
case 22223:
case 22225:
case 22227:
case 22229:
return true;
}
return false;
}

/**
* HF5: При неудачной модификации предмет не исчезает и сохраняет уровень модификации за счет силы Богини Разрушения. Не действует на предметы выше +6.
*/
public final static boolean isDestructionArmEnchantScroll(int itemId)
{
switch(itemId)
{
case 22222:
case 22224:
case 22226:
case 22228:
case 22230:
return true;
}
return false;
}

/**
* Эти свитки имеют 10% бонус шанса заточки
*/
public final static boolean isItemMallEnchantScroll(int itemId)
{
switch(itemId)
{
case 22006: // Wpn D
case 22010: // Arm D
case 22007: // Wpn C
case 22011: // Arm C
case 22008: // Wpn B
case 22012: // Arm B
case 22009: // Wpn A
case 22013: // Arm A
case 20517: // Wpn S
case 20518: // Arm S
return true;
default:
return isAncientEnchantScroll(itemId);
}
}

/**
* Эти свитки имеют 100% шанс
*/
public final static boolean isDivineEnchantScroll(int itemId)
{
switch(itemId)
{
case 22018: // Wpn B
case 22020: // Arm B
case 22019: // Wpn A
case 22021: // Arm A
case 20521: // Wpn S
case 20522: // Arm S
return true;
}
return false;
}

/**
* Они не используются официальным серером, но могут быть задействованы альтами
*/
public final static boolean isCrystallEnchantScroll(int itemId)
{
switch(itemId)
{
case 957: // Wpn D
case 958: // Arm D
case 953: // Wpn C
case 954: // Arm C
case 949: // Wpn B
case 950: // Arm B
case 731: // Wpn A
case 732: // Arm A
case 961: // Wpn S
case 962: // Arm S
return true;
}
return false;
}

/**
* Проверка соответствия свитка и катализатора грейду вещи.
*
* Return id кристалла для соответствующих и 0 для несоответствующих.
*/
public final static int getEnchantCrystalId(ItemInstance item, ItemInstance scroll, ItemInstance catalyst)
{
boolean scrollValid = false, catalystValid = false;

for(int scrollId : getEnchantScrollId(item))
if(scroll.getItemId() == scrollId)
{
scrollValid = true;
break;
}

if(catalyst == null)
catalystValid = true;
else
for(int catalystId : getEnchantCatalystId(item))
if(catalystId == catalyst.getItemId())
{
catalystValid = true;
break;
}

if(scrollValid && catalystValid)
switch(item.getCrystalType().cry)
{
case ItemTemplate.CRYSTAL_NONE:
return 0;
case ItemTemplate.CRYSTAL_D:
return 1458;
case ItemTemplate.CRYSTAL_C:
return 1459;
case ItemTemplate.CRYSTAL_B:
return 1460;
case ItemTemplate.CRYSTAL_A:
return 1461;
case ItemTemplate.CRYSTAL_S:
return 1462;
}

return -1;
}

/**
* Возвращает список свитков, которые подходят для вещи.
*/
public final static int[] getEnchantScrollId(ItemInstance item)
{
if(item.getTemplate().getType2() == ItemTemplate.TYPE2_WEAPON)
switch(item.getCrystalType().cry)
{
case ItemTemplate.CRYSTAL_NONE:
return new int[]{13540};
case ItemTemplate.CRYSTAL_D:
return new int[]{955, 6575, 957, 22006, 22229};
case ItemTemplate.CRYSTAL_C:
return new int[]{951, 6573, 953, 22007, 22227};
case ItemTemplate.CRYSTAL_B:
return new int[]{947, 6571, 949, 22008, 22014, 22018, 22225};
case ItemTemplate.CRYSTAL_A:
return new int[]{729, 6569, 731, 22009, 22015, 22019, 22223};
case ItemTemplate.CRYSTAL_S:
return new int[]{959, 6577, 961, 20517, 20519, 20521, 22221};
}
else if(item.getTemplate().getType2() == ItemTemplate.TYPE2_SHIELD_ARMOR || item.getTemplate().getType2() == ItemTemplate.TYPE2_ACCESSORY)
switch(item.getCrystalType().cry)
{
case ItemTemplate.CRYSTAL_NONE:
return new int[]{21581, 21582};
case ItemTemplate.CRYSTAL_D:
return new int[]{956, 6576, 958, 22010, 22230};
case ItemTemplate.CRYSTAL_C:
return new int[]{952, 6574, 954, 22011, 22228};
case ItemTemplate.CRYSTAL_B:
return new int[]{948, 6572, 950, 22012, 22016, 22020, 22226};
case ItemTemplate.CRYSTAL_A:
return new int[]{730, 6570, 732, 22013, 22017, 22021, 22224};
case ItemTemplate.CRYSTAL_S:
return new int[]{960, 6578, 962, 20518, 20520, 20522, 22222};
}
return new int[0];
}

public static final int[][] catalyst = {
// enchant catalyst list
{12362, 14078, 14702}, // 0 - W D
{12363, 14079, 14703}, // 1 - W C
{12364, 14080, 14704}, // 2 - W B
{12365, 14081, 14705}, // 3 - W A
{12366, 14082, 14706}, // 4 - W S
{12367, 14083, 14707}, // 5 - A D
{12368, 14084, 14708}, // 6 - A C
{12369, 14085, 14709}, // 7 - A B
{12370, 14086, 14710}, // 8 - A A
{12371, 14087, 14711}, // 9 - A S
};
public final static int getCatalystPower(int itemId)
{
/*
14702 Agathion Auxiliary Stone: Enchant Weapon (D-Grade) The Agathion Auxilary Stone raises the ability to enchant a D-Grade weapon by 20%
14703 Agathion Auxiliary Stone: Enchant Weapon (C-Grade) The Agathion Auxilary Stone raises the ability to enchant a C-Grade weapon by 18%
14704 Agathion Auxiliary Stone: Enchant Weapon (B-Grade) The Agathion Auxilary Stone raises the ability to enchant a B-Grade weapon by 15%
14705 Agathion Auxiliary Stone: Enchant Weapon (A-Grade) The Agathion Auxilary Stone raises the ability to enchant a A-Grade weapon by 12%
14706 Agathion Auxiliary Stone: Enchant Weapon (S-Grade) The Agathion Auxilary Stone raises the ability to enchant a S-Grade weapon by 10%
14707 Agathion Auxiliary Stone: Enchant Armor (D-Grade) The Agathion Auxilary Stone raises the ability to enchant a D-Grade armor by 35%
14708 Agathion Auxiliary Stone: Enchant Armor (C-Grade) The Agathion Auxilary Stone raises the ability to enchant a C-Grade armor by 27%
14709 Agathion Auxiliary Stone: Enchant Armor (B-Grade) The Agathion Auxilary Stone raises the ability to enchant a B-Grade armor by 23%
14710 Agathion Auxiliary Stone: Enchant Armor (A-Grade) The Agathion Auxilary Stone raises the ability to enchant a A-Grade armor by 18%
14711 Agathion Auxiliary Stone: Enchant Armor (S-Grade) The Agathion Auxilary Stone raises the ability to enchant a S-Grade armor by 15%
*/
for(int i = 0; i < catalyst.length; i++)
for(int id : catalyst)
if(id == itemId)
switch(i)
{
case 0:
return 20;
case 1:
return 18;
case 2:
return 15;
case 3:
return 12;
case 4:
return 10;
case 5:
return 35;
case 6:
return 27;
case 7:
return 23;
case 8:
return 18;
case 9:
return 15;
}

return 0;
/*
switch(_itemId)
{
case 14702:
case 14078:
case 12362:
return 20;
case 14703:
case 14079:
case 12363:
return 18;
case 14704:
case 14080:
case 12364:
return 15;
case 14705:
case 14081:
case 12365:
return 12;
case 14706:
case 14082:
case 12366:
return 10;
case 14707:
case 14083:
case 12367:
return 35;
case 14708:
case 14084:
case 12368:
return 27;
case 14709:
case 14085:
case 12369:
return 23;
case 14710:
case 14086:
case 12370:
return 18;
case 14711:
case 14087:
case 12371:
return 15;
default:
return 0;
}
*/
}
/**
* Augmentation
*/
public final static boolean isLifeStone(int itemId)
{
return itemId >= 8723 && itemId <= 8762 || itemId >= 9573 && itemId <= 9576 || itemId >= 10483 && itemId <= 10486 || itemId >= 14166 && itemId <= 14169 || itemId >= 16160 && itemId <= 16167;
}

public final static boolean isAccessoryLifeStone(int itemId)
{
return itemId >= 12754 && itemId <= 12763 || itemId >= 12840 && itemId <= 12851 || itemId == 12821 || itemId == 12822 || itemId == 14008 || itemId == 16177 || itemId == 16178;
}

public final static int getLifeStoneGrade(int itemId)
{
switch(itemId)
{
case 8723:
case 8724:
case 8725:
case 8726:
case 8727:
case 8728:
case 8729:
case 8730:
case 8731:
case 8732:
case 9573:
case 10483:
case 14166:
case 16160:
case 16164:
return 0;
case 8733:
case 8734:
case 8735:
case 8736:
case 8737:
case 8738:
case 8739:
case 8740:
case 8741:
case 8742:
case 9574:
case 10484:
case 14167:
case 16161:
case 16165:
return 1;
case 8743:
case 8744:
case 8745:
case 8746:
case 8747:
case 8748:
case 8749:
case 8750:
case 8751:
case 8752:
case 9575:
case 10485:
case 14168:
case 16162:
case 16166:
return 2;
case 8753:
case 8754:
case 8755:
case 8756:
case 8757:
case 8758:
case 8759:
case 8760:
case 8761:
case 8762:
case 9576:
case 10486:
case 14169:
case 16163:
case 16167:
return 3;
default:
return 0;
}
}

public final static int getLifeStoneLevel(int itemId)
{
switch(itemId)
{
case 8723:
case 8733:
case 8743:
case 8753:
case 12754:
case 12840:
return 1;
case 8724:
case 8734:
case 8744:
case 8754:
case 12755:
case 12841:
return 2;
case 8725:
case 8735:
case 8745:
case 8755:
case 12756:
case 12842:
return 3;
case 8726:
case 8736:
case 8746:
case 8756:
case 12757:
case 12843:
return 4;
case 8727:
case 8737:
case 8747:
case 8757:
case 12758:
case 12844:
return 5;
case 8728:
case 8738:
case 8748:
case 8758:
case 12759:
case 12845:
return 6;
case 8729:
case 8739:
case 8749:
case 8759:
case 12760:
case 12846:
return 7;
case 8730:
case 8740:
case 8750:
case 8760:
case 12761:
case 12847:
return 8;
case 8731:
case 8741:
case 8751:
case 8761:
case 12762:
case 12848:
return 9;
case 8732:
case 8742:
case 8752:
case 8762:
case 12763:
case 12849:
return 10;
case 9573:
case 9574:
case 9575:
case 9576:
case 12821:
case 12850:
return 11;
case 10483:
case 10484:
case 10485:
case 10486:
case 12822:
case 12851:
return 12;
case 14008:
case 14166:
case 14167:
case 14168:
case 14169:
return 13;
case 16160:
case 16161:
case 16162:
case 16163:
case 16177:
return 14;
case 16164:
case 16165:
case 16166:
case 16167:
case 16178:
return 15;
default:
return 1;
}
}

/**
* Возвращает тип элемента для камня атрибуции
*
* Return значение элемента
*/
public static Element getEnchantAttributeStoneElement(int itemId, boolean isArmor)
{
Element element = Element.NONE;
switch(itemId)
{
case 9546:
case 9552:
case 10521:
case 9558:
case 9564:
element = Element.FIRE;
break;
case 9547:
case 9553:
case 10522:
case 9559:
case 9565:
element = Element.WATER;
break;
case 9548:
case 9554:
case 10523:
case 9560:
case 9566:
element = Element.EARTH;
break;
case 9549:
case 9555:
case 10524:
case 9561:
case 9567:
element = Element.WIND;
break;
case 9550:
case 9556:
case 10525:
case 9562:
case 9568:
element = Element.UNHOLY;
break;
case 9551:
case 9557:
case 10526:
case 9563:
case 9569:
element = Element.HOLY;
break;
}

if(isArmor)
return Element.getReverseElement(element);

return element;
}
 
Назад
Сверху Снизу