diff --git a/src/main/java/net/server/channel/handlers/CashShopSurpriseHandler.java b/src/main/java/net/server/channel/handlers/CashShopSurpriseHandler.java index 7b338dc082..9fff47092f 100644 --- a/src/main/java/net/server/channel/handlers/CashShopSurpriseHandler.java +++ b/src/main/java/net/server/channel/handlers/CashShopSurpriseHandler.java @@ -42,7 +42,8 @@ public class CashShopSurpriseHandler extends AbstractPacketHandler { return; } - Optional result = cs.openCashShopSurprise(); + long cashId = p.readLong(); + Optional result = cs.openCashShopSurprise(cashId); if (result.isEmpty()) { c.sendPacket(PacketCreator.onCashItemGachaponOpenFailed()); return; diff --git a/src/main/java/server/CashShop.java b/src/main/java/server/CashShop.java index ae9a45599e..498fe12fdc 100644 --- a/src/main/java/server/CashShop.java +++ b/src/main/java/server/CashShop.java @@ -29,6 +29,7 @@ import client.inventory.Pet; import config.YamlConfig; import constants.id.ItemId; import constants.inventory.ItemConstants; +import net.jcip.annotations.GuardedBy; import net.server.Server; import provider.Data; import provider.DataProvider; @@ -408,17 +409,6 @@ public class CashShop { } } - public int getItemsSize() { - int size = 0; - lock.lock(); - try { - size = inventory.size(); - } finally { - lock.unlock(); - } - return size; - } - public List getWishList() { return wishList; } @@ -537,46 +527,58 @@ public class CashShop { } } - private Item getCashShopItemByItemid(int itemid) { + public Optional openCashShopSurprise(long cashId) { lock.lock(); try { - for (Item it : inventory) { - if (it.getItemId() == itemid) { - return it; - } + Optional maybeCashShopSurprise = getItemByCashId(cashId); + if (maybeCashShopSurprise.isEmpty() || + maybeCashShopSurprise.get().getItemId() != ItemId.CASH_SHOP_SURPRISE) { + return Optional.empty(); } + + Item cashShopSurprise = maybeCashShopSurprise.get(); + if (cashShopSurprise.getQuantity() <= 0) { + return Optional.empty(); + } + + if (getItemsSize() >= 100) { + return Optional.empty(); + } + + CashItem cashItemReward = CashItemFactory.getRandomCashItem(); + if (cashItemReward == null) { + return Optional.empty(); + } + + short newQuantity = (short) (cashShopSurprise.getQuantity() - 1); + cashShopSurprise.setQuantity(newQuantity); + if (newQuantity <= 0) { + removeFromInventory(cashShopSurprise); + } + + Item itemReward = cashItemReward.toItem(); + addToInventory(itemReward); + + return Optional.of(new CashShopSurpriseResult(cashShopSurprise, itemReward)); } finally { lock.unlock(); } - - return null; } - public synchronized Optional openCashShopSurprise() { - Item cashShopSurprise = getCashShopItemByItemid(ItemId.CASH_SHOP_SURPRISE); - if (cashShopSurprise == null || cashShopSurprise.getQuantity() <= 0) { - return Optional.empty(); + @GuardedBy("lock") + private Optional getItemByCashId(long cashId) { + return inventory.stream() + .filter(item -> item.getCashId() == cashId) + .findAny(); + } + + public int getItemsSize() { + lock.lock(); + try { + return inventory.size(); + } finally { + lock.unlock(); } - - if (getItemsSize() >= 100) { - return Optional.empty(); - } - - CashItem cashItemReward = CashItemFactory.getRandomCashItem(); - if (cashItemReward == null) { - return Optional.empty(); - } - - short newQuantity = (short) (cashShopSurprise.getQuantity() - 1); - cashShopSurprise.setQuantity(newQuantity); - if (newQuantity <= 0) { - removeFromInventory(cashShopSurprise); - } - - Item itemReward = cashItemReward.toItem(); - addToInventory(itemReward); - - return Optional.of(new CashShopSurpriseResult(cashShopSurprise, itemReward)); } public static Item generateCouponItem(int itemId, short quantity) { diff --git a/src/test/java/net/server/channel/handlers/CashShopSurpriseHandlerTest.java b/src/test/java/net/server/channel/handlers/CashShopSurpriseHandlerTest.java index ff97b11fe3..71d0246ab1 100644 --- a/src/test/java/net/server/channel/handlers/CashShopSurpriseHandlerTest.java +++ b/src/test/java/net/server/channel/handlers/CashShopSurpriseHandlerTest.java @@ -2,6 +2,7 @@ package net.server.channel.handlers; import client.inventory.Item; import constants.id.ItemId; +import net.packet.InPacket; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -15,6 +16,7 @@ import tools.PacketCreator; import java.util.Optional; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -31,21 +33,25 @@ class CashShopSurpriseHandlerTest extends HandlerTest { when(chr.getCashShop()).thenReturn(cashShop); } + private InPacket useCashShopSurprisePacket(long cashId) { + return Packets.buildInPacket(out -> out.writeLong(cashId)); + } + @Test void shouldDoNothingWhenCsIsNotOpened() { when(cashShop.isOpened()).thenReturn(false); - handler.handlePacket(Packets.emptyInPacket(), client); + handler.handlePacket(useCashShopSurprisePacket(123), client); - verify(cashShop, never()).openCashShopSurprise(); + verify(cashShop, never()).openCashShopSurprise(anyLong()); } @Test void shouldSendFailurePacketWhenFailToOpen() { when(cashShop.isOpened()).thenReturn(true); - when(cashShop.openCashShopSurprise()).thenReturn(Optional.empty()); + when(cashShop.openCashShopSurprise(anyLong())).thenReturn(Optional.empty()); - handler.handlePacket(Packets.emptyInPacket(), client); + handler.handlePacket(useCashShopSurprisePacket(456), client); verify(client).sendPacket(PacketCreator.onCashItemGachaponOpenFailed()); } @@ -55,10 +61,10 @@ class CashShopSurpriseHandlerTest extends HandlerTest { when(cashShop.isOpened()).thenReturn(true); Item cashShopSurprise = Items.itemWithQuantity(ItemId.CASH_SHOP_SURPRISE, 3); Item reward = Items.itemWithQuantity(5000012, 1); - when(cashShop.openCashShopSurprise()).thenReturn(Optional.of(new CashShop.CashShopSurpriseResult( + when(cashShop.openCashShopSurprise(789)).thenReturn(Optional.of(new CashShop.CashShopSurpriseResult( cashShopSurprise, reward))); - handler.handlePacket(Packets.emptyInPacket(), client); + handler.handlePacket(useCashShopSurprisePacket(789), client); verify(client).sendPacket(PacketCreator.onCashGachaponOpenSuccess(ACCOUNT_ID, cashShopSurprise.getCashId(), 3, reward, 5000012, 1, true)); diff --git a/src/test/java/testutil/Packets.java b/src/test/java/testutil/Packets.java index f833694388..6bd9db8a9c 100644 --- a/src/test/java/testutil/Packets.java +++ b/src/test/java/testutil/Packets.java @@ -2,11 +2,17 @@ package testutil; import io.netty.buffer.Unpooled; import net.packet.ByteBufInPacket; +import net.packet.ByteBufOutPacket; import net.packet.InPacket; +import net.packet.OutPacket; + +import java.util.function.Consumer; public class Packets { - public static InPacket emptyInPacket() { - return new ByteBufInPacket(Unpooled.buffer()); + public static InPacket buildInPacket(Consumer contentProvider) { + OutPacket builderInput = new ByteBufOutPacket(); + contentProvider.accept(builderInput); + return new ByteBufInPacket(Unpooled.wrappedBuffer(builderInput.getBytes())); } }