package org.reunionemu.jreunion.server;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import org.reunionemu.jreunion.events.Event;
import org.reunionemu.jreunion.events.EventDispatcher;
import org.reunionemu.jreunion.events.EventListener;
import org.reunionemu.jreunion.events.client.ClientConnectEvent;
import org.reunionemu.jreunion.events.client.ClientDisconnectEvent;
import org.reunionemu.jreunion.events.client.ClientEvent;
import org.reunionemu.jreunion.events.client.ClientReceiveEvent;
import org.reunionemu.jreunion.events.map.PlayerLoginEvent;
import org.reunionemu.jreunion.game.Equipment;
import org.reunionemu.jreunion.game.Equipment.Slot;
import org.reunionemu.jreunion.game.ExchangeItem;
import org.reunionemu.jreunion.game.Inventory;
import org.reunionemu.jreunion.game.InventoryItem;
import org.reunionemu.jreunion.game.Item;
import org.reunionemu.jreunion.game.LivingObject;
import org.reunionemu.jreunion.game.Npc;
import org.reunionemu.jreunion.game.Pet;
import org.reunionemu.jreunion.game.Pet.PetStatus;
import org.reunionemu.jreunion.game.Player;
import org.reunionemu.jreunion.game.Player.Race;
import org.reunionemu.jreunion.game.Player.Sex;
import org.reunionemu.jreunion.game.Player.Status;
import org.reunionemu.jreunion.game.Position;
import org.reunionemu.jreunion.game.QuickSlotItem;
import org.reunionemu.jreunion.game.RoamingItem;
import org.reunionemu.jreunion.game.Shop;
import org.reunionemu.jreunion.game.Skill;
import org.reunionemu.jreunion.game.items.GemStone;
import org.reunionemu.jreunion.game.items.etc.MissionReceiver;
import org.reunionemu.jreunion.game.items.pet.PetEgg;
import org.reunionemu.jreunion.game.npc.Merchant;
import org.reunionemu.jreunion.game.npc.Trader;
import org.reunionemu.jreunion.game.npc.Warehouse;
import org.reunionemu.jreunion.protocol.OtherProtocol;
import org.reunionemu.jreunion.server.Client.LoginType;
import org.reunionemu.jreunion.server.Client.State;
import org.reunionemu.jreunion.server.PacketFactory.Type;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Aidamina
* @license http://reunion.googlecode.com/svn/trunk/license.txt
*/
public class PacketParser extends EventDispatcher implements EventListener{
private MessageParser messageParser;
private static Logger logger = LoggerFactory.getLogger(PacketParser.class);
public PacketParser() {
super();
messageParser = new MessageParser();
}
public boolean checkCharsLoggedIn(Player player)
{
Client client = player.getClient();
boolean alreadyLogged = false;
java.util.Map<SocketChannel,Client> clients = Server.getInstance().getWorld().getClients();
synchronized(clients){
for(Client cl: clients.values()){
if(cl.equals(client))
continue;
if(cl.getAccountId()==client.getAccountId()){
alreadyLogged = true;
}
}
}
return alreadyLogged;
}
private void HandleMessage(Client client, String message[]) {
synchronized(client){
Player player = client.getPlayer();
World world = client.getWorld();
Command com = world.getCommand();
logger.debug("Parsing {} command on client: {}", message[0], client);
switch (client.getState()) {
case DISCONNECTED: {
break;
}
case ACCEPTED: {
//TODO: Better version handling
/*
try{
if (message[0].equals(Reference.getInstance().getServerReference().getItem("Server").getMemberValue("Version"))) {
logger.info("Got Version");
client.setState(Client.State.GOT_VERSION);
break;
} else {
logger.info("Inconsistent version (err 1) detected on: "
+ client);
client.sendWrongVersion(Integer.parseInt(message[0]));
client.setState(Client.State.DISCONNECTED);
break;
}
}catch(Exception e)
{
LoggerFactory.getLogger(this.getClass()).warn("Exception",e);
client.disconnect();
}
*/
int version = Integer.parseInt(message[0]);
client.setVersion(version);
if(client.getProtocol() instanceof OtherProtocol)
((OtherProtocol)client.getProtocol()).setVersion(version);
logger.info("Got version "+version);
client.setState(State.GOT_VERSION);
break;
}
case GOT_VERSION: {
if (message[0].equals("login")) {
logger.info("Got login");
client.setState(State.GOT_LOGIN);
client.setLoginType(LoginType.LOGIN);
break;
} else if(message[0].equals("play")) {
logger.info("Got play");
client.setState(State.GOT_LOGIN);
client.setLoginType(LoginType.PLAY);
break;
} else {
logger.info("Inconsistent protocol (err 2) detected on: "
+ client);
client.setState(State.DISCONNECTED);
break;
}
}
case GOT_LOGIN: {
if (message[0].length() < 28) {
client.setUsername(new String(message[0]));
logger.info("Got Username");
client.setState(State.GOT_USERNAME);
break;
} else {
logger.info("Inconsistent protocol (err 3) detected on: "
+ client);
client.setState(State.DISCONNECTED);
break;
}
}
case GOT_USERNAME: {
Server.State serverState = Server.getInstance().getState();
if(serverState!=Server.State.RUNNING){
String failMessage = null;
switch(serverState) {
case LOADING:
failMessage="Server loading, try again in a few minutes.";
break;
case CLOSING:
failMessage="Server closing, try again in a few minutes.";
break;
}
client.sendPacket(Type.FAIL, failMessage);
return;
}
if (message[0].length() < 28) {
client.setPassword(new String(message[0]));
logger.info("Got Password");
client.setState(State.GOT_PASSWORD);
com.authClient(client);
break;
} else {
logger.info("Inconsistent protocol (err 4) detected on: "
+ client);
client.setState(State.DISCONNECTED);
break;
}
}
case CHAR_LIST: {
if (message[0].equals("char_exist")) {
if (DatabaseUtils.getDinamicInstance().getCharNameFree(message[1])) {
com.sendSuccess(client);
} else {
client.sendPacket(Type.FAIL);
}
break;
} else if (message[0].equals("char_new")) {
int slot = Integer.parseInt(message[1]);
java.util.Map<SocketChannel,Client> clients = world.getClients();
synchronized(clients){
for(Client cl: clients.values()){
if(cl.equals(client))
continue;
if(cl.getAccountId()==client.getAccountId()){
Player p1 = cl.getPlayer();
if(p1!=null&&p1.getSlot()==slot){
//return because we've reserved this slot for a logged in user
//TODO:find out if we can do some feedback here to the client
client.sendPacket(Type.FAIL);
return;
}
}
}
}
Race race = Race.values()[Integer.parseInt(message[3])];
Sex sex = Sex.values()[Integer.parseInt(message[4])];
if(race == Race.HYBRIDER)
{
client.sendPacket(Type.FAIL);
com.sendCharList(client);
return;
}
com.createChar(client, slot,
message[2], race,
sex,
Integer.parseInt(message[5]),
Integer.parseInt(message[6]),
Integer.parseInt(message[7]),
Integer.parseInt(message[8]),
Integer.parseInt(message[9]),
Integer.parseInt(message[10]));
com.sendSuccess(client);
com.sendCharList(client);
} else if (message[0].equals("char_del")) {
com.delChar(Integer.parseInt(message[1]), client.getAccountId());
com.sendSuccess(client);
com.sendCharList(client);
} else if (message[0].equals("start")) {
client.setState(Client.State.LOADING);
int slot = Integer.parseInt(message[1]);
player = com.loginChar(slot, client.getAccountId(), client);
if(player==null){
client.sendPacket(Type.FAIL, "Cannot log in");
client.disconnect();
}
}
break;
}
case LOADING: {
if (message[0].equals("start_game")) {
Map map = null;
for (Map m : Server.getInstance().getWorld().getMaps()) {
if (m.getAddress().equals(client.getSocketChannel().socket().getLocalSocketAddress())) {
map = m;
break;
}
}
if (map == null || !map.isLocal()) {
LoggerFactory.getLogger(Command.class).error("Invalid Map: " + map);
player.getClient().disconnect();
return;
}
Position savedPosition = DatabaseUtils.getDinamicInstance().getSavedPosition(player);
if(savedPosition != null) {
Map savedMap = savedPosition.getMap();
if(client.getLoginType()==LoginType.LOGIN){
if(map!= savedMap) {
com.GoToWorld(player, savedMap, 0);
return;
}
}
else{
if(map!= savedMap) {
savedPosition = null;
}
}
}
player.getPosition().setMap((LocalMap)map);
world.getPlayerManager().addPlayer(player);
DatabaseUtils.getDinamicInstance().loadStash(client);
DatabaseUtils.getDinamicInstance().loadQuickSlot(player);
DatabaseUtils.getDinamicInstance().loadInventory(player);
DatabaseUtils.getDinamicInstance().loadExchange(player);
player.loadInventory();
player.loadExchange();
player.loadQuickSlot();
client.sendPacket(PacketFactory.Type.OK);
//System.out.println(savedPosition);
map.fireEvent(PlayerLoginEvent.class, player, savedPosition);
/*
* server.getNetworkModule().SendPacket(client.networkId,
* "hour 3\n" + "weather 0\n" + "gwar_prize 0\n" +
* "guild_level 0\n" +
* "on_battle 0 3 BlackSouls 7 SlAcKeRs 0 DELTA 700 pSyKo 701 SlAcKeRs 702 Iron_Fist 703 pSyKo\n"
* +
* "mypet 99935 PHOENIX 7049 5297 0.0 585 591 595 597 602 605 7219 6181\n" +
* "pstatus 0 20790 20000 0\n" + "pstatus 1 10000 0 0\n" +
* "pstatus 2 10000 0 0\n" + "pstatus 3 10000 0 0\n" +
* "pstatus 4 10000 0 0\n" + "pstatus 5 15 0 0\n" +
* "pstatus 6 39 0 0\n" + "pstatus 7 4 0 0\n" +
* "pstatus 8 100 0 0\n" + "pstatus 9 100 0 0\n" +
* "pstatus 10 100 0 0\n" + "pstatus 12 4190441 0 0\n" +
* "pstatus 11 16826042 0 0\n" + "pstatus 17 693315 0 0\n" +
* "pstatus 13 14 0 0\n" + "pstatus 15 619 0 0\n" +
* "pstatus 16 6 0 0\n" + "pstatus 18 967 0 0\n");
*/
// "pstatus 13 2 0 0\n");
/*
player.updateStatus(0, player.getHp(),
player.getStr() * 1 + player.getConstitution() * 2);
player.updateStatus(1, player.getMana(),
player.getWis() * 2 + player.getDexterity() * 1);
player.updateStatus(2, player.getStm(),
player.getStr() * 2 + player.getConstitution() * 1);
player.updateStatus(3, player.getElect(),
player.getWis() * 1 + player.getDexterity() * 2);
player.updateStatus(13, -player.getStatusPoints(), 0);
int statusPoints = player.getStr() + player.getWis() + player.getDexterity()
+ player.getConstitution() + player.getLeadership() - 80;
player.updateStatus(13, (player.getLevel() - 1) * 3 - statusPoints, 0);
world.getTeleportManager().remove(player);
*/
client.setState(Client.State.INGAME);
if(player.getPosition().getMap().getId() == 4)
client.sendPacket(Type.INFO, world.getServerSetings().getWelcomeMessage());
//world.sendPacket(Type.SAY, player.getName() + " (" +player.getPlayerId()+ ") logged in on Map "+player.getPosition().getMap().getName());
player.setHp(player.getMaxHp());
player.setStamina(player.getMaxStamina());
player.setMana(player.getMaxMana());
player.setElectricity(player.getMaxElectricity());
player.sendStatus(Status.TOTALEXP);
player.sendStatus(Status.LEVELUPEXP);
player.sendStatus(Status.STATUSPOINTS);
player.sendStatus(Status.LIME);
player.sendStatus(Status.PENALTYPOINTS);
//player.setQuestState(DatabaseUtils.getDinamicInstance().loadQuestState(player));
player.update();
//handle with player pet loading
Pet pet = world.getPetManager().getPet(player);
if(pet != null){
Item<?> item = player.getEquipment().getShoulderMount();
player.setPet(pet);
pet.setOwner(player);
pet.sendStatus(PetStatus.STATE);
if(pet.getState() > 1){
pet.setEquipment(DatabaseUtils.getDinamicInstance().loadPetEquipment(player));
if(pet.getState() == 12){
pet.load();
}
} else if(item != null && item.getType() instanceof PetEgg){
pet.setBreeding(true);
pet.startBreeding();
}
} else {
player.getClient().sendPacket(Type.PSTATUS, 13, 0l, 0l, 0);
}
if(map.getId() == 6){
int flyStatus = player.getEquipment().getBoots().getExtraStats() >= 268435456 ? 1 : 0;
player.getClient().sendPacket(Type.SKY, player, flyStatus);
}
Player playerobj = client.getPlayer();
if(playerobj.getGuildId() != 0)
{
client.sendPacket(Type.GUILD_NAME, playerobj);
client.sendPacket(Type.GUILD_GRADE, playerobj);
client.sendPacket(Type.GUILD_LEVEL, playerobj);
}
}
break;
}
case LOADED: {
logger.info("Received" +message[0]+" while loaded state");
break;
}
case INGAME: {
if (message[0].equals("walk")) {
Position position = new Position(
Integer.parseInt(message[1]),
Integer.parseInt(message[2]),
Integer.parseInt(message[3]),
player.getPosition().getLocalMap(),
Double.NaN
);
client.getPlayer().walk(position,
Integer.parseInt(message[4])==1);
client.getPlayer().update();
} else if (message[0].equals("place")) {
double rotation = Double.parseDouble(message[4]);
Position position = new Position(
Integer.parseInt(message[1]),
Integer.parseInt(message[2]),
Integer.parseInt(message[3]),
player.getPosition().getLocalMap(),
rotation/10000
);
client.getPlayer().place(position,
Integer.parseInt(message[5]),
Integer.parseInt(message[6])==1);
client.getPlayer().update();
} else if (message[0].equals("stop")) {
double rotation = Double.parseDouble(message[4]);
Position position = new Position(
Integer.parseInt(message[1]),
Integer.parseInt(message[2]),
Integer.parseInt(message[3]),
player.getPosition().getLocalMap(),
rotation/10000
);
client.getPlayer().stop(position);
client.getPlayer().update();
} else if (message[0].equals("stamina")) {
client.getPlayer().loseStamina((Integer.parseInt(message[1]) > 0) ? Integer.parseInt(message[1]) : 2);
}
else if (message[0].equals("say")) {
String text = message[1];
for (int i = 2; i < message.length; i++) {
text += " " + message[i];
}
text = messageParser.parse(client.getPlayer(), text);
if (text != null && text.length() > 0) {
player.say(text);
}
}
else if (message[0].equals("upgrade")) {
Slot slot = Slot.byValue(Integer.parseInt(message[1]));
Item<?> item = player.getEquipment().getItem(slot);
item.upgrade(player,slot);
}
else if (message[0].equals("npc_init")) {
if(message.length == 6) {
int strength = Integer.parseInt(message[1]);
int wisdom = Integer.parseInt(message[2]);
int dex = Integer.parseInt(message[3]);
int strain = Integer.parseInt(message[4]);
int charisma = Integer.parseInt(message[5]);
int sumuSP = strength+wisdom+dex+strain+charisma;
long playerLevel = player.getLevel();
int reskillCosts = (int) ((playerLevel <= 99 ) ? ((playerLevel * playerLevel * playerLevel) * 0.4) : ((playerLevel <= 119) ? ((playerLevel * playerLevel * playerLevel) * 0.7) : ((playerLevel >= 120)) ? (playerLevel * playerLevel * playerLevel) : 0 ));
if(player.getLime() > reskillCosts)
{
boolean allowed = (((player.getRace() == Race.HYBRIDER && strength >= 5 && strength <= 30 && wisdom >=5 && wisdom <= 10 && dex >=5 && dex <=10 && strain >= 5 && strain <= 25 && charisma >=5 && charisma <= 5)) ? true : (((player.getRace() == Race.AIDIA && strength >= 5 && strength <= 15 && wisdom >=5 && wisdom <= 30 && dex >=5 && dex <=20 && strain >= 5 && strain <= 15 && charisma >=5 && charisma <= 20) ) ? true : ((player.getRace() == Race.HUMAN && strength >= 5 && strength <= 15 && wisdom >=5 && wisdom <= 5 && dex >=5 && dex <=30 && strain >= 5 && strain <= 20 && charisma >=5 && charisma <= 10) ? true : ((player.getRace() == Race.KAILIPTON && strength >= 5 && strength <= 15 && wisdom >=5 && wisdom <= 30 && dex >=5 && dex <=5 && strain >= 5 && strain <= 15 && charisma >=5 && charisma <= 15) ? true : ((player.getRace() == Race.BULKAN && strength >= 5 && strength <= 30 && wisdom >=5 && wisdom <= 5 && dex >=5 && dex <=5 && strain >= 5 && strain <= 30 && charisma >=5 && charisma <= 10) ? true : false)))));
if(allowed && sumuSP == 80) {
player.setLime(player.getLime()-reskillCosts);
player.setStrength(strength);
player.setWisdom(wisdom);
player.setDexterity(dex);
player.setConstitution(strain);
player.setLeadership(charisma);
player.resetSkills();
sumuSP = 80-sumuSP-3;
player.setStatusPoints(player.getMaxStatusPoints()+sumuSP);
client.sendPacket(Type.SAY, "Reskill was successfull!");
}
else
{
client.sendPacket(Type.SAY, "Sum of Strength, Wisdom, Dex, Stain and charisma must be 80");
}
}
else
{
client.sendPacket(Type.SAY, "You don't have enough lime!");
}
}
}
else if (message[0].equals("tell")) {
String text = "";
for (int i = 2; i < message.length; i++) {
text += " " + message[i];
}
player.tell(message[1], text); //message[1]: playername
} else if (message[0].equals(":")) {
Iterator<Player> iterPlayer = Server.getInstance().getWorld().getPlayerManager().getPlayerListIterator();
long guildId = player.getGuildId();
if(guildId != 0)
{
String text = "";
for (int i = 1; i < message.length; i++) {
text += " " + message[i];
}
boolean guildmemberonline = false;
while(iterPlayer.hasNext())
{
Player currplayer = iterPlayer.next();
if(currplayer.getGuildId() == guildId && currplayer != player)
{
guildmemberonline = true;
currplayer.getClient().sendPacket(Type.GUILD_SAY, text, player);
}
}
if(guildmemberonline)
client.sendPacket(Type.GUILD_SAY, text, player);
else
client.sendPacket(Type.SAY, "Currently there is no online guild member");
}
else
{
client.sendPacket(Type.SAY, "You dont have a guild");
}
} else if (message[0].equals("combat")) {
client.getPlayer().setIsInCombat(Integer.parseInt(message[1])==1);
} else if (message[0].equals("social")) {
player.setSocial(Long.parseLong(message[1]));
} else if (message[0].equals("levelup")) {
Status status = Status.byValue(Integer.parseInt(message[1])+10);
player.addStatus(status);
} else if (message[0].equals("pick")) {
int entityId = Integer.parseInt(message[1]);
LocalMap map = player.getPosition().getLocalMap();
RoamingItem roamingItem = (RoamingItem)map.getRoamingItem(entityId);
if(roamingItem!=null && player.getInventory().getHoldingItem()==null ){
client.getPlayer().pickupItem(roamingItem);
}
} else if (message[0].equals("use_inven")) {
int tab = Integer.parseInt(message[1]);
int x = Integer.parseInt(message[2]);
int y = Integer.parseInt(message[3]);
Inventory inventory = player.getInventory();
InventoryItem inventoryItem = inventory.getItem(tab, x, y);
Item<?> item = inventoryItem.getItem();
com.useItem(player, item, -1);
inventory.deleteInventoryItem(inventoryItem);
//used when we click in any position inside the inventory
} else if (message[0].equals("inven")) {
int tab = Integer.parseInt(message[1]);
int x = Integer.parseInt(message[2]);
int y = Integer.parseInt(message[3]);
client.getPlayer().getInventory().handleInventory(tab, x, y);
} else if (message[0].equals("drop")) {
client.getPlayer().dropItem(Integer.parseInt(message[1]));
} else if (message[0].equals("subat")) {
Skill skill = world.getSkillManager().getSkill(Integer.parseInt(message[3]));
skill.handle(player, message);
/*
LivingObject singleTarget = (LivingObject)player.getPosition().getLocalMap().getEntity(Integer.parseInt(message[2]));
int skillId = Integer.parseInt(message[3]);
int unknown1 = Integer.parseInt(message[4]);
List<LivingObject> targets = new Vector<LivingObject>(); //TODO: add several targets
targets.add(singleTarget);
com.subAttack(player,targets,skillId,unknown1);
*/
} else if (message[0].equals("pulse")) {
if (Integer.parseInt(message[2].substring(0,
message[2].length() - 1)) == -1) {
//client.getPlayer().setMinDmg(1);
//client.getPlayer().setMaxDmg(2);
} else {
com.playerWeapon(
client.getPlayer(),
Integer.parseInt(message[3].substring(0,
message[3].length() - 1)));
}
} else if (message[0].equals("wear")) {
int slotId = Integer.parseInt(message[1]);
Equipment.Slot slot = Equipment.Slot.byValue(slotId);
client.getPlayer().wearSlot(slot);
// com.getPlayer()Wear(client.getPlayer()Object,Integer.parseInt(message[1]));
} else if (message[0].equals("use_skill") || message[0].equals("attack")) {
// if attack command sent, then use SkillID 0 (Basic Attack)
int skillId = message[0].equals("attack") ? 0 : Integer.parseInt(message[1]);
Skill skill = player.getSkill(skillId);
if(skill!=null){
skill.handle(player, message);
}
else{
logger.error("Skill with id %d not found.", skillId);
}
} else if (message[0].equals("skillup")) {
synchronized(player) {
float statusPoints = player.getStatusPoints();
if(statusPoints>0){
int skillId = Integer.parseInt(message[1]);
Skill skill = player.getSkill(skillId);
if(skill.levelUp(player)){
player.setStatusPoints(player.getStatusPoints() - 1);
}
}
}
} else if (message[0].equals("revival")) {
client.getPlayer().revive();
} else if (message[0].equals("g_pos")) {
if(message[1].equals("req"))
{
Iterator<Player> iterPlayer = Server.getInstance().getWorld().getPlayerManager().getPlayerListIterator();
long guildId = player.getGuildId();
client.sendPacket(Type.G_POS_START);
if(guildId != 0)
{
while(iterPlayer.hasNext())
{
Player currplayer = iterPlayer.next();
if(currplayer.getGuildId() == guildId)
{
if(currplayer.getPosition().getMap() == player.getPosition().getMap() && currplayer != player)
client.sendPacket(Type.G_POS_BODY, currplayer);
}
}
client.sendPacket(Type.G_POS_END);
}
else
{
client.sendPacket(Type.SAY, "You dont have a guild");
}
}
} else if (message[0].equals("quick")) {
client.getPlayer().getQuickSlotBar().quickSlot(
client.getPlayer(), Integer.parseInt(message[1]));
} else if (message[0].equals("go_world")) {
int mapId = Integer.parseInt(message[1]);
Map map = world.getMap(mapId);
com.GoToWorld(client.getPlayer(), map,
Integer.parseInt(message[2]));
} else if (message[0].equals("trans")) {
int posx = (int) Float.parseFloat(message[1]);
int posy = (int) Float.parseFloat(message[2]);
Position position = player.getPosition().clone();
position.setX(posx);
position.setY(posy);
com.GoToPos(player, position);
} else if (message[0].equals("use_quick")) { //2007 client
player.getQuickSlotBar().useQuickSlot(
player, Integer.parseInt(message[1]));
QuickSlotItem qsItem = player.getQuickSlotBar().getItem(Integer.parseInt(message[1]));
Item<?> item = qsItem.getItem();
if(item.getType() instanceof GemStone){
int index = 2;
while (index < message.length) {
int tab = Integer.parseInt(message[index++]);
int posX = Integer.parseInt(message[index++]);
int posY = Integer.parseInt(message[index++]);
InventoryItem invItem = player.getInventory().getItem(tab, posX, posY);
Item<?> assemblingKit = invItem.getItem();
player.getInventory().deleteInventoryItem(invItem);
player.getPosition().getLocalMap().removeEntity(assemblingKit);
}
}
} else if (message[0].equals("using_item")) {
int unknown = Integer.parseInt(message[1]);
int quickSlotBarPosition = Integer.parseInt(message[2]);
int itemEntityId = Integer.parseInt(message[3]);
int unknown2 = message.length == 5 ? Integer.parseInt(message[4]): 0;
player.getQuickSlotBar().useQuickSlot(
player, quickSlotBarPosition, unknown2, itemEntityId);
} else if (message[0].equals("move_to_quick")) { // old 2007 client
player.getQuickSlotBar().MoveToQuick(
Integer.parseInt(message[1]),
Integer.parseInt(message[2]),
Integer.parseInt(message[3]));
} else if (message[0].equals("moving_item")) {
player.getQuickSlotBar().MovingItem(
Integer.parseInt(message[1]),
Integer.parseInt(message[2]),
Integer.parseInt(message[3]));
} else if (message[0].equals("quest")) {
if (message[1].equals("cancel")) {
client.getPlayer().setQuest(null);
} else if (message[1].equals("click")) {
//TODO: use archeologist (npcType=257) to give quest scroll to meta players
} else {
if (client.getPlayer().getQuest() == null) {
Item<?> item = player.getQuickSlotBar().getItem(Integer.parseInt(message[1])).getItem();
if(item.is(MissionReceiver.class)){
((MissionReceiver)item.getType()).use(item, player,Integer.parseInt(message[1]),0);
}
} else {
player.getClient().sendPacket(Type.SAY, "Player already has an ongoing quest.");
}
}
} else if (message[0].equals("stash_open")) {
if(!checkCharsLoggedIn(player))
{
if (message.length == 1) {
Warehouse warehouse = (Warehouse)client.getWorld().getNpcManager().getNpcType(Warehouse.class);
warehouse.openStash(client.getPlayer());
} else {
logUnknownCommand(message);
}
}
else
{
client.sendPacket(Type.SAY, "You cant use the warehouse if u're logged in with more than one char!");
}
} else if (message[0].equals("stash_click") && !checkCharsLoggedIn(player)) {
if(message.length >= 4){
Warehouse warehouse = (Warehouse)client.getWorld().getNpcManager().getNpcType(Warehouse.class);
int special = message.length == 5 ? Integer.parseInt(message[4]) : 0;
warehouse.stashClick(client.getPlayer(),
Integer.parseInt(message[1]),
Integer.parseInt(message[2]),
Integer.parseInt(message[3]),
special);
}
} else if (message[0].equals("stash_put") && !checkCharsLoggedIn(player)) {
Warehouse warehouse = (Warehouse)client.getWorld().getNpcManager().getNpcType(Warehouse.class);
int length = message.length > 23 ? 23 : message.length;
int[] packetData = new int[length];
int index = 0;
while(index < packetData.length -1){
packetData[index] = Integer.parseInt(message[index++ + 1]);
}
warehouse.stashPut(player, packetData);
} else if (message[0].equals("stash_get") && !checkCharsLoggedIn(player)) {
if(message.length >= 5){
Warehouse warehouse = (Warehouse)client.getWorld().getNpcManager().getNpcType(Warehouse.class);
warehouse.stashGet(player,
Integer.parseInt(message[1]),
Integer.parseInt(message[2]),
Integer.parseInt(message[3]),
Integer.parseInt(message[4]));
}
} else if (message[0].equals("stash_close") && !checkCharsLoggedIn(player)) {
//nothing is returned to the client here, so we can just save the stash in the DB.
if (message.length == 1) {
//logger.info("Saving "+player+" stash...");
//DatabaseUtils.getDinamicInstance().saveStash(client);
player.save();
} else {
logUnknownCommand(message);
}
} else if (message[0].equals("shop")) {
int npcId = Integer.parseInt(message[1]);
Npc<?> npc = (Npc<?>) player.getPosition().getLocalMap().getEntity(npcId);
if (npc!=null) {
if(npc.getType() instanceof Merchant){
npc.getShop().openShop(client.getPlayer());
//((Merchant)npc.getType()).openShop(client.getPlayer());
}
} else {
logger.warn("Npc not found: " + npcId);
}
} else if (message[0].equals("buy")) {
int npcId = Integer.parseInt(message[1]);
Npc<?> npc = (Npc<?>) player.getPosition().getLocalMap().getEntity(npcId);
if (npc!=null) {
if(npc.getType() instanceof Merchant){
npc.getShop().buyItem(client.getPlayer(), Integer.parseInt(message[4]),
Integer.parseInt(message[5]), 1);
//((Merchant)npc.getType()).buyItem(client.getPlayer(), Integer.parseInt(message[4]),
// Integer.parseInt(message[5]), 1);
}
} else {
logger.warn("Npc not found: " + npcId);
}
} else if (message[0].equals("sell")) {
int npcId = Integer.parseInt(message[1]);
Npc<?> npc = (Npc<?>) player.getPosition().getLocalMap().getEntity(npcId);
if (npc!=null) {
if(npc.getType() instanceof Merchant){
npc.getShop().sellItem(client.getPlayer());
//((Merchant)npc.getType()).sellItem(client.getPlayer());
}
} else {
logger.warn("Npc not found: " + npcId);
}
} else if (message[0].equals("pbuy")) {
int npcId = Integer.parseInt(message[1]);
Npc<?> npc = (Npc<?>) player.getPosition().getLocalMap().getEntity(npcId);
int itemType = Integer.parseInt(message[2]);
int tab = Integer.parseInt(message[3]);
int quantity = 10;
if (npc!=null) {
if(npc.getType() instanceof Merchant){
npc.getShop().buyItem(client.getPlayer(), itemType, tab, quantity);
//((Merchant)npc.getType()).buyItem(client.getPlayer(), itemType, tab, quantity);
}
} else {
logger.warn("Npc not found: " + npcId);
}
} else if (message[0].equals("chip_exchange")) { //exchange 5 chips any grade
Trader trader = (Trader)world.getNpcManager().getNpcType(Trader.class);
if (message.length == 3) {
trader.chipExchange(player,
Integer.parseInt(message[1]),
Integer.parseInt(message[2]),
-1);
} else {
trader.chipExchange(player,
Integer.parseInt(message[1]),
Integer.parseInt(message[2]),
Integer.parseInt(message[3]));
}
} else if (message[0].equals("exch")) { //handles exchange inventory
if (message.length == 2) {
if(message[1].equals("cancel")){ // cancel request
player.getExchange().cancelRequest();
} else if(message[1].equals("ok")) { //accept request
player.getExchange().acceptRequest();
} else if(message[1].equals("trade")) { //trade confirmation
player.getExchange().tradeConfirmation();
}
} else if (message.length == 3) {
if(message[1].equals("money")){ // add money
long money = Long.parseLong(message[2]);
player.getExchange().addMoney(money);
}
} else if (message.length == 4) {
if(message[1].equals("inven")){ //exchange inventory click
client.getPlayer().itemExchange(Integer.parseInt(message[2]),
Integer.parseInt(message[3]));
}
}
} else if (message[0].equals("ichange")) { //armor exchange
Trader trader = (Trader)world.getNpcManager().getNpcType(Trader.class);
if (message.length == 1) {
trader.exchangeArmor(player, 0);
} else {
trader.exchangeArmor(player, Integer.parseInt(message[1]));
}
} else if (message[0].equals("q_ex")) {
if(player.getExchange().listSize() > 0){
if(!player.getExchange().isItemsScrolls()){
player.getClient().sendPacket(Type.MSG, "Wrong item.");
return;
}
int limeAmmount = 0;
Iterator<ExchangeItem> exchangeIter = player.getExchange().itemListIterator();
while(exchangeIter.hasNext()){
ExchangeItem exchangeItem = exchangeIter.next();
limeAmmount += exchangeItem.getItem().getExtraStats();
DatabaseUtils.getDinamicInstance().deleteItem(exchangeItem.getItem().getItemId());
}
player.getExchange().clearExchange();
player.setLime(player.getLime() + limeAmmount);
player.getClient().sendPacket(Type.Q_EX, limeAmmount);
}
} else if (message[0].equals("up_sky")) {
Item<?> boots = player.getEquipment().getBoots();
if(boots != null){
boots.update(player, Slot.BOOTS);
if(player.getPosition().getLocalMap().getId() == 6)
client.sendPacket(Type.SKY, player, 1);
}
} else if (message[0].equals("use_sub")) {
if (message.length == 2) {
player.getQuickSlotBar().useQuickSlot(player, Integer.parseInt(message[1]));
}
} else if (message[0].equals("go_zone")) {
if (message.length == 4) {
Item<?> item = player.getQuickSlotBar().getItem(Integer.parseInt(message[1])).getItem();
item.setGemNumber(Integer.parseInt(message[2]));
item.setExtraStats(Integer.parseInt(message[3]));
player.getQuickSlotBar().useQuickSlot(player, Integer.parseInt(message[1]));
}
} else if (message[0].equals("p_walk")) {
if (message.length == 5) {
Position position = new Position(
Integer.parseInt(message[1]),
Integer.parseInt(message[2]),
Integer.parseInt(message[3]),
player.getPosition().getLocalMap(),
Double.NaN
);
client.getPlayer().getPet().walk(position,
Integer.parseInt(message[4])==1);
}
} else if (message[0].equals("p_drop")) {
if (message.length == 2) {
Pet pet = player.getPet();
pet.getPosition().getLocalMap().removeEntity(pet);
world.getPetManager().removePet(pet);
player.setPet(null);
DatabaseUtils.getDinamicInstance().deletePet(pet);
client.sendPacket(Type.MYPET, "del");
player.getInterested().sendPacket(Type.OUT, pet);
LoggerFactory.getLogger(this.getClass()).info("Player: "+player+" deleted Pet: "+pet);
int tab = Integer.parseInt(message[1]);
pet = new Pet(player, 1);
world.getPetManager().buyEgg(pet, tab);
}
} else if (message[0].equals("p_keep")) {
if (message.length == 2) {
Pet pet = world.getPetManager().getPet(player);
if(message[1].equals("open")){
if(pet != null){
if(pet.getState() == 1){
client.sendPacket(Type.P_KEEP, "fail", pet);
} else if(pet.getState() >= 2){
client.sendPacket(Type.P_KEEP, "info", pet);
}
}
} else if(message[1].equals("in")){
pet.setState(2);
pet.getPosition().getLocalMap().removeEntity(pet);
client.sendPacket(Type.MYPET, "del");
pet.sendStatus(PetStatus.STATE);
player.getInterested().sendPacket(Type.OUT, pet);
LoggerFactory.getLogger(this.getClass()).info("Pet: "+pet+" stored at Npc.");
}else if(message[1].equals("out")){
player.setLime(player.getLime()-15000);
pet.setState(12);
pet.setSatiety(100);
pet.setHp(pet.getMaxHp());
pet.load();
player.getInterested().sendPacket(Type.IN_PET, player, true);
LoggerFactory.getLogger(this.getClass()).info("Pet: "+pet+" removed from Npc.");
}
}
} else if (message[0].equals("buy_egg")) {
if (message.length == 2) {
int tab = Integer.parseInt(message[1]);
Pet pet = new Pet(player, 1);
world.getPetManager().buyEgg(pet, tab);
}
} else if (message[0].equals("party")) {
if(message.length > 1){
if(message[1].equals("request")){ //party invitation
LocalMap map = player.getPosition().getLocalMap();
Player newMember = map.getWorld().getPlayerManager().getPlayer(message[2]);
map.inviteParty(player, newMember, Integer.parseInt(message[3]), Integer.parseInt(message[4]));
} else if(message[1].equals("consist")){ //party invitation accepted
int inviterEntityId = Integer.parseInt(message[3]);
LocalMap map = player.getPosition().getLocalMap();
Player inviterPlayer = (Player)map.getEntity(inviterEntityId);
inviterPlayer.getParty().accept(inviterEntityId, player);
} else if (message[1].equals("secession")){
if(message.length > 2){ // party invitation rejected
int inviterEntityId = Integer.parseInt(message[2]);
player.getPosition().getLocalMap().getParty(inviterEntityId).reject(inviterEntityId, player);
} else{ //request party exit
player.getParty().exit(player);
}
}
}
} else if (message[0].equals("exchange")) { //exchange request with another player
if (message.length == 2) {
String targetName = message[1];
Player target = world.getPlayerManager().getPlayer(targetName);
player.getExchange().request(target);
}
} else if (message[0].equals("u_shop")) { //exchange request with another player
if (message.length > 1) {
if(message[1].equals("close")){
if(player.getShop() != null){
Shop buyingFromShop = player.getPosition().getLocalMap().getShopBuying(player);
if(buyingFromShop != null){
buyingFromShop.removePlayerBuying(player.getShop());
}
player.getShop().close();
}
} else if(message[1].equals("reg")){
int shopPosition = Integer.parseInt(message[2]);
int invTab = Integer.parseInt(message[3]);
int goldBars = Integer.parseInt(message[4]);
int silverBars = Integer.parseInt(message[5]);
int bronzeBars = Integer.parseInt(message[6]);
long price = Long.parseLong(message[7]);
int invPosX = Integer.parseInt(message[8]);
int invPosY = Integer.parseInt(message[9]);
player.getShop().regItem(shopPosition, invTab, goldBars, silverBars, bronzeBars, price, invPosX, invPosY);
} else if(message[1].equals("unreg")){
Integer position = Integer.parseInt(message[2]);
Integer ammount = Integer.parseInt(message[4]);
player.getShop().unRegItem(position, ammount);
} else if(message[1].equals("start")){
player.getShop().start(message);
} else if(message[1].equals("modify")){
for(Shop shop : player.getShop().getPlayersBuying()){
shop.getOwner().getClient().sendPacket(Type.MSG, player.getName()+" closed shop.");
shop.close();
}
player.getShop().getPlayersBuying().clear();
player.getShop().modify();
} else if(message[1].equals("open")){
int shopOwnerEntityId = Integer.parseInt(message[3]);
Player shopOwner = world.getPlayerManager().getPlayer(shopOwnerEntityId);
shopOwner.getShop().open(player);
} else if(message[1].equals("buy")){
Integer position = Integer.parseInt(message[2]);
Integer ammount = Integer.parseInt(message[4]);
player.getShop().buy(position, ammount);
}
}
} else if (message[0].equals("..")) {
//client keep alive
} else {
logUnknownCommand(message);
if(!message[0].contains("encrypt_") && player.getAdminState()>=260)
client.sendPacket(Type.SAY,"Encrypt: "+StringUtils.join(message, " "));
}
break;
}
default: {
logger.error("State Conflict: "+client.getState());
client.setState(Client.State.DISCONNECTED);
}
}
}
}
public void logUnknownCommand(String [] message){
logger.warn("Unknown command:\n"+StringUtils.join(message, " "));
}
public void Parse(Client client, String packet) {
String[] messages = ParsePacket(packet);
if (client.getState() != Client.State.DISCONNECTED) {
for (String message : messages) {
String[] words = ParseMessage(message);
if (client.getState() != Client.State.DISCONNECTED) {
HandleMessage(client, words);
}
}
}
}
static Pattern regexParseMessage = Pattern.compile(" ");
private String[] ParseMessage(String message) {
return regexParseMessage.split(message);
}
static Pattern regexParsePacket = Pattern.compile("\n");
private String[] ParsePacket(String packet) {
return regexParsePacket.split(packet);
}
@Override
public void handleEvent(Event event) {
if (event instanceof ClientEvent){
Client client =((ClientEvent) event).getClient();
if(event instanceof ClientReceiveEvent){
ClientReceiveEvent e = (ClientReceiveEvent)event;
String data = null;
synchronized(client){
StringBuffer inputBuffer = client.getInputBuffer();
data = inputBuffer.toString();
inputBuffer.setLength(0);
}
if(data!=null&&!data.isEmpty())
Parse(client, data);
}else
if(event instanceof ClientConnectEvent){
ClientConnectEvent e = (ClientConnectEvent)event;
client.addEventListener(ClientReceiveEvent.class, this);
}else
if(event instanceof ClientDisconnectEvent){
client.removeEventListener(ClientReceiveEvent.class, this);
}
}
}
}