use of com.almuradev.almura.feature.store.listing.BuyingItem in project Almura by AlmuraDev.
the class StoreScreen method listOrModify.
private void listOrModify() {
final ItemStack selectedItem = this.adminItemList.getSelectedItem();
if (selectedItem == null) {
return;
}
final Optional<BuyingItem> buyingItem = this.store.getBuyingItems().stream().filter(i -> StoreScreen.isStackEqualIgnoreSize(i.asRealStack(), selectedItem)).findAny();
final Optional<SellingItem> sellingItem = this.store.getSellingItems().stream().filter(i -> StoreScreen.isStackEqualIgnoreSize(i.asRealStack(), selectedItem)).findAny();
if (buyingItem.isPresent() || sellingItem.isPresent()) {
new StoreListScreen(this, this.store, buyingItem.orElse(null), sellingItem.orElse(null), selectedItem).display();
} else {
new StoreListScreen(this, this.store, selectedItem).display();
}
}
use of com.almuradev.almura.feature.store.listing.BuyingItem in project Almura by AlmuraDev.
the class ServerStoreManager method handleBuyingItemTransaction.
/**
* Transaction (Selling/Buying)
*/
public void handleBuyingItemTransaction(final Player player, final String id, final int recNo, final int quantity) {
checkNotNull(player);
checkNotNull(id);
checkState(recNo >= 0);
checkState(quantity >= 0);
final Store store = this.getStore(id).orElse(null);
if (store == null) {
this.logger.error("Player '{}' attempted to buy an item from store '{}' but the server has no knowledge of it. Syncing " + "store registry...", player.getName(), id);
this.syncStoreRegistryTo(player);
return;
}
final EconomyService economyService = this.serviceManager.provide(EconomyService.class).orElse(null);
if (economyService == null) {
this.notificationManager.sendWindowMessage(player, Text.of("Store"), Text.of("Critical error encountered, check the " + "server console for more details!"));
this.logger.error("Player '{}' attempted to buy an item from store '{}' but the economy service no longer exists. This is a " + "critical error that should be reported to your economy plugin ASAP.", player.getName(), id);
return;
}
final UniqueAccount account = economyService.getOrCreateAccount(player.getUniqueId()).orElse(null);
if (account == null) {
this.notificationManager.sendWindowMessage(player, Text.of("Store"), Text.of("Critical error encountered, check the " + "server console for more details!"));
this.logger.error("Player '{}' attempted to buy an item from store '{}' but the economy service returned no account for them. " + "This is a critical error that should be reported to your economy plugin ASAP.", player.getName(), id);
return;
}
final List<BuyingItem> buyingItems = store.getBuyingItems();
if (buyingItems.isEmpty()) {
this.logger.error("Player '{}' attempted to buy an item from store '{}' but the server knows of no " + " buying items for it. This could be a de-sync or an exploit.", player.getName(), store.getId());
this.network.sendTo(player, new ClientboundListItemsResponsePacket(store.getId(), StoreItemSegmentType.BUYING, buyingItems));
return;
}
final BuyingItem found = buyingItems.stream().filter(v -> v.getRecord() == recNo).findAny().orElse(null);
if (found == null) {
this.logger.error("Player '{}' attempted to buy item '{}' from store '{}' but the server knows of no knowledge of it. " + "This could be a de-sync or an exploit. Discarding...", player.getName(), recNo, store.getId());
this.network.sendTo(player, new ClientboundListItemsResponsePacket(store.getId(), StoreItemSegmentType.BUYING, buyingItems));
return;
}
final boolean infinite = found.getQuantity() == FeatureConstants.UNLIMITED;
if (!infinite && found.getQuantity() < quantity) {
this.notificationManager.sendWindowMessage(player, Text.of("Store"), Text.of("There is not enough quantity left to fulfill your order!"));
return;
}
final BigDecimal balance = account.getBalance(economyService.getDefaultCurrency());
final BigDecimal price = found.getPrice();
final double total = price.doubleValue() * quantity;
if (total > balance.doubleValue()) {
final String formattedTotal = FeatureConstants.CURRENCY_DECIMAL_FORMAT.format(total);
final String formattedBalance = FeatureConstants.CURRENCY_DECIMAL_FORMAT.format(balance.doubleValue());
final String formattedDifference = FeatureConstants.CURRENCY_DECIMAL_FORMAT.format(total - balance.doubleValue());
this.notificationManager.sendWindowMessage(player, Text.of("Store"), Text.of("You attempted to purchase items totaling to ", TextColors.RED, formattedTotal, TextColors.RESET, " while you only have ", TextColors.GREEN, formattedBalance, TextColors.RESET, ".", Text.NEW_LINE, Text.NEW_LINE, "You need ", TextColors.LIGHT_PURPLE, formattedDifference, TextColors.RESET, " more!"));
return;
}
EntityPlayerMP serverPlayer = (EntityPlayerMP) player;
final IItemHandler inventory = serverPlayer.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.UP);
final BuyingItem copyStack = found.copy();
copyStack.setQuantity(quantity);
final ItemStack simulatedResultStack = ItemHandlerHelper.insertItemStacked(inventory, copyStack.asRealStack(), true);
if (!simulatedResultStack.isEmpty()) {
this.notificationManager.sendWindowMessage(player, Text.of("Store"), Text.of("You lack sufficient inventory space to " + "purchase these item(s)!"));
return;
}
// Charge the buyer
try (final CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
frame.pushCause(store);
account.withdraw(economyService.getDefaultCurrency(), BigDecimal.valueOf(total), frame.getCurrentCause());
this.notificationManager.sendPopupNotification(player, Text.of(TextColors.GREEN, "Transaction Complete"), Text.of("Purchased ", TextColors.AQUA, quantity, TextColors.WHITE, " x ", TextColors.YELLOW, found.asRealStack().getDisplayName(), TextColors.RESET, " for a total of ", TextColors.GOLD, "$", FeatureConstants.CURRENCY_DECIMAL_FORMAT.format(total)), 3);
}
this.scheduler.createTaskBuilder().async().execute(() -> {
try (final DSLContext context = this.databaseManager.createContext(true)) {
int result;
if (!infinite) {
result = StoreQueries.createUpdateBuyingItem(found.getRecord(), found.getQuantity() - quantity, found.getIndex(), found.getPrice()).build(context).execute();
if (result == 0) {
// TODO It failed, message
return;
}
}
result = StoreQueries.createInsertBuyingTransaction(Instant.now(), found.getRecord(), player.getUniqueId(), found.getPrice(), quantity).build(context).execute();
if (result == 0) {
// TODO It failed, message
StoreQueries.createUpdateBuyingItem(found.getRecord(), found.getQuantity(), found.getIndex(), found.getPrice()).build(context).execute();
return;
}
final List<BuyingItem> finalBuyingItems = new ArrayList<>();
if (!infinite) {
final Results results = StoreQueries.createFetchBuyingItemsAndDataFor(store.getId(), false).build(context).fetchMany();
results.forEach(r -> finalBuyingItems.addAll(this.parseBuyingItemsFor(r)));
}
this.scheduler.createTaskBuilder().execute(() -> {
if (!infinite) {
store.putBuyingItems(finalBuyingItems);
}
final ItemStack resultStack = ItemHandlerHelper.insertItemStacked(inventory, copyStack.asRealStack(), false);
if (!resultStack.isEmpty()) {
// TODO Inventory changed awaiting DB and now we're full...could drop it on the ground? It is an off-case
}
if (!infinite) {
this.network.sendToAll(new ClientboundListItemsResponsePacket(store.getId(), StoreItemSegmentType.BUYING, store.getBuyingItems()));
}
}).submit(this.container);
} catch (final SQLException e) {
e.printStackTrace();
}
}).submit(this.container);
}
use of com.almuradev.almura.feature.store.listing.BuyingItem in project Almura by AlmuraDev.
the class ClientboundListItemsResponsePacket method readFrom.
@Override
public void readFrom(final ChannelBuf buf) {
this.id = buf.readString();
this.type = StoreItemSegmentType.valueOf(buf.readString());
final int count = buf.readInteger();
if (count > 0) {
if (type == StoreItemSegmentType.SELLING) {
this.storeItems = new ArrayList<SellingItem>();
} else {
this.storeItems = new ArrayList<BuyingItem>();
}
for (int i = 0; i < count; i++) {
final int record = buf.readInteger();
final Instant created;
try {
created = SerializationUtil.bytesToObject(buf.readBytes(buf.readInteger()));
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
continue;
}
final ResourceLocation location = new ResourceLocation(buf.readString(), buf.readString());
final Item item = ForgeRegistries.ITEMS.getValue(location);
if (item == null) {
new IOException("Unknown item id '" + location.toString() + "' when receiving item! . Skipping...").printStackTrace();
continue;
}
final int quantity = buf.readInteger();
final int metadata = buf.readInteger();
final BigDecimal price = ByteBufUtil.readBigDecimal((ByteBuf) buf);
final int index = buf.readInteger();
final int compoundDataLength = buf.readInteger();
NBTTagCompound compound = null;
if (compoundDataLength > 0) {
try {
compound = SerializationUtil.compoundFromBytes(buf.readBytes(compoundDataLength));
} catch (IOException e) {
e.printStackTrace();
continue;
}
}
final Constructor<? extends AbstractStoreItem> constructor;
try {
constructor = this.type.getItemClass().getConstructor(Integer.TYPE, Instant.class, Item.class, Integer.TYPE, Integer.TYPE, BigDecimal.class, Integer.TYPE, NBTTagCompound.class);
final AbstractStoreItem storeItem = constructor.newInstance(record, created, item, quantity, metadata, price, index, compound);
if (this.type == StoreItemSegmentType.SELLING) {
((List<SellingItem>) this.storeItems).add((SellingItem) storeItem);
} else {
((List<BuyingItem>) this.storeItems).add((BuyingItem) storeItem);
}
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
Aggregations