/* This file is part of the OdinMS Maple Story Server Copyright (C) 2008 ~ 2010 Patrick Huy <patrick.huy@frz.cc> Matthias Butz <matze@odinms.de> Jan Christian Meyer <vimes@odinms.de> This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation. You may not use, modify or distribute this program under any other version of the GNU Affero General Public License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package tools.packet; import client.MapleCharacter; import client.MapleClient; import client.inventory.Item; import constants.GameConstants; import handling.SendPacketOpcode; import handling.channel.handler.PlayerInteractionHandler; import handling.world.MapleCharacterLook; import java.util.List; import server.MerchItemPackage; import server.stores.AbstractPlayerStore.BoughtItem; import server.stores.HiredMerchant; import server.stores.IMaplePlayerShop; import server.stores.MapleMiniGame; import server.stores.MaplePlayerShop; import server.stores.MaplePlayerShopItem; import tools.Pair; import tools.data.MaplePacketLittleEndianWriter; public class PlayerShopPacket { public static byte[] sendTitleBox() { return sendTitleBox(7); // SendOpenShopRequest } public static byte[] sendTitleBox(int mode) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(8); mplew.writeShort(SendPacketOpcode.SEND_TITLE_BOX.getValue()); mplew.write(mode); if ((mode == 8) || (mode == 16)) { mplew.writeInt(0); mplew.write(0); } else if (mode == 13) { mplew.writeInt(0); } else if (mode == 14) { mplew.write(0); } else if (mode == 18) { mplew.write(1); mplew.writeMapleAsciiString(""); } return mplew.getPacket(); } public static byte[] requestShopPic(final int oid) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(17); mplew.writeShort(SendPacketOpcode.SEND_TITLE_BOX.getValue()); mplew.write(17); mplew.writeInt(oid); mplew.writeShort(0); mplew.writeLong(0L); return mplew.getPacket(); } public static final byte[] addCharBox(final MapleCharacter c, final int type) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.UPDATE_CHAR_BOX.getValue()); mplew.writeInt(c.getId()); PacketHelper.addAnnounceBox(mplew, c); return mplew.getPacket(); } public static final byte[] removeCharBox(final MapleCharacter c) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.UPDATE_CHAR_BOX.getValue()); mplew.writeInt(c.getId()); mplew.write(0); return mplew.getPacket(); } public static final byte[] sendPlayerShopBox(final MapleCharacter c) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.UPDATE_CHAR_BOX.getValue()); mplew.writeInt(c.getId()); PacketHelper.addAnnounceBox(mplew, c); return mplew.getPacket(); } public static byte[] getHiredMerch(MapleCharacter chr, HiredMerchant merch, boolean firstTime) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(20);//was11 mplew.write(6); mplew.write(7); mplew.writeShort(merch.getVisitorSlot(chr)); mplew.writeInt(merch.getItemId()); mplew.writeMapleAsciiString("Hired Merchant"); for (Pair storechr : merch.getVisitors()) { mplew.write(((Byte) storechr.left).byteValue()); PacketHelper.addCharLook(mplew, (MapleCharacterLook) storechr.right, false, false); mplew.writeMapleAsciiString(((MapleCharacter) storechr.right).getName()); mplew.writeShort(((MapleCharacter) storechr.right).getJob()); } mplew.write(-1); mplew.writeShort(0); mplew.writeMapleAsciiString(merch.getOwnerName()); if (merch.isOwner(chr)) { mplew.writeInt(merch.getTimeLeft()); mplew.write(firstTime ? 1 : 0); mplew.write(merch.getBoughtItems().size()); for (final BoughtItem SoldItem : merch.getBoughtItems()) { mplew.writeInt(SoldItem.id); mplew.writeShort(SoldItem.quantity); mplew.writeLong(SoldItem.totalPrice); mplew.writeMapleAsciiString(SoldItem.buyer); } mplew.writeLong(merch.getMeso()); } mplew.writeInt(263); mplew.writeMapleAsciiString(merch.getDescription()); mplew.write(16); mplew.writeLong(merch.getMeso()); mplew.write(merch.getItems().size()); for (MaplePlayerShopItem item : merch.getItems()) { mplew.writeShort(item.bundles); mplew.writeShort(item.item.getQuantity()); mplew.writeLong(item.price); PacketHelper.addItemInfo(mplew, item.item); } mplew.writeShort(0); return mplew.getPacket(); } public static final byte[] getPlayerStore(final MapleCharacter chr, final boolean firstTime) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); IMaplePlayerShop ips = chr.getPlayerShop(); mplew.write(GameConstants.GMS ? 11 : 5); switch (ips.getShopType()) { case 2: mplew.write(4); mplew.write(4); break; case 3: mplew.write(2); mplew.write(2); break; case 4: mplew.write(1); mplew.write(2); break; } mplew.writeShort(ips.getVisitorSlot(chr)); PacketHelper.addCharLook(mplew, ((MaplePlayerShop) ips).getMCOwner(), false, false); mplew.writeMapleAsciiString(ips.getOwnerName()); mplew.writeShort(((MaplePlayerShop) ips).getMCOwner().getJob()); for (final Pair<Byte, MapleCharacter> storechr : ips.getVisitors()) { mplew.write(storechr.left); PacketHelper.addCharLook(mplew, storechr.right, false, false); mplew.writeMapleAsciiString(storechr.right.getName()); mplew.writeShort(storechr.right.getJob()); } mplew.write(255); mplew.writeMapleAsciiString(ips.getDescription()); mplew.write(10); mplew.write(ips.getItems().size()); for (final MaplePlayerShopItem item : ips.getItems()) { mplew.writeShort(item.bundles); mplew.writeShort(item.item.getQuantity()); mplew.writeInt(item.price); PacketHelper.addItemInfo(mplew, item.item); } return mplew.getPacket(); } public static final byte[] shopChat(final String message, final int slot) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(24);//was15 mplew.write(25);//was15 mplew.write(slot); mplew.writeMapleAsciiString(message); return mplew.getPacket(); } public static final byte[] shopErrorMessage(final int error, final int type) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(GameConstants.GMS ? 28 : 10);//was18 mplew.write(type); mplew.write(error); return mplew.getPacket(); } public static final byte[] spawnHiredMerchant(final HiredMerchant hm) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.SPAWN_HIRED_MERCHANT.getValue()); mplew.writeInt(hm.getOwnerId()); mplew.writeInt(hm.getItemId()); mplew.writePos(hm.getTruePosition()); mplew.writeShort(0); mplew.writeMapleAsciiString(hm.getOwnerName()); PacketHelper.addInteraction(mplew, hm); // System.err.println(hm.getItemId()); return mplew.getPacket(); } public static final byte[] destroyHiredMerchant(final int id) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.DESTROY_HIRED_MERCHANT.getValue()); mplew.writeInt(id); return mplew.getPacket(); } public static final byte[] shopItemUpdate(final IMaplePlayerShop shop) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(77);//was50 if (shop.getShopType() == 1) { mplew.writeLong(0L); } mplew.write(shop.getItems().size()); for (final MaplePlayerShopItem item : shop.getItems()) { mplew.writeShort(item.bundles); mplew.writeShort(item.item.getQuantity()); mplew.writeLong(item.price); PacketHelper.addItemInfo(mplew, item.item); } mplew.writeShort(0); return mplew.getPacket(); } public static final byte[] shopVisitorAdd(final MapleCharacter chr, final int slot) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(PlayerInteractionHandler.Interaction.VISIT.action); // mplew.write(19);//was10 mplew.write(slot); PacketHelper.addCharLook(mplew, chr, false, false); mplew.writeMapleAsciiString(chr.getName()); mplew.writeShort(chr.getJob()); return mplew.getPacket(); } public static final byte[] shopVisitorLeave(final byte slot) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(19); mplew.write(slot); return mplew.getPacket(); } public static final byte[] Merchant_Buy_Error(final byte message) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); // 2 = You have not enough meso mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(44); mplew.write(message); return mplew.getPacket(); } public static final byte[] updateHiredMerchant(final HiredMerchant shop) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.UPDATE_HIRED_MERCHANT.getValue()); mplew.writeInt(shop.getOwnerId()); PacketHelper.addInteraction(mplew, shop); return mplew.getPacket(); } public static final byte[] merchItem_Message(final int op) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.MERCH_ITEM_MSG.getValue()); mplew.write(op); return mplew.getPacket(); } public static final byte[] merchItemStore(final byte op, final int days, final int fees) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); // 40: This is currently unavailable.\r\nPlease try again later mplew.writeShort(SendPacketOpcode.MERCH_ITEM_STORE.getValue()); mplew.write(op); switch (op) { case 39: mplew.writeInt(999999999); // ? mplew.writeInt(999999999); // mapid mplew.write(0); // >= -2 channel // if cc -1 or map = 999,999,999 : I don't think you have any items or money to retrieve here. This is where you retrieve the items and mesos that you couldn't get from your Hired Merchant. You'll also need to see me as the character that opened the Personal Store. //Your Personal Store is open #bin Channel %s, Free Market %d#k.\r\nIf you need me, then please close your personal store first before seeing me. break; case 38: mplew.writeInt(days); // % tax or days, 1 day = 1% mplew.writeInt(fees); // feees break; } return mplew.getPacket(); } public static final byte[] merchItemStore_ItemData(final MerchItemPackage pack) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.MERCH_ITEM_STORE.getValue()); mplew.write(38); mplew.writeInt(9030000); // Fredrick mplew.write(16); // max items? mplew.writeLong(126L); // ? mplew.writeLong(pack.getMesos()); mplew.write(0); mplew.write(pack.getItems().size()); for (final Item item : pack.getItems()) { PacketHelper.addItemInfo(mplew, item); } mplew.writeZeroBytes(3); return mplew.getPacket(); } public static byte[] getMiniGame(MapleClient c, MapleMiniGame minigame) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(10); mplew.write(minigame.getGameType()); mplew.write(minigame.getMaxSize()); mplew.writeShort(minigame.getVisitorSlot(c.getPlayer())); PacketHelper.addCharLook(mplew, minigame.getMCOwner(), false, false); mplew.writeMapleAsciiString(minigame.getOwnerName()); mplew.writeShort(minigame.getMCOwner().getJob()); for (Pair visitorz : minigame.getVisitors()) { mplew.write(((Byte) visitorz.getLeft()).byteValue()); PacketHelper.addCharLook(mplew, (MapleCharacterLook) visitorz.getRight(), false, false); mplew.writeMapleAsciiString(((MapleCharacter) visitorz.getRight()).getName()); mplew.writeShort(((MapleCharacter) visitorz.getRight()).getJob()); } mplew.write(-1); mplew.write(0); addGameInfo(mplew, minigame.getMCOwner(), minigame); for (Pair visitorz : minigame.getVisitors()) { mplew.write(((Byte) visitorz.getLeft()).byteValue()); addGameInfo(mplew, (MapleCharacter) visitorz.getRight(), minigame); } mplew.write(-1); mplew.writeMapleAsciiString(minigame.getDescription()); mplew.writeShort(minigame.getPieceType()); return mplew.getPacket(); } public static byte[] getMiniGameReady(boolean ready) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(ready ? 56 : GameConstants.GMS ? 60 : ready ? 59 : 57); return mplew.getPacket(); } public static byte[] getMiniGameExitAfter(boolean ready) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(ready ? 54 : GameConstants.GMS ? 58 : ready ? 57 : 55); return mplew.getPacket(); } public static byte[] getMiniGameStart(int loser) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(GameConstants.GMS ? 62 : 59); mplew.write(loser == 1 ? 0 : 1); return mplew.getPacket(); } public static byte[] getMiniGameSkip(int slot) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(GameConstants.GMS ? 64 : 61); mplew.write(slot); return mplew.getPacket(); } public static byte[] getMiniGameRequestTie() { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(GameConstants.GMS ? 51 : 48); return mplew.getPacket(); } public static byte[] getMiniGameDenyTie() { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(GameConstants.GMS ? 50 : 49); return mplew.getPacket(); } public static byte[] getMiniGameFull() { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.writeShort(GameConstants.GMS ? 10 : 5); mplew.write(2); return mplew.getPacket(); } public static byte[] getMiniGameMoveOmok(int move1, int move2, int move3) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(GameConstants.GMS ? 65 : 62); mplew.writeInt(move1); mplew.writeInt(move2); mplew.write(move3); return mplew.getPacket(); } public static byte[] getMiniGameNewVisitor(MapleCharacter c, int slot, MapleMiniGame game) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(GameConstants.GMS ? 9 : 4); mplew.write(slot); PacketHelper.addCharLook(mplew, c, false, false); mplew.writeMapleAsciiString(c.getName()); mplew.writeShort(c.getJob()); addGameInfo(mplew, c, game); return mplew.getPacket(); } public static void addGameInfo(MaplePacketLittleEndianWriter mplew, MapleCharacter chr, MapleMiniGame game) { mplew.writeInt(game.getGameType()); mplew.writeInt(game.getWins(chr)); mplew.writeInt(game.getTies(chr)); mplew.writeInt(game.getLosses(chr)); mplew.writeInt(game.getScore(chr)); } public static byte[] getMiniGameClose(byte number) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(GameConstants.GMS ? 18 : 10); mplew.write(1); mplew.write(number); return mplew.getPacket(); } public static byte[] getMatchCardStart(MapleMiniGame game, int loser) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(GameConstants.GMS ? 62 : 59); mplew.write(loser == 1 ? 0 : 1); int times = game.getPieceType() == 2 ? 30 : game.getPieceType() == 1 ? 20 : 12; mplew.write(times); for (int i = 1; i <= times; i++) { mplew.writeInt(game.getCardId(i)); } return mplew.getPacket(); } public static byte[] getMatchCardSelect(int turn, int slot, int firstslot, int type) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(GameConstants.GMS ? 69 : 66); mplew.write(turn); mplew.write(slot); if (turn == 0) { mplew.write(firstslot); mplew.write(type); } return mplew.getPacket(); } public static byte[] getMiniGameResult(MapleMiniGame game, int type, int x) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(GameConstants.GMS ? 63 : 60); mplew.write(type); game.setPoints(x, type); if (type != 0) { game.setPoints(x == 1 ? 0 : 1, type == 2 ? 0 : 1); } if (type != 1) { if (type == 0) { mplew.write(x == 1 ? 0 : 1); } else { mplew.write(x); } } addGameInfo(mplew, game.getMCOwner(), game); for (Pair visitorz : game.getVisitors()) { addGameInfo(mplew, (MapleCharacter) visitorz.right, game); } return mplew.getPacket(); } public static final byte[] MerchantBlackListView(final List<String> blackList) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(39); mplew.writeShort(blackList.size()); for (String visit : blackList) { mplew.writeMapleAsciiString(visit); } return mplew.getPacket(); } public static final byte[] MerchantVisitorView(List<String> visitor) { final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.writeShort(SendPacketOpcode.PLAYER_INTERACTION.getValue()); mplew.write(38); mplew.writeShort(visitor.size()); for (String visit : visitor) { mplew.writeMapleAsciiString(visit); mplew.writeInt(1); } return mplew.getPacket(); } }