P1ckw1ck 158 Опубликовано 23 марта, 2016 Не подскажете где находится метод/пакет обмена вещей через exc_multisell Сделал ап тотемов но мультисел не открывается. когда в нем присутствуют Pc очки. <!-- 2 ур тотемы --> <item id="1"> <production id="9308" count="1"/> <ingredient id="9300" count="1"/> <ingredient id="9501" count="600"/> <ingredient id="65436" count="800"/> Если я удаляю строку с ингредиентом Pc очков то. мультисел открывается нормально и апает тотем. гс пишет Bad RequestBypassToServer: null Я видать не сделал реализацию pc очей в exc_multisell. Интересует в каком классе находится данный метод/пакет. </item> Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
LifeGame32 312 Опубликовано 23 марта, 2016 Не подскажете где находится метод/пакет обмена вещей через exc_multisell Сделал ап тотемов но мультисел не открывается. когда в нем присутствуют Pc очки. <!-- 2 ур тотемы --> <item id="1"> <production id="9308" count="1"/> <ingredient id="9300" count="1"/> <ingredient id="9501" count="600"/> <ingredient id="65436" count="800"/> Если я удаляю строку с ингредиентом Pc очков то. мультисел открывается нормально и апает тотем. гс пишет Bad RequestBypassToServer: null Я видать не сделал реализацию pc очей в exc_multisell. Интересует в каком классе находится данный метод/пакет. </item> сдается ид pc "-100" exc_multisell должно быть там же где multisell. в handlers Multisell.java Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
l2inplay 29 Опубликовано 23 марта, 2016 А под какую сборку тебе нужно? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
P1ckw1ck 158 Опубликовано 23 марта, 2016 Ацис Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
P1ckw1ck 158 Опубликовано 23 марта, 2016 сдается ид pc "-100" exc_multisell должно быть там же где multisell. в handlers Multisell.java У меня через 65436 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
l2inplay 29 Опубликовано 23 марта, 2016 У меня через 65436 В ядре за все эти чудеса отвечает MultiSellList и MultisellData, но опять же смотря чье ядро Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
P1ckw1ck 158 Опубликовано 24 марта, 2016 Вот 2 пакета с реализацией Pc очей. подскажите где я упустил что-то. MultisellList.java /* * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * 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 General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see <http://www.gnu.org/licenses/>. */ package net.sf.l2j.gameserver.network.serverpackets; import net.sf.l2j.gameserver.datatables.ItemTable; import net.sf.l2j.gameserver.model.item.kind.Item; import net.sf.l2j.gameserver.model.multisell.Entry; import net.sf.l2j.gameserver.model.multisell.Ingredient; import net.sf.l2j.gameserver.model.multisell.ListContainer; public class MultiSellList extends L2GameServerPacket { protected int _listId, _page, _finished; protected ListContainer _list; public MultiSellList(ListContainer list, int page, int finished) { _list = list; _listId = list.getListId(); _page = page; _finished = finished; } @Override protected void writeImpl() { writeC(0xd0); writeD(_listId); // list id writeD(_page); // page writeD(_finished); // finished writeD(0x28); // size of pages writeD(_list == null ? 0 : _list.getEntries().size()); // list lenght if (_list != null) { for (Entry ent : _list.getEntries()) { writeD(ent.getEntryId()); writeD(0x00); // C6 writeD(0x00); // C6 writeC(1); writeH(ent.getProducts().size()); writeH(ent.getIngredients().size()); for (Ingredient i : ent.getProducts()) { Item item = ItemTable.getInstance().getTemplate(i.getItemId()); writeH(i.getItemId()); writeD(item.getBodyPart()); writeH(item.getType2()); writeD(i.getItemCount()); writeH(i.getEnchantmentLevel()); writeD(0x00); // TODO: i.getAugmentId() writeD(0x00); // TODO: i.getManaLeft() } for (Ingredient i : ent.getIngredients()) { int items = i.getItemId(); int typeE = 65535; if (items != 65336 && items < 65436 ) typeE = ItemTable.getInstance().getTemplate(i.getItemId()).getType2(); writeH(items); //ID writeH(typeE); writeD(i.getItemCount()); //Count writeH(i.getEnchantmentLevel()); //Enchant Level writeD(0x00); // C6 writeD(0x00); // C6 } } } } } MultiSellChoose.java /* * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * 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 General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see <http://www.gnu.org/licenses/>. */ package net.sf.l2j.gameserver.network.clientpackets; import java.util.ArrayList; import java.util.List; import net.sf.l2j.Config; import net.sf.l2j.gameserver.datatables.ItemTable; import net.sf.l2j.gameserver.datatables.MultisellData; import net.sf.l2j.gameserver.model.L2Augmentation; import net.sf.l2j.gameserver.model.actor.L2Npc; import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance; import net.sf.l2j.gameserver.model.item.instance.ItemInstance; import net.sf.l2j.gameserver.model.item.kind.Armor; import net.sf.l2j.gameserver.model.item.kind.Item; import net.sf.l2j.gameserver.model.item.kind.Weapon; import net.sf.l2j.gameserver.model.itemcontainer.PcInventory; import net.sf.l2j.gameserver.model.multisell.Entry; import net.sf.l2j.gameserver.model.multisell.Ingredient; import net.sf.l2j.gameserver.model.multisell.ListContainer; import net.sf.l2j.gameserver.network.SystemMessageId; import net.sf.l2j.gameserver.network.serverpackets.ItemList; import net.sf.l2j.gameserver.network.serverpackets.StatusUpdate; import net.sf.l2j.gameserver.network.serverpackets.SystemMessage; import net.sf.l2j.gameserver.util.FloodProtectors; import net.sf.l2j.gameserver.util.FloodProtectors.Action; public class MultiSellChoose extends L2GameClientPacket { private int _listId; private int _entryId; private int _amount; private int _enchantment; private int _transactionTax; // local handling of taxation @Override protected void readImpl() { _listId = readD(); _entryId = readD(); _amount = readD(); _enchantment = _entryId % 100000; _entryId = _entryId / 100000; _transactionTax = 0; } @Override public void runImpl() { if (!FloodProtectors.performAction(getClient(), Action.MULTISELL)) return; final L2PcInstance player = getClient().getActiveChar(); if (player == null) return; if (_amount < 1 || _amount > 9999) return; // Verify first if the player can interact with the trader. L2Npc merchant = (player.getTarget() instanceof L2Npc) ? (L2Npc) player.getTarget() : null; if (merchant == null || !merchant.canInteract(player)) return; ListContainer list = MultisellData.getInstance().getList(_listId); if (list == null) return; for (Entry entry : list.getEntries()) { if (entry.getEntryId() == _entryId) { doExchange(player, merchant, entry, list.getApplyTaxes(), list.getMaintainEnchantment(), _enchantment); return; } } } private void doExchange(L2PcInstance player, L2Npc merchant, Entry templateEntry, boolean applyTaxes, boolean maintainEnchantment, int enchantment) { final PcInventory inv = player.getInventory(); Entry entry = prepareEntry(merchant, templateEntry, applyTaxes, maintainEnchantment, enchantment); /** * Checks if the amount to purchase is exceeding the inventory slots or weight limit and returns a message to the player. */ int slots = 0; int weight = 0; for (Ingredient e : entry.getProducts()) { int id = e.getItemId(); if (id < 0) continue; Item template = ItemTable.getInstance().getTemplate(id); if (template == null) continue; if (!template.isStackable()) slots += e.getItemCount() * _amount; else if (player.getInventory().getItemByItemId(id) == null) slots++; weight += e.getItemCount() * _amount * template.getWeight(); } if (!inv.validateWeight(weight)) { player.sendPacket(SystemMessageId.WEIGHT_LIMIT_EXCEEDED); return; } if (!inv.validateCapacity(slots)) { player.sendPacket(SystemMessageId.SLOTS_FULL); return; } // Generate a list of distinct ingredients and counts in order to check if the correct item-counts // are possessed by the player List<Ingredient> _ingredientsList = new ArrayList<>(); boolean newIng = true; for (Ingredient e : entry.getIngredients()) { newIng = true; // at this point, the template has already been modified so that enchantments are properly included // whenever they need to be applied. Uniqueness of items is thus judged by item id AND enchantment level for (Ingredient ex : _ingredientsList) { // if the item was already added in the list, merely increment the count // this happens if 1 list entry has the same ingredient twice (example 2 swords = 1 dual) if ((ex.getItemId() == e.getItemId()) && (ex.getEnchantmentLevel() == e.getEnchantmentLevel())) { if ((double) ex.getItemCount() + e.getItemCount() > Integer.MAX_VALUE) { player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_QUANTITY_THAT_CAN_BE_INPUTTED); _ingredientsList.clear(); _ingredientsList = null; return; } ex.setItemCount(ex.getItemCount() + e.getItemCount()); newIng = false; } } // if it's a new ingredient, just store its info directly (item id, count, enchantment) if (newIng) _ingredientsList.add(new Ingredient(e)); } // now check if the player has sufficient items in the inventory to cover the ingredients' expences for (Ingredient e : _ingredientsList) { if ((double) e.getItemCount() * _amount > Integer.MAX_VALUE) { player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_QUANTITY_THAT_CAN_BE_INPUTTED); _ingredientsList.clear(); _ingredientsList = null; return; } //if (e.getItemId() == 65436 && e.getItemCount() * _amount > player.getPcBangScore()) //{ //player.sendPacket(SystemMessageId.NOT_ENOUGH_ITEMS); //return; //} else if (e.getItemId() != 65336) { if (e.getItemId() == 65436) { if (player.getPcBangScore() < (e.getItemCount() * _amount)) { player.sendMessage("Не достаточно Очков Фракции."); return; } } else // if this is not a list that maintains enchantment, check the count of all items that have the given id. // otherwise, check only the count of items with exactly the needed enchantment level if (inv.getInventoryItemCount(e.getItemId(), maintainEnchantment ? e.getEnchantmentLevel() : -1) < ((Config.ALT_BLACKSMITH_USE_RECIPES || !e.getMaintainIngredient()) ? (e.getItemCount() * _amount) : e.getItemCount())) { player.sendPacket(SystemMessageId.NOT_ENOUGH_ITEMS); _ingredientsList.clear(); _ingredientsList = null; return; } } else { if (player.getClan() == null) { player.sendPacket(SystemMessageId.YOU_ARE_NOT_A_CLAN_MEMBER); return; } if (!player.isClanLeader()) { player.sendPacket(SystemMessageId.ONLY_THE_CLAN_LEADER_IS_ENABLED); return; } if (player.getClan().getReputationScore() < (e.getItemCount() * _amount)) { player.sendPacket(SystemMessageId.THE_CLAN_REPUTATION_SCORE_IS_TOO_LOW); return; } } } _ingredientsList.clear(); _ingredientsList = null; List<L2Augmentation> augmentation = new ArrayList<>(); // All ok, send success message, remove items and add final product player.sendPacket(SystemMessageId.SUCCESSFULLY_TRADED_WITH_NPC); for (Ingredient e : entry.getIngredients()) { if (e.getItemId() != 65336) { if (e.getItemId() == 65436) { player.reducePcBangScore(e.getItemCount() * _amount); SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.USING_S1_PCPOINT); sm.addNumber(e.getItemCount()); player.sendPacket(sm); } else { ItemInstance itemToTake = inv.getItemByItemId(e.getItemId()); if (itemToTake == null) { // this is a cheat, transaction will be aborted _log.severe(player.getName() + " is trying to cheat using multisell, merchant id: " + merchant.getNpcId()); return; } if (Config.ALT_BLACKSMITH_USE_RECIPES || !e.getMaintainIngredient()) { // if it's a stackable item, just reduce the amount from the first (only) instance that is found in the inventory if (itemToTake.isStackable()) { if (!player.destroyItem("Multisell", itemToTake.getObjectId(), (e.getItemCount() * _amount), player.getTarget(), true)) return; } else { // for non-stackable items, one of two scenaria are possible: // a) list maintains enchantment: get the instances that exactly match the requested enchantment level // list does not maintain enchantment: get the instances with the LOWEST enchantment level // a) if enchantment is maintained, then get a list of items that exactly match this enchantment if (maintainEnchantment) { // loop through this list and remove (one by one) each item until the required amount is taken. ItemInstance[] inventoryContents = inv.getAllItemsByItemId(e.getItemId(), e.getEnchantmentLevel()); for (int i = 0; i < (e.getItemCount() * _amount); i++) { if (inventoryContents[i].isAugmented()) augmentation.add(inventoryContents[i].getAugmentation()); if (!player.destroyItem("Multisell", inventoryContents[i].getObjectId(), 1, player.getTarget(), true)) return; } } else // enchantment is not maintained. Get the instances with the LOWEST enchantment level { for (int i = 1; i <= (e.getItemCount() * _amount); i++) { ItemInstance[] inventoryContents = inv.getAllItemsByItemId(e.getItemId()); itemToTake = inventoryContents[0]; // get item with the LOWEST enchantment level from the inventory (0 is the lowest) if (itemToTake.getEnchantLevel() > 0) { for (ItemInstance item : inventoryContents) { if (item.getEnchantLevel() < itemToTake.getEnchantLevel()) { itemToTake = item; // nothing will have enchantment less than 0. If a zero-enchanted // item is found, just take it if (itemToTake.getEnchantLevel() == 0) break; } } } if (!player.destroyItem("Multisell", itemToTake.getObjectId(), 1, player.getTarget(), true)) return; } } } } } } else { int totalReputation = e.getItemCount() * _amount; player.getClan().takeReputationScore(totalReputation); player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.S1_DEDUCTED_FROM_CLAN_REP).addNumber(totalReputation)); } } // Generate the appropriate items for (Ingredient e : entry.getProducts()) { if (ItemTable.getInstance().createDummyItem(e.getItemId()).isStackable()) inv.addItem("Multisell", e.getItemId(), (e.getItemCount() * _amount), player, player.getTarget()); else { for (int i = 0; i < (e.getItemCount() * _amount); i++) { ItemInstance product = inv.addItem("Multisell", e.getItemId(), 1, player, player.getTarget()); if (product == null) continue; if (maintainEnchantment) { if (i < augmentation.size()) product.setAugmentation(new L2Augmentation(augmentation.get(i).getAugmentationId(), augmentation.get(i).getSkill())); product.setEnchantLevel(e.getEnchantmentLevel()); } } } // msg part SystemMessage sm; if (e.getItemCount() * _amount > 1) { sm = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S2_S1_S); sm.addItemName(e.getItemId()); sm.addNumber(e.getItemCount() * _amount); player.sendPacket(sm); } else { if (maintainEnchantment && _enchantment > 0) { sm = SystemMessage.getSystemMessage(SystemMessageId.ACQUIRED_S1_S2); sm.addNumber(_enchantment); sm.addItemName(e.getItemId()); } else { sm = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1); sm.addItemName(e.getItemId()); } player.sendPacket(sm); } } player.sendPacket(new ItemList(player, false)); StatusUpdate su = new StatusUpdate(player); su.addAttribute(StatusUpdate.CUR_LOAD, player.getCurrentLoad()); player.sendPacket(su); // finally, give the tax to the castle... if (merchant != null && merchant.getIsInTown() && merchant.getCastle().getOwnerId() > 0) merchant.getCastle().addToTreasury(_transactionTax * _amount); } // Regarding taxation, the following appears to be the case: // a) The count of aa remains unchanged (taxes do not affect aa directly). // 5/6 of the amount of aa is taxed by the normal tax rate. // c) the resulting taxes are added as normal adena value. // d) normal adena are taxed fully. // e) Items other than adena and ancient adena are not taxed even when the list is taxable. // example: If the template has an item worth 120aa, and the tax is 10%, // then from 120aa, take 5/6 so that is 100aa, apply the 10% tax in adena (10a) // so the final price will be 120aa and 10a! private Entry prepareEntry(L2Npc merchant, Entry templateEntry, boolean applyTaxes, boolean maintainEnchantment, int enchantLevel) { Entry newEntry = new Entry(); newEntry.setEntryId(templateEntry.getEntryId()); int totalAdenaCount = 0; boolean hasIngredient = false; for (Ingredient ing : templateEntry.getIngredients()) { // load the ingredient from the template Ingredient newIngredient = new Ingredient(ing); if (newIngredient.getItemId() == 57 && newIngredient.isTaxIngredient()) { double taxRate = 0.0; if (applyTaxes) { if (merchant != null && merchant.getIsInTown()) taxRate = merchant.getCastle().getTaxRate(); } _transactionTax = (int) Math.round(newIngredient.getItemCount() * taxRate); totalAdenaCount += _transactionTax; continue; // do not yet add this adena amount to the list as non-taxIngredient adena might be entered later (order not guaranteed) } else if (ing.getItemId() == 57) // && !ing.isTaxIngredient() { totalAdenaCount += newIngredient.getItemCount(); continue; // do not yet add this adena amount to the list as taxIngredient adena might be entered later (order not guaranteed) } // if it is an armor/weapon, modify the enchantment level appropriately, if necessary else if (maintainEnchantment && newIngredient.getItemId() > 0) { Item tempItem = ItemTable.getInstance().createDummyItem(newIngredient.getItemId()).getItem(); if ((tempItem instanceof Armor) || (tempItem instanceof Weapon)) { newIngredient.setEnchantmentLevel(enchantLevel); hasIngredient = true; } } // finally, add this ingredient to the entry newEntry.addIngredient(newIngredient); } // Next add the adena amount, if any if (totalAdenaCount > 0) newEntry.addIngredient(new Ingredient(57, totalAdenaCount, false, false)); // Now modify the enchantment level of products, if necessary for (Ingredient ing : templateEntry.getProducts()) { // load the ingredient from the template Ingredient newIngredient = new Ingredient(ing); if (maintainEnchantment && hasIngredient) { // if it is an armor/weapon, modify the enchantment level appropriately // (note, if maintain enchantment is "false" this modification will result to a +0) Item tempItem = ItemTable.getInstance().createDummyItem(newIngredient.getItemId()).getItem(); if ((tempItem instanceof Armor) || (tempItem instanceof Weapon)) newIngredient.setEnchantmentLevel(enchantLevel); } newEntry.addProduct(newIngredient); } return newEntry; } } Буду от всей души Благодарен. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
ncsSpawN 45 Опубликовано 24 марта, 2016 найти где на каком месте идет передача null и почему. Заключите это место в: try{ ..... }catch(Exception e) { e.printStackTrace(); } И посмотрите лог ошибки. Взять к примеру исходник Scoria: com.l2scoria.gameserver.network.clientpackets.MultiSellChoose com.l2scoria.gameserver.network.serverpackets.MultiSellList И посмотреть пример. Ид 65436 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
P1ckw1ck 158 Опубликовано 24 марта, 2016 найти где на каком месте идет передача null и почему. Заключите это место в: try{ ..... }catch(Exception e) { e.printStackTrace(); } И посмотрите лог ошибки. Взять к примеру исходник Scoria: com.l2scoria.gameserver.network.clientpackets.MultiSellChoose com.l2scoria.gameserver.network.serverpackets.MultiSellList И посмотреть пример. Ид 65436 Спасибо, но я не такой гений в яве как вы. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
ncsSpawN 45 Опубликовано 24 марта, 2016 Спасибо, но я не такой гений в яве как вы.Да тут не нужно быть гением, главное только понимать синтакс java. А всю информацию оно само напишет. 1 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
P1ckw1ck 158 Опубликовано 24 марта, 2016 спасибо, буду ражать. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты