Multisell related improvements.

This commit is contained in:
MobiusDevelopment 2019-08-06 12:41:01 +00:00
parent 35ff7f04de
commit 1c06645f6a
28 changed files with 958 additions and 1179 deletions

View File

@ -74,7 +74,7 @@ FloodProtectorServerBypassPunishmentType = none
FloodProtectorServerBypassPunishmentTime = 0 FloodProtectorServerBypassPunishmentTime = 0
# ServerBypass - multisell list request flooding # ServerBypass - multisell list request flooding
FloodProtectorMultiSellInterval = 1 FloodProtectorMultiSellInterval = 10
FloodProtectorMultiSellLogFlooding = False FloodProtectorMultiSellLogFlooding = False
FloodProtectorMultiSellPunishmentLimit = 0 FloodProtectorMultiSellPunishmentLimit = 0
FloodProtectorMultiSellPunishmentType = none FloodProtectorMultiSellPunishmentType = none

View File

@ -18,10 +18,7 @@ package org.l2jmobius.gameserver.network.clientpackets;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.OptionalLong; import java.util.OptionalLong;
import java.util.stream.Collectors;
import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.gameserver.data.xml.impl.MultisellData; import org.l2jmobius.gameserver.data.xml.impl.MultisellData;
@ -102,7 +99,7 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
if ((_amount < 1) || (_amount > 999999)) // 999 999 is client max. if ((_amount < 1) || (_amount > 10000)) // 999 999 is client max.
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -197,8 +194,7 @@ public class MultiSellChoose implements IClientIncomingPacket
} }
final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount); final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount);
if ((totalCount < 1) || (totalCount > Integer.MAX_VALUE))
if (!(totalCount >= 0) && (totalCount <= Integer.MAX_VALUE))
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -240,47 +236,32 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
// Summarize all item counts into one map. That would include non-stackable items under 1 id and multiple count. // Check for enchanted level and ingredient count requirements.
final Map<Integer, Long> itemIdCount = entry.getIngredients().stream().collect(Collectors.toMap(i -> i.getId(), i -> list.getIngredientCount(i), (k1, k2) -> Math.addExact(k1, k2)));
// Check for enchanted level requirements.
for (ItemChanceHolder ingredient : entry.getIngredients()) for (ItemChanceHolder ingredient : entry.getIngredients())
{ {
if (ingredient.getEnchantmentLevel() == 0) if (ingredient.getEnchantmentLevel() > 0)
{ {
continue; int found = 0;
} for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
int found = 0;
for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
{
if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{ {
found++; if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{
found++;
}
}
if (found < ingredient.getCount())
{
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return;
} }
} }
else if (!checkIngredients(player, list, inventory, clan, ingredient.getId(), Math.multiplyExact(ingredient.getCount(), _amount)))
if (found < ingredient.getCount())
{ {
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return; return;
} }
itemIdCount.remove(ingredient.getId()); // Since we check now.
}
// Now check if the player has sufficient items in the inventory to cover the ingredients' expences. Take care for non-stackable items like 2 swords to dual.
boolean allOk = true;
for (Entry<Integer, Long> idCount : itemIdCount.entrySet())
{
allOk &= checkIngredients(player, list, inventory, clan, idCount.getKey(), Math.multiplyExact(idCount.getValue(), _amount));
}
// The above operation should not be short-circuited, in order to show all missing ingredients.
if (!allOk)
{
return;
} }
final InventoryUpdate iu = new InventoryUpdate(); final InventoryUpdate iu = new InventoryUpdate();
@ -447,13 +428,40 @@ public class MultiSellChoose implements IClientIncomingPacket
{ {
addedItem.setEnchantLevel(itemEnchantment.getEnchantLevel()); addedItem.setEnchantLevel(itemEnchantment.getEnchantLevel());
addedItem.setAugmentation(itemEnchantment.getAugmentation(), false); addedItem.setAugmentation(itemEnchantment.getAugmentation(), false);
addedItem.setAttribute(new AttributeHolder(AttributeType.findByClientId(itemEnchantment.getAttackElementType()), itemEnchantment.getAttackElementPower()), false); if (addedItem.isWeapon())
addedItem.setAttribute(new AttributeHolder(AttributeType.FIRE, itemEnchantment.getAttributeDefence(AttributeType.FIRE)), false); {
addedItem.setAttribute(new AttributeHolder(AttributeType.WATER, itemEnchantment.getAttributeDefence(AttributeType.WATER)), false); if (itemEnchantment.getAttackElementPower() > 0)
addedItem.setAttribute(new AttributeHolder(AttributeType.WIND, itemEnchantment.getAttributeDefence(AttributeType.WIND)), false); {
addedItem.setAttribute(new AttributeHolder(AttributeType.EARTH, itemEnchantment.getAttributeDefence(AttributeType.EARTH)), false); addedItem.setAttribute(new AttributeHolder(AttributeType.findByClientId(itemEnchantment.getAttackElementType()), itemEnchantment.getAttackElementPower()), false);
addedItem.setAttribute(new AttributeHolder(AttributeType.HOLY, itemEnchantment.getAttributeDefence(AttributeType.HOLY)), false); }
addedItem.setAttribute(new AttributeHolder(AttributeType.DARK, itemEnchantment.getAttributeDefence(AttributeType.DARK)), false); }
else
{
if (itemEnchantment.getAttributeDefence(AttributeType.FIRE) > 0)
{
addedItem.setAttribute(new AttributeHolder(AttributeType.FIRE, itemEnchantment.getAttributeDefence(AttributeType.FIRE)), false);
}
if (itemEnchantment.getAttributeDefence(AttributeType.WATER) > 0)
{
addedItem.setAttribute(new AttributeHolder(AttributeType.WATER, itemEnchantment.getAttributeDefence(AttributeType.WATER)), false);
}
if (itemEnchantment.getAttributeDefence(AttributeType.WIND) > 0)
{
addedItem.setAttribute(new AttributeHolder(AttributeType.WIND, itemEnchantment.getAttributeDefence(AttributeType.WIND)), false);
}
if (itemEnchantment.getAttributeDefence(AttributeType.EARTH) > 0)
{
addedItem.setAttribute(new AttributeHolder(AttributeType.EARTH, itemEnchantment.getAttributeDefence(AttributeType.EARTH)), false);
}
if (itemEnchantment.getAttributeDefence(AttributeType.HOLY) > 0)
{
addedItem.setAttribute(new AttributeHolder(AttributeType.HOLY, itemEnchantment.getAttributeDefence(AttributeType.HOLY)), false);
}
if (itemEnchantment.getAttributeDefence(AttributeType.DARK) > 0)
{
addedItem.setAttribute(new AttributeHolder(AttributeType.DARK, itemEnchantment.getAttributeDefence(AttributeType.DARK)), false);
}
}
addedItem.updateDatabase(true); addedItem.updateDatabase(true);
// Mark that we have already upgraded the item. // Mark that we have already upgraded the item.
itemEnchantmentProcessed = false; itemEnchantmentProcessed = false;

View File

@ -74,7 +74,7 @@ FloodProtectorServerBypassPunishmentType = none
FloodProtectorServerBypassPunishmentTime = 0 FloodProtectorServerBypassPunishmentTime = 0
# ServerBypass - multisell list request flooding # ServerBypass - multisell list request flooding
FloodProtectorMultiSellInterval = 1 FloodProtectorMultiSellInterval = 10
FloodProtectorMultiSellLogFlooding = False FloodProtectorMultiSellLogFlooding = False
FloodProtectorMultiSellPunishmentLimit = 0 FloodProtectorMultiSellPunishmentLimit = 0
FloodProtectorMultiSellPunishmentType = none FloodProtectorMultiSellPunishmentType = none

View File

@ -18,10 +18,7 @@ package org.l2jmobius.gameserver.network.clientpackets;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.OptionalLong; import java.util.OptionalLong;
import java.util.stream.Collectors;
import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.commons.util.CommonUtil; import org.l2jmobius.commons.util.CommonUtil;
@ -119,7 +116,7 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
if ((_amount < 1) || (_amount > 999999)) // 999 999 is client max. if ((_amount < 1) || (_amount > 10000)) // 999 999 is client max.
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -225,8 +222,7 @@ public class MultiSellChoose implements IClientIncomingPacket
} }
final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount); final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount);
if ((totalCount < 1) || (totalCount > Integer.MAX_VALUE))
if (!(totalCount >= 0) && (totalCount <= Integer.MAX_VALUE))
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -268,47 +264,32 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
// Summarize all item counts into one map. That would include non-stackable items under 1 id and multiple count. // Check for enchanted level and ingredient count requirements.
final Map<Integer, Long> itemIdCount = entry.getIngredients().stream().collect(Collectors.toMap(i -> i.getId(), i -> list.getIngredientCount(i), (k1, k2) -> Math.addExact(k1, k2)));
// Check for enchanted level requirements.
for (ItemChanceHolder ingredient : entry.getIngredients()) for (ItemChanceHolder ingredient : entry.getIngredients())
{ {
if (ingredient.getEnchantmentLevel() == 0) if (ingredient.getEnchantmentLevel() > 0)
{ {
continue; int found = 0;
} for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
int found = 0;
for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
{
if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{ {
found++; if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{
found++;
}
}
if (found < ingredient.getCount())
{
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return;
} }
} }
else if (!checkIngredients(player, list, inventory, clan, ingredient.getId(), Math.multiplyExact(ingredient.getCount(), _amount)))
if (found < ingredient.getCount())
{ {
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return; return;
} }
itemIdCount.remove(ingredient.getId()); // Since we check now.
}
// Now check if the player has sufficient items in the inventory to cover the ingredients' expences. Take care for non-stackable items like 2 swords to dual.
boolean allOk = true;
for (Entry<Integer, Long> idCount : itemIdCount.entrySet())
{
allOk &= checkIngredients(player, list, inventory, clan, idCount.getKey(), Math.multiplyExact(idCount.getValue(), _amount));
}
// The above operation should not be short-circuited, in order to show all missing ingredients.
if (!allOk)
{
return;
} }
final InventoryUpdate iu = new InventoryUpdate(); final InventoryUpdate iu = new InventoryUpdate();

View File

@ -74,7 +74,7 @@ FloodProtectorServerBypassPunishmentType = none
FloodProtectorServerBypassPunishmentTime = 0 FloodProtectorServerBypassPunishmentTime = 0
# ServerBypass - multisell list request flooding # ServerBypass - multisell list request flooding
FloodProtectorMultiSellInterval = 1 FloodProtectorMultiSellInterval = 10
FloodProtectorMultiSellLogFlooding = False FloodProtectorMultiSellLogFlooding = False
FloodProtectorMultiSellPunishmentLimit = 0 FloodProtectorMultiSellPunishmentLimit = 0
FloodProtectorMultiSellPunishmentType = none FloodProtectorMultiSellPunishmentType = none

View File

@ -18,10 +18,7 @@ package org.l2jmobius.gameserver.network.clientpackets;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.OptionalLong; import java.util.OptionalLong;
import java.util.stream.Collectors;
import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.commons.util.CommonUtil; import org.l2jmobius.commons.util.CommonUtil;
@ -119,7 +116,7 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
if ((_amount < 1) || (_amount > 999999)) // 999 999 is client max. if ((_amount < 1) || (_amount > 10000)) // 999 999 is client max.
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -225,8 +222,7 @@ public class MultiSellChoose implements IClientIncomingPacket
} }
final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount); final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount);
if ((totalCount < 1) || (totalCount > Integer.MAX_VALUE))
if (!(totalCount >= 0) && (totalCount <= Integer.MAX_VALUE))
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -268,47 +264,32 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
// Summarize all item counts into one map. That would include non-stackable items under 1 id and multiple count. // Check for enchanted level and ingredient count requirements.
final Map<Integer, Long> itemIdCount = entry.getIngredients().stream().collect(Collectors.toMap(i -> i.getId(), i -> list.getIngredientCount(i), (k1, k2) -> Math.addExact(k1, k2)));
// Check for enchanted level requirements.
for (ItemChanceHolder ingredient : entry.getIngredients()) for (ItemChanceHolder ingredient : entry.getIngredients())
{ {
if (ingredient.getEnchantmentLevel() == 0) if (ingredient.getEnchantmentLevel() > 0)
{ {
continue; int found = 0;
} for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
int found = 0;
for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
{
if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{ {
found++; if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{
found++;
}
}
if (found < ingredient.getCount())
{
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return;
} }
} }
else if (!checkIngredients(player, list, inventory, clan, ingredient.getId(), Math.multiplyExact(ingredient.getCount(), _amount)))
if (found < ingredient.getCount())
{ {
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return; return;
} }
itemIdCount.remove(ingredient.getId()); // Since we check now.
}
// Now check if the player has sufficient items in the inventory to cover the ingredients' expences. Take care for non-stackable items like 2 swords to dual.
boolean allOk = true;
for (Entry<Integer, Long> idCount : itemIdCount.entrySet())
{
allOk &= checkIngredients(player, list, inventory, clan, idCount.getKey(), Math.multiplyExact(idCount.getValue(), _amount));
}
// The above operation should not be short-circuited, in order to show all missing ingredients.
if (!allOk)
{
return;
} }
final InventoryUpdate iu = new InventoryUpdate(); final InventoryUpdate iu = new InventoryUpdate();

View File

@ -74,7 +74,7 @@ FloodProtectorServerBypassPunishmentType = none
FloodProtectorServerBypassPunishmentTime = 0 FloodProtectorServerBypassPunishmentTime = 0
# ServerBypass - multisell list request flooding # ServerBypass - multisell list request flooding
FloodProtectorMultiSellInterval = 1 FloodProtectorMultiSellInterval = 10
FloodProtectorMultiSellLogFlooding = False FloodProtectorMultiSellLogFlooding = False
FloodProtectorMultiSellPunishmentLimit = 0 FloodProtectorMultiSellPunishmentLimit = 0
FloodProtectorMultiSellPunishmentType = none FloodProtectorMultiSellPunishmentType = none

View File

@ -18,10 +18,7 @@ package org.l2jmobius.gameserver.network.clientpackets;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.OptionalLong; import java.util.OptionalLong;
import java.util.stream.Collectors;
import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.commons.util.CommonUtil; import org.l2jmobius.commons.util.CommonUtil;
@ -119,7 +116,7 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
if ((_amount < 1) || (_amount > 999999)) // 999 999 is client max. if ((_amount < 1) || (_amount > 10000)) // 999 999 is client max.
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -225,8 +222,7 @@ public class MultiSellChoose implements IClientIncomingPacket
} }
final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount); final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount);
if ((totalCount < 1) || (totalCount > Integer.MAX_VALUE))
if (!(totalCount >= 0) && (totalCount <= Integer.MAX_VALUE))
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -268,47 +264,32 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
// Summarize all item counts into one map. That would include non-stackable items under 1 id and multiple count. // Check for enchanted level and ingredient count requirements.
final Map<Integer, Long> itemIdCount = entry.getIngredients().stream().collect(Collectors.toMap(i -> i.getId(), i -> list.getIngredientCount(i), (k1, k2) -> Math.addExact(k1, k2)));
// Check for enchanted level requirements.
for (ItemChanceHolder ingredient : entry.getIngredients()) for (ItemChanceHolder ingredient : entry.getIngredients())
{ {
if (ingredient.getEnchantmentLevel() == 0) if (ingredient.getEnchantmentLevel() > 0)
{ {
continue; int found = 0;
} for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
int found = 0;
for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
{
if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{ {
found++; if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{
found++;
}
}
if (found < ingredient.getCount())
{
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return;
} }
} }
else if (!checkIngredients(player, list, inventory, clan, ingredient.getId(), Math.multiplyExact(ingredient.getCount(), _amount)))
if (found < ingredient.getCount())
{ {
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return; return;
} }
itemIdCount.remove(ingredient.getId()); // Since we check now.
}
// Now check if the player has sufficient items in the inventory to cover the ingredients' expences. Take care for non-stackable items like 2 swords to dual.
boolean allOk = true;
for (Entry<Integer, Long> idCount : itemIdCount.entrySet())
{
allOk &= checkIngredients(player, list, inventory, clan, idCount.getKey(), Math.multiplyExact(idCount.getValue(), _amount));
}
// The above operation should not be short-circuited, in order to show all missing ingredients.
if (!allOk)
{
return;
} }
final InventoryUpdate iu = new InventoryUpdate(); final InventoryUpdate iu = new InventoryUpdate();

View File

@ -74,7 +74,7 @@ FloodProtectorServerBypassPunishmentType = none
FloodProtectorServerBypassPunishmentTime = 0 FloodProtectorServerBypassPunishmentTime = 0
# ServerBypass - multisell list request flooding # ServerBypass - multisell list request flooding
FloodProtectorMultiSellInterval = 1 FloodProtectorMultiSellInterval = 10
FloodProtectorMultiSellLogFlooding = False FloodProtectorMultiSellLogFlooding = False
FloodProtectorMultiSellPunishmentLimit = 0 FloodProtectorMultiSellPunishmentLimit = 0
FloodProtectorMultiSellPunishmentType = none FloodProtectorMultiSellPunishmentType = none

View File

@ -18,10 +18,7 @@ package org.l2jmobius.gameserver.network.clientpackets;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.OptionalLong; import java.util.OptionalLong;
import java.util.stream.Collectors;
import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.commons.util.CommonUtil; import org.l2jmobius.commons.util.CommonUtil;
@ -119,7 +116,7 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
if ((_amount < 1) || (_amount > 999999)) // 999 999 is client max. if ((_amount < 1) || (_amount > 10000)) // 999 999 is client max.
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -225,8 +222,7 @@ public class MultiSellChoose implements IClientIncomingPacket
} }
final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount); final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount);
if ((totalCount < 1) || (totalCount > Integer.MAX_VALUE))
if (!(totalCount >= 0) && (totalCount <= Integer.MAX_VALUE))
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -268,47 +264,32 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
// Summarize all item counts into one map. That would include non-stackable items under 1 id and multiple count. // Check for enchanted level and ingredient count requirements.
final Map<Integer, Long> itemIdCount = entry.getIngredients().stream().collect(Collectors.toMap(i -> i.getId(), i -> list.getIngredientCount(i), (k1, k2) -> Math.addExact(k1, k2)));
// Check for enchanted level requirements.
for (ItemChanceHolder ingredient : entry.getIngredients()) for (ItemChanceHolder ingredient : entry.getIngredients())
{ {
if (ingredient.getEnchantmentLevel() == 0) if (ingredient.getEnchantmentLevel() > 0)
{ {
continue; int found = 0;
} for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
int found = 0;
for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
{
if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{ {
found++; if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{
found++;
}
}
if (found < ingredient.getCount())
{
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return;
} }
} }
else if (!checkIngredients(player, list, inventory, clan, ingredient.getId(), Math.multiplyExact(ingredient.getCount(), _amount)))
if (found < ingredient.getCount())
{ {
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return; return;
} }
itemIdCount.remove(ingredient.getId()); // Since we check now.
}
// Now check if the player has sufficient items in the inventory to cover the ingredients' expences. Take care for non-stackable items like 2 swords to dual.
boolean allOk = true;
for (Entry<Integer, Long> idCount : itemIdCount.entrySet())
{
allOk &= checkIngredients(player, list, inventory, clan, idCount.getKey(), Math.multiplyExact(idCount.getValue(), _amount));
}
// The above operation should not be short-circuited, in order to show all missing ingredients.
if (!allOk)
{
return;
} }
final InventoryUpdate iu = new InventoryUpdate(); final InventoryUpdate iu = new InventoryUpdate();

View File

@ -74,7 +74,7 @@ FloodProtectorServerBypassPunishmentType = none
FloodProtectorServerBypassPunishmentTime = 0 FloodProtectorServerBypassPunishmentTime = 0
# ServerBypass - multisell list request flooding # ServerBypass - multisell list request flooding
FloodProtectorMultiSellInterval = 1 FloodProtectorMultiSellInterval = 10
FloodProtectorMultiSellLogFlooding = False FloodProtectorMultiSellLogFlooding = False
FloodProtectorMultiSellPunishmentLimit = 0 FloodProtectorMultiSellPunishmentLimit = 0
FloodProtectorMultiSellPunishmentType = none FloodProtectorMultiSellPunishmentType = none

View File

@ -18,10 +18,7 @@ package org.l2jmobius.gameserver.network.clientpackets;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.OptionalLong; import java.util.OptionalLong;
import java.util.stream.Collectors;
import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.commons.util.CommonUtil; import org.l2jmobius.commons.util.CommonUtil;
@ -119,7 +116,7 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
if ((_amount < 1) || (_amount > 999999)) // 999 999 is client max. if ((_amount < 1) || (_amount > 10000)) // 999 999 is client max.
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -225,8 +222,7 @@ public class MultiSellChoose implements IClientIncomingPacket
} }
final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount); final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount);
if ((totalCount < 1) || (totalCount > Integer.MAX_VALUE))
if (!(totalCount >= 0) && (totalCount <= Integer.MAX_VALUE))
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -268,47 +264,32 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
// Summarize all item counts into one map. That would include non-stackable items under 1 id and multiple count. // Check for enchanted level and ingredient count requirements.
final Map<Integer, Long> itemIdCount = entry.getIngredients().stream().collect(Collectors.toMap(i -> i.getId(), i -> list.getIngredientCount(i), (k1, k2) -> Math.addExact(k1, k2)));
// Check for enchanted level requirements.
for (ItemChanceHolder ingredient : entry.getIngredients()) for (ItemChanceHolder ingredient : entry.getIngredients())
{ {
if (ingredient.getEnchantmentLevel() == 0) if (ingredient.getEnchantmentLevel() > 0)
{ {
continue; int found = 0;
} for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
int found = 0;
for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
{
if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{ {
found++; if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{
found++;
}
}
if (found < ingredient.getCount())
{
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return;
} }
} }
else if (!checkIngredients(player, list, inventory, clan, ingredient.getId(), Math.multiplyExact(ingredient.getCount(), _amount)))
if (found < ingredient.getCount())
{ {
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return; return;
} }
itemIdCount.remove(ingredient.getId()); // Since we check now.
}
// Now check if the player has sufficient items in the inventory to cover the ingredients' expences. Take care for non-stackable items like 2 swords to dual.
boolean allOk = true;
for (Entry<Integer, Long> idCount : itemIdCount.entrySet())
{
allOk &= checkIngredients(player, list, inventory, clan, idCount.getKey(), Math.multiplyExact(idCount.getValue(), _amount));
}
// The above operation should not be short-circuited, in order to show all missing ingredients.
if (!allOk)
{
return;
} }
final InventoryUpdate iu = new InventoryUpdate(); final InventoryUpdate iu = new InventoryUpdate();

View File

@ -74,7 +74,7 @@ FloodProtectorServerBypassPunishmentType = none
FloodProtectorServerBypassPunishmentTime = 0 FloodProtectorServerBypassPunishmentTime = 0
# ServerBypass - multisell list request flooding # ServerBypass - multisell list request flooding
FloodProtectorMultiSellInterval = 1 FloodProtectorMultiSellInterval = 10
FloodProtectorMultiSellLogFlooding = False FloodProtectorMultiSellLogFlooding = False
FloodProtectorMultiSellPunishmentLimit = 0 FloodProtectorMultiSellPunishmentLimit = 0
FloodProtectorMultiSellPunishmentType = none FloodProtectorMultiSellPunishmentType = none

View File

@ -13,7 +13,7 @@
# PunishmentTime - for how many minutes should the player(jail)/account(ban) be punished (0 = forever), valid only for PunishmentType 'jail' or 'ban' # PunishmentTime - for how many minutes should the player(jail)/account(ban) be punished (0 = forever), valid only for PunishmentType 'jail' or 'ban'
# UseItem - item usage flooding # UseItem - item usage flooding
FloodProtectorUseItemInterval = 1 FloodProtectorUseItemInterval = 0
FloodProtectorUseItemLogFlooding = False FloodProtectorUseItemLogFlooding = False
FloodProtectorUseItemPunishmentLimit = 0 FloodProtectorUseItemPunishmentLimit = 0
FloodProtectorUseItemPunishmentType = none FloodProtectorUseItemPunishmentType = none
@ -83,10 +83,10 @@ FloodProtectorServerBypassPunishmentType = kick
FloodProtectorServerBypassPunishmentTime = 0 FloodProtectorServerBypassPunishmentTime = 0
# ServerBypass - multisell list request flooding # ServerBypass - multisell list request flooding
FloodProtectorMultiSellInterval = 2 FloodProtectorMultiSellInterval = 10
FloodProtectorMultiSellLogFlooding = False FloodProtectorMultiSellLogFlooding = False
FloodProtectorMultiSellPunishmentLimit = 5 FloodProtectorMultiSellPunishmentLimit = 0
FloodProtectorMultiSellPunishmentType = kick FloodProtectorMultiSellPunishmentType = none
FloodProtectorMultiSellPunishmentTime = 0 FloodProtectorMultiSellPunishmentTime = 0
# All kind of other transactions - to/from pet, private store, warehouse, destroy # All kind of other transactions - to/from pet, private store, warehouse, destroy
@ -138,7 +138,6 @@ FloodProtectorSayActionPunishmentLimit = 2
FloodProtectorSayActionPunishmentType = banchat FloodProtectorSayActionPunishmentType = banchat
FloodProtectorSayActionPunishmentTime = 1 FloodProtectorSayActionPunishmentTime = 1
# Move Action - attempts move to a location # Move Action - attempts move to a location
FloodProtectorMoveActionInterval = 1 FloodProtectorMoveActionInterval = 1
FloodProtectorMoveActionLogFlooding = False FloodProtectorMoveActionLogFlooding = False

View File

@ -75,7 +75,7 @@ FloodProtectorServerBypassPunishmentType = none
FloodProtectorServerBypassPunishmentTime = 0 FloodProtectorServerBypassPunishmentTime = 0
# ServerBypass - multisell list request flooding # ServerBypass - multisell list request flooding
FloodProtectorMultiSellInterval = 1 FloodProtectorMultiSellInterval = 10
FloodProtectorMultiSellLogFlooding = False FloodProtectorMultiSellLogFlooding = False
FloodProtectorMultiSellPunishmentLimit = 0 FloodProtectorMultiSellPunishmentLimit = 0
FloodProtectorMultiSellPunishmentType = none FloodProtectorMultiSellPunishmentType = none

View File

@ -74,7 +74,7 @@ FloodProtectorServerBypassPunishmentType = none
FloodProtectorServerBypassPunishmentTime = 0 FloodProtectorServerBypassPunishmentTime = 0
# ServerBypass - multisell list request flooding # ServerBypass - multisell list request flooding
FloodProtectorMultiSellInterval = 1 FloodProtectorMultiSellInterval = 10
FloodProtectorMultiSellLogFlooding = False FloodProtectorMultiSellLogFlooding = False
FloodProtectorMultiSellPunishmentLimit = 0 FloodProtectorMultiSellPunishmentLimit = 0
FloodProtectorMultiSellPunishmentType = none FloodProtectorMultiSellPunishmentType = none

View File

@ -18,10 +18,7 @@ package org.l2jmobius.gameserver.network.clientpackets;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.OptionalLong; import java.util.OptionalLong;
import java.util.stream.Collectors;
import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.commons.util.CommonUtil; import org.l2jmobius.commons.util.CommonUtil;
@ -119,7 +116,7 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
if ((_amount < 1) || (_amount > 999999)) // 999 999 is client max. if ((_amount < 1) || (_amount > 10000)) // 999 999 is client max.
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -225,8 +222,7 @@ public class MultiSellChoose implements IClientIncomingPacket
} }
final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount); final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount);
if ((totalCount < 1) || (totalCount > Integer.MAX_VALUE))
if (!(totalCount >= 0) && (totalCount <= Integer.MAX_VALUE))
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -268,47 +264,32 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
// Summarize all item counts into one map. That would include non-stackable items under 1 id and multiple count. // Check for enchanted level and ingredient count requirements.
final Map<Integer, Long> itemIdCount = entry.getIngredients().stream().collect(Collectors.toMap(i -> i.getId(), i -> list.getIngredientCount(i), (k1, k2) -> Math.addExact(k1, k2)));
// Check for enchanted level requirements.
for (ItemChanceHolder ingredient : entry.getIngredients()) for (ItemChanceHolder ingredient : entry.getIngredients())
{ {
if (ingredient.getEnchantmentLevel() == 0) if (ingredient.getEnchantmentLevel() > 0)
{ {
continue; int found = 0;
} for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
int found = 0;
for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
{
if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{ {
found++; if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{
found++;
}
}
if (found < ingredient.getCount())
{
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return;
} }
} }
else if (!checkIngredients(player, list, inventory, clan, ingredient.getId(), Math.multiplyExact(ingredient.getCount(), _amount)))
if (found < ingredient.getCount())
{ {
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return; return;
} }
itemIdCount.remove(ingredient.getId()); // Since we check now.
}
// Now check if the player has sufficient items in the inventory to cover the ingredients' expences. Take care for non-stackable items like 2 swords to dual.
boolean allOk = true;
for (Entry<Integer, Long> idCount : itemIdCount.entrySet())
{
allOk &= checkIngredients(player, list, inventory, clan, idCount.getKey(), Math.multiplyExact(idCount.getValue(), _amount));
}
// The above operation should not be short-circuited, in order to show all missing ingredients.
if (!allOk)
{
return;
} }
final InventoryUpdate iu = new InventoryUpdate(); final InventoryUpdate iu = new InventoryUpdate();

View File

@ -74,7 +74,7 @@ FloodProtectorServerBypassPunishmentType = none
FloodProtectorServerBypassPunishmentTime = 0 FloodProtectorServerBypassPunishmentTime = 0
# ServerBypass - multisell list request flooding # ServerBypass - multisell list request flooding
FloodProtectorMultiSellInterval = 1 FloodProtectorMultiSellInterval = 10
FloodProtectorMultiSellLogFlooding = False FloodProtectorMultiSellLogFlooding = False
FloodProtectorMultiSellPunishmentLimit = 0 FloodProtectorMultiSellPunishmentLimit = 0
FloodProtectorMultiSellPunishmentType = none FloodProtectorMultiSellPunishmentType = none

View File

@ -18,10 +18,7 @@ package org.l2jmobius.gameserver.network.clientpackets;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.OptionalLong; import java.util.OptionalLong;
import java.util.stream.Collectors;
import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.commons.util.CommonUtil; import org.l2jmobius.commons.util.CommonUtil;
@ -119,7 +116,7 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
if ((_amount < 1) || (_amount > 999999)) // 999 999 is client max. if ((_amount < 1) || (_amount > 10000)) // 999 999 is client max.
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -225,8 +222,7 @@ public class MultiSellChoose implements IClientIncomingPacket
} }
final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount); final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount);
if ((totalCount < 1) || (totalCount > Integer.MAX_VALUE))
if (!(totalCount >= 0) && (totalCount <= Integer.MAX_VALUE))
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -268,47 +264,32 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
// Summarize all item counts into one map. That would include non-stackable items under 1 id and multiple count. // Check for enchanted level and ingredient count requirements.
final Map<Integer, Long> itemIdCount = entry.getIngredients().stream().collect(Collectors.toMap(i -> i.getId(), i -> list.getIngredientCount(i), (k1, k2) -> Math.addExact(k1, k2)));
// Check for enchanted level requirements.
for (ItemChanceHolder ingredient : entry.getIngredients()) for (ItemChanceHolder ingredient : entry.getIngredients())
{ {
if (ingredient.getEnchantmentLevel() == 0) if (ingredient.getEnchantmentLevel() > 0)
{ {
continue; int found = 0;
} for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
int found = 0;
for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
{
if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{ {
found++; if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{
found++;
}
}
if (found < ingredient.getCount())
{
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return;
} }
} }
else if (!checkIngredients(player, list, inventory, clan, ingredient.getId(), Math.multiplyExact(ingredient.getCount(), _amount)))
if (found < ingredient.getCount())
{ {
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return; return;
} }
itemIdCount.remove(ingredient.getId()); // Since we check now.
}
// Now check if the player has sufficient items in the inventory to cover the ingredients' expences. Take care for non-stackable items like 2 swords to dual.
boolean allOk = true;
for (Entry<Integer, Long> idCount : itemIdCount.entrySet())
{
allOk &= checkIngredients(player, list, inventory, clan, idCount.getKey(), Math.multiplyExact(idCount.getValue(), _amount));
}
// The above operation should not be short-circuited, in order to show all missing ingredients.
if (!allOk)
{
return;
} }
final InventoryUpdate iu = new InventoryUpdate(); final InventoryUpdate iu = new InventoryUpdate();

View File

@ -74,7 +74,7 @@ FloodProtectorServerBypassPunishmentType = none
FloodProtectorServerBypassPunishmentTime = 0 FloodProtectorServerBypassPunishmentTime = 0
# ServerBypass - multisell list request flooding # ServerBypass - multisell list request flooding
FloodProtectorMultiSellInterval = 1 FloodProtectorMultiSellInterval = 10
FloodProtectorMultiSellLogFlooding = False FloodProtectorMultiSellLogFlooding = False
FloodProtectorMultiSellPunishmentLimit = 0 FloodProtectorMultiSellPunishmentLimit = 0
FloodProtectorMultiSellPunishmentType = none FloodProtectorMultiSellPunishmentType = none

View File

@ -18,10 +18,7 @@ package org.l2jmobius.gameserver.network.clientpackets;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.OptionalLong; import java.util.OptionalLong;
import java.util.stream.Collectors;
import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.commons.util.CommonUtil; import org.l2jmobius.commons.util.CommonUtil;
@ -119,7 +116,7 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
if ((_amount < 1) || (_amount > 999999)) // 999 999 is client max. if ((_amount < 1) || (_amount > 10000)) // 999 999 is client max.
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -225,8 +222,7 @@ public class MultiSellChoose implements IClientIncomingPacket
} }
final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount); final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount);
if ((totalCount < 1) || (totalCount > Integer.MAX_VALUE))
if (!(totalCount >= 0) && (totalCount <= Integer.MAX_VALUE))
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -268,47 +264,32 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
// Summarize all item counts into one map. That would include non-stackable items under 1 id and multiple count. // Check for enchanted level and ingredient count requirements.
final Map<Integer, Long> itemIdCount = entry.getIngredients().stream().collect(Collectors.toMap(i -> i.getId(), i -> list.getIngredientCount(i), (k1, k2) -> Math.addExact(k1, k2)));
// Check for enchanted level requirements.
for (ItemChanceHolder ingredient : entry.getIngredients()) for (ItemChanceHolder ingredient : entry.getIngredients())
{ {
if (ingredient.getEnchantmentLevel() == 0) if (ingredient.getEnchantmentLevel() > 0)
{ {
continue; int found = 0;
} for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
int found = 0;
for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
{
if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{ {
found++; if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{
found++;
}
}
if (found < ingredient.getCount())
{
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return;
} }
} }
else if (!checkIngredients(player, list, inventory, clan, ingredient.getId(), Math.multiplyExact(ingredient.getCount(), _amount)))
if (found < ingredient.getCount())
{ {
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return; return;
} }
itemIdCount.remove(ingredient.getId()); // Since we check now.
}
// Now check if the player has sufficient items in the inventory to cover the ingredients' expences. Take care for non-stackable items like 2 swords to dual.
boolean allOk = true;
for (Entry<Integer, Long> idCount : itemIdCount.entrySet())
{
allOk &= checkIngredients(player, list, inventory, clan, idCount.getKey(), Math.multiplyExact(idCount.getValue(), _amount));
}
// The above operation should not be short-circuited, in order to show all missing ingredients.
if (!allOk)
{
return;
} }
final InventoryUpdate iu = new InventoryUpdate(); final InventoryUpdate iu = new InventoryUpdate();

View File

@ -74,7 +74,7 @@ FloodProtectorServerBypassPunishmentType = none
FloodProtectorServerBypassPunishmentTime = 0 FloodProtectorServerBypassPunishmentTime = 0
# ServerBypass - multisell list request flooding # ServerBypass - multisell list request flooding
FloodProtectorMultiSellInterval = 1 FloodProtectorMultiSellInterval = 10
FloodProtectorMultiSellLogFlooding = False FloodProtectorMultiSellLogFlooding = False
FloodProtectorMultiSellPunishmentLimit = 0 FloodProtectorMultiSellPunishmentLimit = 0
FloodProtectorMultiSellPunishmentType = none FloodProtectorMultiSellPunishmentType = none

View File

@ -18,10 +18,7 @@ package org.l2jmobius.gameserver.network.clientpackets;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.OptionalLong; import java.util.OptionalLong;
import java.util.stream.Collectors;
import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.commons.util.CommonUtil; import org.l2jmobius.commons.util.CommonUtil;
@ -119,7 +116,7 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
if ((_amount < 1) || (_amount > 999999)) // 999 999 is client max. if ((_amount < 1) || (_amount > 10000)) // 999 999 is client max.
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -225,8 +222,7 @@ public class MultiSellChoose implements IClientIncomingPacket
} }
final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount); final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount);
if ((totalCount < 1) || (totalCount > Integer.MAX_VALUE))
if (!(totalCount >= 0) && (totalCount <= Integer.MAX_VALUE))
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -268,47 +264,32 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
// Summarize all item counts into one map. That would include non-stackable items under 1 id and multiple count. // Check for enchanted level and ingredient count requirements.
final Map<Integer, Long> itemIdCount = entry.getIngredients().stream().collect(Collectors.toMap(i -> i.getId(), i -> list.getIngredientCount(i), (k1, k2) -> Math.addExact(k1, k2)));
// Check for enchanted level requirements.
for (ItemChanceHolder ingredient : entry.getIngredients()) for (ItemChanceHolder ingredient : entry.getIngredients())
{ {
if (ingredient.getEnchantmentLevel() == 0) if (ingredient.getEnchantmentLevel() > 0)
{ {
continue; int found = 0;
} for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
int found = 0;
for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
{
if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{ {
found++; if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{
found++;
}
}
if (found < ingredient.getCount())
{
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return;
} }
} }
else if (!checkIngredients(player, list, inventory, clan, ingredient.getId(), Math.multiplyExact(ingredient.getCount(), _amount)))
if (found < ingredient.getCount())
{ {
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return; return;
} }
itemIdCount.remove(ingredient.getId()); // Since we check now.
}
// Now check if the player has sufficient items in the inventory to cover the ingredients' expences. Take care for non-stackable items like 2 swords to dual.
boolean allOk = true;
for (Entry<Integer, Long> idCount : itemIdCount.entrySet())
{
allOk &= checkIngredients(player, list, inventory, clan, idCount.getKey(), Math.multiplyExact(idCount.getValue(), _amount));
}
// The above operation should not be short-circuited, in order to show all missing ingredients.
if (!allOk)
{
return;
} }
final InventoryUpdate iu = new InventoryUpdate(); final InventoryUpdate iu = new InventoryUpdate();

View File

@ -74,7 +74,7 @@ FloodProtectorServerBypassPunishmentType = none
FloodProtectorServerBypassPunishmentTime = 0 FloodProtectorServerBypassPunishmentTime = 0
# ServerBypass - multisell list request flooding # ServerBypass - multisell list request flooding
FloodProtectorMultiSellInterval = 1 FloodProtectorMultiSellInterval = 10
FloodProtectorMultiSellLogFlooding = False FloodProtectorMultiSellLogFlooding = False
FloodProtectorMultiSellPunishmentLimit = 0 FloodProtectorMultiSellPunishmentLimit = 0
FloodProtectorMultiSellPunishmentType = none FloodProtectorMultiSellPunishmentType = none

View File

@ -18,10 +18,7 @@ package org.l2jmobius.gameserver.network.clientpackets;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.OptionalLong; import java.util.OptionalLong;
import java.util.stream.Collectors;
import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.commons.util.CommonUtil; import org.l2jmobius.commons.util.CommonUtil;
@ -119,7 +116,7 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
if ((_amount < 1) || (_amount > 999999)) // 999 999 is client max. if ((_amount < 1) || (_amount > 10000)) // 999 999 is client max.
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -225,8 +222,7 @@ public class MultiSellChoose implements IClientIncomingPacket
} }
final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount); final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount);
if ((totalCount < 1) || (totalCount > Integer.MAX_VALUE))
if (!(totalCount >= 0) && (totalCount <= Integer.MAX_VALUE))
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -268,47 +264,32 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
// Summarize all item counts into one map. That would include non-stackable items under 1 id and multiple count. // Check for enchanted level and ingredient count requirements.
final Map<Integer, Long> itemIdCount = entry.getIngredients().stream().collect(Collectors.toMap(i -> i.getId(), i -> list.getIngredientCount(i), (k1, k2) -> Math.addExact(k1, k2)));
// Check for enchanted level requirements.
for (ItemChanceHolder ingredient : entry.getIngredients()) for (ItemChanceHolder ingredient : entry.getIngredients())
{ {
if (ingredient.getEnchantmentLevel() == 0) if (ingredient.getEnchantmentLevel() > 0)
{ {
continue; int found = 0;
} for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
int found = 0;
for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
{
if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{ {
found++; if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{
found++;
}
}
if (found < ingredient.getCount())
{
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return;
} }
} }
else if (!checkIngredients(player, list, inventory, clan, ingredient.getId(), Math.multiplyExact(ingredient.getCount(), _amount)))
if (found < ingredient.getCount())
{ {
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return; return;
} }
itemIdCount.remove(ingredient.getId()); // Since we check now.
}
// Now check if the player has sufficient items in the inventory to cover the ingredients' expences. Take care for non-stackable items like 2 swords to dual.
boolean allOk = true;
for (Entry<Integer, Long> idCount : itemIdCount.entrySet())
{
allOk &= checkIngredients(player, list, inventory, clan, idCount.getKey(), Math.multiplyExact(idCount.getValue(), _amount));
}
// The above operation should not be short-circuited, in order to show all missing ingredients.
if (!allOk)
{
return;
} }
final InventoryUpdate iu = new InventoryUpdate(); final InventoryUpdate iu = new InventoryUpdate();

View File

@ -74,7 +74,7 @@ FloodProtectorServerBypassPunishmentType = none
FloodProtectorServerBypassPunishmentTime = 0 FloodProtectorServerBypassPunishmentTime = 0
# ServerBypass - multisell list request flooding # ServerBypass - multisell list request flooding
FloodProtectorMultiSellInterval = 1 FloodProtectorMultiSellInterval = 10
FloodProtectorMultiSellLogFlooding = False FloodProtectorMultiSellLogFlooding = False
FloodProtectorMultiSellPunishmentLimit = 0 FloodProtectorMultiSellPunishmentLimit = 0
FloodProtectorMultiSellPunishmentType = none FloodProtectorMultiSellPunishmentType = none

View File

@ -18,10 +18,7 @@ package org.l2jmobius.gameserver.network.clientpackets;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.OptionalLong; import java.util.OptionalLong;
import java.util.stream.Collectors;
import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.commons.network.PacketReader;
import org.l2jmobius.commons.util.CommonUtil; import org.l2jmobius.commons.util.CommonUtil;
@ -119,7 +116,7 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
if ((_amount < 1) || (_amount > 999999)) // 999 999 is client max. if ((_amount < 1) || (_amount > 10000)) // 999 999 is client max.
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -225,8 +222,7 @@ public class MultiSellChoose implements IClientIncomingPacket
} }
final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount); final long totalCount = Math.multiplyExact(list.getProductCount(product), _amount);
if ((totalCount < 1) || (totalCount > Integer.MAX_VALUE))
if (!(totalCount >= 0) && (totalCount <= Integer.MAX_VALUE))
{ {
player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED); player.sendPacket(SystemMessageId.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED);
return; return;
@ -268,47 +264,32 @@ public class MultiSellChoose implements IClientIncomingPacket
return; return;
} }
// Summarize all item counts into one map. That would include non-stackable items under 1 id and multiple count. // Check for enchanted level and ingredient count requirements.
final Map<Integer, Long> itemIdCount = entry.getIngredients().stream().collect(Collectors.toMap(i -> i.getId(), i -> list.getIngredientCount(i), (k1, k2) -> Math.addExact(k1, k2)));
// Check for enchanted level requirements.
for (ItemChanceHolder ingredient : entry.getIngredients()) for (ItemChanceHolder ingredient : entry.getIngredients())
{ {
if (ingredient.getEnchantmentLevel() == 0) if (ingredient.getEnchantmentLevel() > 0)
{ {
continue; int found = 0;
} for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
int found = 0;
for (ItemInstance item : inventory.getAllItemsByItemId(ingredient.getId(), ingredient.getEnchantmentLevel()))
{
if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{ {
found++; if (item.getEnchantLevel() >= ingredient.getEnchantmentLevel())
{
found++;
}
}
if (found < ingredient.getCount())
{
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return;
} }
} }
else if (!checkIngredients(player, list, inventory, clan, ingredient.getId(), Math.multiplyExact(ingredient.getCount(), _amount)))
if (found < ingredient.getCount())
{ {
final SystemMessage sm = new SystemMessage(SystemMessageId.YOU_NEED_A_N_S1);
sm.addString("+" + ingredient.getEnchantmentLevel() + " " + ItemTable.getInstance().getTemplate(ingredient.getId()).getName());
player.sendPacket(sm);
return; return;
} }
itemIdCount.remove(ingredient.getId()); // Since we check now.
}
// Now check if the player has sufficient items in the inventory to cover the ingredients' expences. Take care for non-stackable items like 2 swords to dual.
boolean allOk = true;
for (Entry<Integer, Long> idCount : itemIdCount.entrySet())
{
allOk &= checkIngredients(player, list, inventory, clan, idCount.getKey(), Math.multiplyExact(idCount.getValue(), _amount));
}
// The above operation should not be short-circuited, in order to show all missing ingredients.
if (!allOk)
{
return;
} }
final InventoryUpdate iu = new InventoryUpdate(); final InventoryUpdate iu = new InventoryUpdate();