package tools.packet; import client.MapleClient; import client.inventory.Item; import client.inventory.MapleInventoryType; import handling.SendPacketOpcode; import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.log4j.Logger; import server.ServerProperties; import server.life.MapleNPC; import server.life.PlayerNPC; import server.shop.MapleShop; import server.shop.MapleShopResponse; import tools.FileoutputUtil; import tools.HexTool; import tools.Pair; import tools.data.output.MaplePacketLittleEndianWriter; public class NPCPacket { private static final Logger log = Logger.getLogger(NPCPacket.class); /** * 召唤NPC * @param life * @param show * @return */ public static byte[] spawnNPC(MapleNPC life, boolean show) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.SPAWN_NPC.getValue()); mplew.writeInt(life.getObjectId()); mplew.writeInt(life.getId()); baseNPC(mplew,life); return mplew.getPacket(); } public static void baseNPC(MaplePacketLittleEndianWriter mplew,MapleNPC life){ mplew.writeShort(life.getPosition().x); mplew.writeShort(life.getCy()); mplew.write(life.getF() == 1 ? 0 : 1); mplew.writeShort(life.getFh()); mplew.writeShort(life.getRx0()); mplew.writeShort(life.getRx1()); } public static byte[] removeNPC(int objectid) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.REMOVE_NPC.getValue()); mplew.writeInt(objectid); return mplew.getPacket(); } public static byte[] removeNPCController(int objectid) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.SPAWN_NPC_REQUEST_CONTROLLER.getValue()); mplew.write(0); mplew.writeInt(objectid); return mplew.getPacket(); } /** * 请求控制NPC * @param life * @param MiniMap * @return */ public static byte[] spawnNPCRequestController(MapleNPC life, boolean MiniMap) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.SPAWN_NPC_REQUEST_CONTROLLER.getValue()); mplew.write(1); mplew.writeInt(life.getObjectId()); mplew.writeInt(life.getId()); baseNPC(mplew,life); return mplew.getPacket(); } public static byte[] setNPCSpecialAction(int oid, String action) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.NPC_SET_SPECIAL_ACTION.getValue()); mplew.writeInt(oid); mplew.writeMapleAsciiString(action); mplew.writeInt(0); //unknown yet mplew.write(0); //unknown yet return mplew.getPacket(); } public static byte[] NPCSpecialAction(MapleNPC life) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.NPC_ACTION.getValue()); mplew.writeInt(life.getObjectId()); mplew.writeShort(-1); mplew.writeInt(0); mplew.writeInt(0); mplew.writeShort(life.getPosition().x); mplew.writeShort(life.getPosition().y); mplew.writeInt(0); mplew.writeShort(1); mplew.writeShort(life.getPosition().x); mplew.writeShort(life.getPosition().y); mplew.writeShort(0); mplew.writeShort(0); mplew.writeShort(life.getFh()); mplew.writeInt(0); mplew.write(5); mplew.write(0x38); mplew.write(4); return mplew.getPacket(); } public static byte[] NPCSpecialAction(int npc, String code) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.NPC_ACTION.getValue()); mplew.writeInt(npc); mplew.write(HexTool.getByteArrayFromHexString(code)); return mplew.getPacket(); } public static byte[] spawnPlayerNPC(PlayerNPC npc) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.PLAYER_NPC.getValue()); mplew.write(npc.getF() == 1 ? 0 : 1); mplew.writeInt(npc.getId()); mplew.writeMapleAsciiString(npc.getName()); mplew.write(npc.getGender()); mplew.write(npc.getSkin()); mplew.writeInt(npc.getFace()); mplew.writeInt(0); mplew.write(0); mplew.writeInt(npc.getHair()); Map<Byte, Integer> equip = npc.getEquips(); Map<Byte, Integer> myEquip = new LinkedHashMap(); Map<Byte, Integer> maskedEquip = new LinkedHashMap(); for (Entry<Byte, Integer> position : equip.entrySet()) { byte pos = (byte) ((position.getKey()) * -1); if ((pos < 100) && (myEquip.get(pos) == null)) { myEquip.put(pos, position.getValue()); } else if ((pos > 100) && (pos != 111)) { pos = (byte) (pos - 100); if (myEquip.get(pos) != null) { maskedEquip.put(pos, myEquip.get(pos)); } myEquip.put(pos, position.getValue()); } else if (myEquip.get(pos) != null) { maskedEquip.put(pos, position.getValue()); } } for (Map.Entry entry : myEquip.entrySet()) { mplew.write(((Byte) entry.getKey())); mplew.writeInt(((Integer) entry.getValue())); } mplew.write(255); for (Map.Entry entry : maskedEquip.entrySet()) { mplew.write(((Byte) entry.getKey())); mplew.writeInt(((Integer) entry.getValue())); } mplew.write(255); Integer cWeapon = equip.get(Byte.valueOf((byte) -111)); if (cWeapon != null) { mplew.writeInt(cWeapon); } else { mplew.writeInt(0); } for (int i = 0; i < 3; i++) { mplew.writeInt(npc.getPet(i)); } return mplew.getPacket(); } public static byte[] setNPCScriptable(List<Pair<Integer, String>> npcs) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.NPC_SCRIPTABLE.getValue()); mplew.write(npcs.size()); for (Pair s : npcs) { mplew.writeInt(((Integer) s.left)); mplew.writeMapleAsciiString((String) s.right); mplew.writeInt(0); mplew.writeInt(2147483647); } return mplew.getPacket(); } public static void baseScriptMan (MaplePacketLittleEndianWriter mplew,int npc,byte msgType) { mplew.write(SendPacketOpcode.NPC_TALK.getValue()); mplew.write(4); mplew.writeInt(npc); mplew.write(msgType); // 消息类型 } public static byte[] sendNPCSay(int npc,String talk) { return sendNPCSay(npc,talk,false,false); } /** * * @param npc * @param talk * @return */ public static byte[] sendChoose(int npc,String talk){ MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); baseScriptMan(mplew,npc,(byte)4); mplew.writeMapleAsciiString(talk); return mplew.getPacket(); } /** * NPC说话 * @param npc * @param talk * @param pre * @param next * @return */ public static byte[] sendNPCSay(int npc,String talk,boolean pre,boolean next) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); baseScriptMan(mplew,npc,(byte)0); mplew.writeMapleAsciiString(talk); if (pre) mplew.write(1); else mplew.write(0); if (next) mplew.write(1); else mplew.write(0); return mplew.getPacket(); } /** * NPC询问玩家做选择 * @param npc * @param talk * @return */ public static byte[] sendNPCAskYesNo(int npc,String talk) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); baseScriptMan(mplew,npc,(byte)1); mplew.writeMapleAsciiString(talk); return mplew.getPacket(); } /** * NPC显示询问文本 * @param npc * @param talk * @return */ public static byte[] sendNPCAskText(int npc,String talk) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); baseScriptMan(mplew,npc,(byte)2); mplew.writeMapleAsciiString(talk); mplew.writeMapleAsciiString("什么?"); // def mplew.writeShort(0); // min mplew.writeShort(0); // max return mplew.getPacket(); } /** * NPC显示数字 * @param npc * @param talk * @param def * @param min * @param max * @return */ public static byte[] sendNPCAskNumber(int npc,String talk,int def,int min,int max) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); baseScriptMan(mplew,npc,(byte)3); mplew.writeMapleAsciiString(talk); mplew.writeInt(def); mplew.writeInt(min); mplew.writeInt(max); return mplew.getPacket(); } /** * NPC显示菜单 * @param npc * @param talk * @return */ public static byte[] sendNPCAskMenu(int npc,String talk) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); baseScriptMan(mplew,npc,(byte)4); mplew.writeMapleAsciiString(talk); return mplew.getPacket(); } /** * NPC显示宠物信息 * @param npc * @param talk * @return */ public static byte[] sendNPCAskAvatar(int npc,String talk,int styles[]) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); baseScriptMan(mplew,npc,(byte)5); mplew.writeMapleAsciiString(talk); mplew.write(styles.length); for (int i = 0; i < styles.length; i++) { mplew.writeInt(styles[i]); } return mplew.getPacket(); } /** * NPC显示宠物信息 * @param npc * @param talk * @return */ public static byte[] sendNPCAskPet(int npc,String talk) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); baseScriptMan(mplew,npc,(byte)6); mplew.writeMapleAsciiString(talk); mplew.write(0); // 宠物个数 // mplew.writeLong(5000000); // sn // mplew.write(0); return mplew.getPacket(); } public static byte[] getNPCShop(int shopId, MapleShop shop, MapleClient c) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.OPEN_NPC_SHOP.getValue()); mplew.writeInt(shopId); PacketHelper.addShopInfo(mplew, shop, c); return mplew.getPacket(); } /** * 确认商店购买东西 * @param code * @param shop * @param c * @param indexBought * @return */ public static byte[] confirmShopTransaction(MapleShopResponse code, MapleShop shop, MapleClient c, int indexBought) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.CONFIRM_SHOP_TRANSACTION.getValue()); mplew.write(code.getValue()); return mplew.getPacket(); } /** * 发送仓库内的道具 * @param npcId * @param slots * @param items * @param meso * @return */ public static byte[] getStorage(int npcId, byte slots, Collection<Item> items, long meso) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.STORAGE_OPEN.getValue()); mplew.writeInt(npcId); mplew.write(slots); short flag = 0x7E; // 标记位 mplew.writeShort(flag); mplew.writeInt((int)meso); byte size[] = new byte[]{0,0,0,0,0,0}; for (Item item : items) { switch(item.getItemId() / 1000000) { case 1: size[1]++; break; case 2: size[2]++; break; case 3: size[3]++; break; case 4: size[4]++; break; case 5: size[5]++; break; default: FileoutputUtil.log("Unknown type found!"); break; } } for (int i=1;i<6;i++) { if (size[i] > 0) { mplew.write(size[i]); for (Item item : items) { if (item.getItemId() / 1000000 == i) { PacketHelper.addItemInfo(mplew, item, true); } } } else { mplew.write(0); } } return mplew.getPacket(); } /** * 仓库操作错误包 * @param op * @return */ public static byte[] getStorageError(byte op) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.STORAGE_OPERATION.getValue()); mplew.write(op); return mplew.getPacket(); } /** * 存钱 * @param slots * @param meso * @return */ public static byte[] mesoStorage(byte slots, long meso) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.STORAGE_OPERATION.getValue()); mplew.write(0xF); mplew.write(slots); mplew.writeShort(2); mplew.writeInt((int)meso); return mplew.getPacket(); } /** * 存放道具 * @param slots * @param type * @param items * @return */ public static byte[] storeStorage(byte slots, MapleInventoryType type, Collection<Item> items) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.STORAGE_OPERATION.getValue()); mplew.write(0xF); mplew.write(slots); mplew.writeShort(type.getBitfieldEncoding()); mplew.write(items.size()); for (Item item : items) { PacketHelper.addItemInfo(mplew, item,true); } return mplew.getPacket(); } /** * 从仓库取道具出来 * @param slots * @param type * @param items * @return */ public static byte[] takeOutStorage(byte slots, MapleInventoryType type, Collection<Item> items) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.STORAGE_OPERATION.getValue()); mplew.write(0x0F); mplew.write(slots); mplew.writeShort(type.getBitfieldEncoding()); mplew.write(items.size()); for (Item item : items) { PacketHelper.addItemInfo(mplew, item,true); } return mplew.getPacket(); } public static byte[] spawnNPCRequestController(int npc) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.SPAWN_NPC_REQUEST_CONTROLLER.getValue()); mplew.write(1); mplew.writeInt(npc); return mplew.getPacket(); } public static byte[] NPCSpecialAction(int oid, int value, int x, int y) { MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); mplew.write(SendPacketOpcode.NPC_UPDATE_LIMITED_INFO.getValue()); mplew.writeInt(oid); mplew.writeInt(value); mplew.writeInt(x); mplew.writeInt(y); return mplew.getPacket(); } }