Updatee
This commit is contained in:
		@@ -6,7 +6,7 @@ minecraft_version=1.21.1
 | 
			
		||||
yarn_mappings=1.21.1+build.3
 | 
			
		||||
loader_version=0.16.2
 | 
			
		||||
# Mod Properties
 | 
			
		||||
mod_version=1.0
 | 
			
		||||
mod_version=1.2
 | 
			
		||||
maven_group=systems.brn
 | 
			
		||||
archives_base_name=servershop
 | 
			
		||||
# Dependencies
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,37 @@
 | 
			
		||||
package systems.brn.servershop;
 | 
			
		||||
 | 
			
		||||
public record ItemPrice(
 | 
			
		||||
        int buyPrice, int sellPrice
 | 
			
		||||
) {
 | 
			
		||||
import net.minecraft.item.ItemStack;
 | 
			
		||||
import net.minecraft.nbt.NbtCompound;
 | 
			
		||||
import net.minecraft.nbt.NbtElement;
 | 
			
		||||
import net.minecraft.registry.RegistryWrapper;
 | 
			
		||||
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
 | 
			
		||||
public record ItemPrice(int buyPrice, int sellPrice, ItemStack stack) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public NbtCompound toNbt(RegistryWrapper.WrapperLookup wrapperLookup) {
 | 
			
		||||
        NbtCompound nbt = new NbtCompound();
 | 
			
		||||
        nbt.putInt("BuyPrice", this.buyPrice);
 | 
			
		||||
        nbt.putInt("SellPrice", this.sellPrice);
 | 
			
		||||
 | 
			
		||||
        // Serialize the ItemStack to NBT and add it to the compound
 | 
			
		||||
        NbtElement stackNbt = stack.encode(wrapperLookup);
 | 
			
		||||
        nbt.put("ItemStack", stackNbt); // Adds the ItemStack's NBT data to the main NBT compound
 | 
			
		||||
 | 
			
		||||
        return nbt;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ItemPrice fromNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup wrapperLookup) {
 | 
			
		||||
        int buyPrice = nbt.getInt("BuyPrice");
 | 
			
		||||
        int sellPrice = nbt.getInt("SellPrice");
 | 
			
		||||
 | 
			
		||||
        // Deserialize the ItemStack from the NBT
 | 
			
		||||
        NbtElement stackElement = nbt.get("ItemStack");
 | 
			
		||||
 | 
			
		||||
        Optional<ItemStack> stack = ItemStack.fromNbt(wrapperLookup, stackElement);
 | 
			
		||||
        return stack.map(itemStack -> new ItemPrice(buyPrice, sellPrice, itemStack)).orElse(null);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -47,7 +47,7 @@ public class ServerShop implements ModInitializer {
 | 
			
		||||
 | 
			
		||||
    private void onPlayerJoin(ServerPlayNetworkHandler serverPlayNetworkHandler, PacketSender packetSender, MinecraftServer server) {
 | 
			
		||||
        if (packetSender instanceof ServerPlayerEntity player) {
 | 
			
		||||
            balanceManager.onJoin(player);
 | 
			
		||||
            balanceManager.setBalance(player, 0L);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -94,6 +94,13 @@ public class ServerShop implements ModInitializer {
 | 
			
		||||
                                )
 | 
			
		||||
                        )
 | 
			
		||||
                )
 | 
			
		||||
                .then(literal("setHand")
 | 
			
		||||
                        .then(argument("buyprice", IntegerArgumentType.integer())
 | 
			
		||||
                                .then(argument("sellprice", IntegerArgumentType.integer())
 | 
			
		||||
                                        .executes(ShopPricesCommand::setHand)
 | 
			
		||||
                                )
 | 
			
		||||
                        )
 | 
			
		||||
                )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        dispatcher.register(literal("buy")
 | 
			
		||||
@@ -110,6 +117,12 @@ public class ServerShop implements ModInitializer {
 | 
			
		||||
                        .executes(StoreCommands::sellOne)
 | 
			
		||||
                )
 | 
			
		||||
        );
 | 
			
		||||
        dispatcher.register(literal("price")
 | 
			
		||||
                .then(argument("item", ItemStackArgumentType.itemStack(commandRegistryAccess))
 | 
			
		||||
                        .executes(PriceCommand::run)
 | 
			
		||||
                )
 | 
			
		||||
                .executes(PriceCommand::runHand)
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -119,6 +132,6 @@ public class ServerShop implements ModInitializer {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void onServerStopped(MinecraftServer server) {
 | 
			
		||||
        balanceManager.saveBalance();
 | 
			
		||||
        balanceManager.saveBalances();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,55 @@
 | 
			
		||||
package systems.brn.servershop.commands;
 | 
			
		||||
 | 
			
		||||
import com.mojang.brigadier.context.CommandContext;
 | 
			
		||||
import net.minecraft.command.argument.ItemStackArgumentType;
 | 
			
		||||
import net.minecraft.item.Item;
 | 
			
		||||
import net.minecraft.item.ItemStack;
 | 
			
		||||
import net.minecraft.server.command.ServerCommandSource;
 | 
			
		||||
import net.minecraft.server.network.ServerPlayerEntity;
 | 
			
		||||
import net.minecraft.text.Text;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
import systems.brn.servershop.ItemPrice;
 | 
			
		||||
 | 
			
		||||
import static systems.brn.servershop.ServerShop.priceStorage;
 | 
			
		||||
 | 
			
		||||
public class PriceCommand {
 | 
			
		||||
    public static int run(CommandContext<ServerCommandSource> ctx) {
 | 
			
		||||
        Item item = ItemStackArgumentType.getItemStackArgument(ctx, "item").getItem();
 | 
			
		||||
        ItemStack stack = item.getDefaultStack();
 | 
			
		||||
        return runStack(ctx, stack);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static int runStack(CommandContext<ServerCommandSource> ctx, ItemStack stack) {
 | 
			
		||||
        ItemPrice itemPrice = priceStorage.getPrices(stack);
 | 
			
		||||
        ServerCommandSource src = ctx.getSource();
 | 
			
		||||
        int buyPrice = itemPrice.buyPrice();
 | 
			
		||||
        int sellPrice = itemPrice.sellPrice();
 | 
			
		||||
        String itemName = stack.getItem().toString();
 | 
			
		||||
        Text text = getText(buyPrice, sellPrice, itemName);
 | 
			
		||||
        src.sendFeedback(() -> text, false);
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static int runHand(CommandContext<ServerCommandSource> ctx) {
 | 
			
		||||
        ServerPlayerEntity player = ctx.getSource().getPlayer();
 | 
			
		||||
        if (player != null) {
 | 
			
		||||
            ItemStack stack = player.getMainHandStack();
 | 
			
		||||
            return runStack(ctx, stack);
 | 
			
		||||
        }
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static @NotNull Text getText(int buyPrice, int sellPrice, String itemName) {
 | 
			
		||||
        Text text;
 | 
			
		||||
        if (buyPrice > 0 && sellPrice > 0) {
 | 
			
		||||
            text = Text.translatable("message.servershop.price.both", itemName, buyPrice, sellPrice);
 | 
			
		||||
        } else if (buyPrice > 0) {
 | 
			
		||||
            text = Text.translatable("message.servershop.price.buy", itemName, buyPrice);
 | 
			
		||||
        } else if (sellPrice > 0) {
 | 
			
		||||
            text = Text.translatable("message.servershop.price.sell", itemName, sellPrice);
 | 
			
		||||
        } else {
 | 
			
		||||
            text = Text.translatable("message.servershop.price.neither", itemName);
 | 
			
		||||
        }
 | 
			
		||||
        return text;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -3,8 +3,11 @@ package systems.brn.servershop.commands;
 | 
			
		||||
import com.mojang.brigadier.arguments.IntegerArgumentType;
 | 
			
		||||
import com.mojang.brigadier.context.CommandContext;
 | 
			
		||||
import net.minecraft.command.argument.ItemStackArgumentType;
 | 
			
		||||
import net.minecraft.item.Item;
 | 
			
		||||
import net.minecraft.item.ItemStack;
 | 
			
		||||
import net.minecraft.registry.RegistryWrapper;
 | 
			
		||||
import net.minecraft.server.MinecraftServer;
 | 
			
		||||
import net.minecraft.server.command.ServerCommandSource;
 | 
			
		||||
import net.minecraft.server.network.ServerPlayerEntity;
 | 
			
		||||
import net.minecraft.text.Text;
 | 
			
		||||
import systems.brn.servershop.ServerShop;
 | 
			
		||||
 | 
			
		||||
@@ -15,6 +18,12 @@ public class ShopPricesCommand {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static int loadLegacy(CommandContext<ServerCommandSource> ctx) {
 | 
			
		||||
        ServerShop.priceStorage.loadLegacy();
 | 
			
		||||
        ctx.getSource().sendFeedback(() -> Text.translatable("message.servershop.storage.load"), false);
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static int save(CommandContext<ServerCommandSource> ctx) {
 | 
			
		||||
        boolean success = ServerShop.priceStorage.save();
 | 
			
		||||
        ctx.getSource().sendFeedback(() ->
 | 
			
		||||
@@ -29,17 +38,28 @@ public class ShopPricesCommand {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static int set(CommandContext<ServerCommandSource> ctx) {
 | 
			
		||||
        Item item = ItemStackArgumentType.getItemStackArgument(ctx, "item").getItem();
 | 
			
		||||
        ItemStack stack = ItemStackArgumentType.getItemStackArgument(ctx, "item").getItem().getDefaultStack();
 | 
			
		||||
        return setStack(ctx, stack);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static int setHand(CommandContext<ServerCommandSource> ctx) {
 | 
			
		||||
        ServerPlayerEntity player = ctx.getSource().getPlayer();
 | 
			
		||||
        if (player != null) {
 | 
			
		||||
            ItemStack stack = player.getMainHandStack().copy();
 | 
			
		||||
            if (!stack.isEmpty()) {
 | 
			
		||||
                return setStack(ctx, stack);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static int setStack(CommandContext<ServerCommandSource> ctx, ItemStack stack) {
 | 
			
		||||
        String itemName = stack.getItem().toString();
 | 
			
		||||
        int buyPrice = IntegerArgumentType.getInteger(ctx, "buyprice");
 | 
			
		||||
        int sellPrice = IntegerArgumentType.getInteger(ctx, "sellprice");
 | 
			
		||||
        String itemName = item.toString();
 | 
			
		||||
        boolean success = ServerShop.priceStorage.setPrices(item, buyPrice, sellPrice);
 | 
			
		||||
        if (success) {
 | 
			
		||||
            ctx.getSource().sendFeedback(() -> Text.translatable("message.servershop.storage.set", itemName, buyPrice, sellPrice), false);
 | 
			
		||||
            return 1;
 | 
			
		||||
        } else {
 | 
			
		||||
            ctx.getSource().sendFeedback(() -> Text.translatable("message.servershop.storage.set_fail", itemName), false);
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        ServerShop.priceStorage.setPrices(stack, buyPrice, sellPrice);
 | 
			
		||||
        ctx.getSource().sendFeedback(() -> Text.translatable("message.servershop.storage.set", itemName, buyPrice, sellPrice), false);
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@ public class StoreCommands {
 | 
			
		||||
        ItemStack itemStack = new ItemStack(item, count);
 | 
			
		||||
        ServerPlayerEntity player = ctx.getSource().getPlayer();
 | 
			
		||||
        if (player != null) {
 | 
			
		||||
            buy(itemStack, player);
 | 
			
		||||
            buy(itemStack, player, false);
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        return 1;
 | 
			
		||||
@@ -29,7 +29,7 @@ public class StoreCommands {
 | 
			
		||||
        ItemStack itemStack = new ItemStack(item);
 | 
			
		||||
        ServerPlayerEntity player = ctx.getSource().getPlayer();
 | 
			
		||||
        if (player != null) {
 | 
			
		||||
            buy(itemStack, player);
 | 
			
		||||
            buy(itemStack, player, false);
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        return 1;
 | 
			
		||||
@@ -41,7 +41,7 @@ public class StoreCommands {
 | 
			
		||||
        ItemStack itemStack = new ItemStack(item, count);
 | 
			
		||||
        ServerPlayerEntity player = ctx.getSource().getPlayer();
 | 
			
		||||
        if (player != null) {
 | 
			
		||||
            sell(itemStack, player);
 | 
			
		||||
            sell(itemStack, player, false);
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        return 1;
 | 
			
		||||
@@ -52,7 +52,7 @@ public class StoreCommands {
 | 
			
		||||
        ItemStack itemStack = new ItemStack(item);
 | 
			
		||||
        ServerPlayerEntity player = ctx.getSource().getPlayer();
 | 
			
		||||
        if (player != null) {
 | 
			
		||||
            sell(itemStack, player);
 | 
			
		||||
            sell(itemStack, player, false);
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        return 1;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,36 +1,35 @@
 | 
			
		||||
package systems.brn.servershop.lib;
 | 
			
		||||
 | 
			
		||||
import net.minecraft.nbt.*;
 | 
			
		||||
import net.minecraft.server.MinecraftServer;
 | 
			
		||||
import net.minecraft.server.network.ServerPlayerEntity;
 | 
			
		||||
import net.minecraft.text.Text;
 | 
			
		||||
import net.minecraft.util.Identifier;
 | 
			
		||||
import net.minecraft.util.WorldSavePath;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
import java.io.FileWriter;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
import java.util.Scanner;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
import java.util.concurrent.locks.ReentrantLock;
 | 
			
		||||
 | 
			
		||||
public class BalanceManager {
 | 
			
		||||
    final private HashMap<UUID, Long> balances = new HashMap<>();
 | 
			
		||||
    private final HashMap<UUID, Long> balances = new HashMap<>();
 | 
			
		||||
    public final MinecraftServer server;
 | 
			
		||||
    public final File balanceStorageFile;
 | 
			
		||||
    private final File balanceStorageFile;
 | 
			
		||||
    private final File balanceStorageCSVFile;
 | 
			
		||||
    private static final ReentrantLock lock = new ReentrantLock();  // Lock for in-memory operations
 | 
			
		||||
 | 
			
		||||
    public BalanceManager(MinecraftServer server) {
 | 
			
		||||
        this.server = server;
 | 
			
		||||
        balanceStorageFile = server.getSavePath(WorldSavePath.ROOT).resolve("balances.csv").toFile();
 | 
			
		||||
        loadBalance();
 | 
			
		||||
        balanceStorageFile = server.getSavePath(WorldSavePath.ROOT).resolve("balances.dat").toFile();
 | 
			
		||||
        balanceStorageCSVFile = server.getSavePath(WorldSavePath.ROOT).resolve("balances.csv").toFile();
 | 
			
		||||
        loadBalances();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public long getBalance(UUID uuid) {
 | 
			
		||||
        if (balances.containsKey(uuid)) {
 | 
			
		||||
            return balances.get(uuid);
 | 
			
		||||
        }
 | 
			
		||||
        return 0L;
 | 
			
		||||
        return balances.getOrDefault(uuid, 0L);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public long getBalance(ServerPlayerEntity player) {
 | 
			
		||||
@@ -38,8 +37,8 @@ public class BalanceManager {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void addBalance(UUID uuid, long amount) {
 | 
			
		||||
        balances.put(uuid, amount + getBalance(uuid));
 | 
			
		||||
        saveBalance();
 | 
			
		||||
        balances.put(uuid, getBalance(uuid) + amount);
 | 
			
		||||
        saveBalances();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void addBalance(ServerPlayerEntity player, long amount) {
 | 
			
		||||
@@ -49,11 +48,12 @@ public class BalanceManager {
 | 
			
		||||
 | 
			
		||||
    public void removeBalance(UUID uuid, long amount) {
 | 
			
		||||
        balances.put(uuid, getBalance(uuid) - amount);
 | 
			
		||||
        saveBalance();
 | 
			
		||||
        saveBalances();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setBalance(UUID uuid, long amount) {
 | 
			
		||||
        balances.put(uuid, getBalance(uuid) + amount);
 | 
			
		||||
        balances.put(uuid, amount);
 | 
			
		||||
        saveBalances();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setBalance(ServerPlayerEntity player, long amount) {
 | 
			
		||||
@@ -66,37 +66,63 @@ public class BalanceManager {
 | 
			
		||||
        announceBalance(player, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean saveBalance() {
 | 
			
		||||
    public void saveBalances() {
 | 
			
		||||
        lock.lock();
 | 
			
		||||
        try {
 | 
			
		||||
            FileWriter fileWriter = new FileWriter(balanceStorageFile, false);
 | 
			
		||||
            NbtList nbtList = new NbtList();
 | 
			
		||||
            for (UUID uuid : balances.keySet()) {
 | 
			
		||||
                long balance = getBalance(uuid);
 | 
			
		||||
                fileWriter.write(uuid.toString() + "," + balance + "\n");
 | 
			
		||||
                NbtCompound nbtCompound = new NbtCompound();
 | 
			
		||||
                nbtCompound.putUuid("UUID", uuid);
 | 
			
		||||
                nbtCompound.putLong("Balance", balances.get(uuid));
 | 
			
		||||
                nbtList.add(nbtCompound);
 | 
			
		||||
            }
 | 
			
		||||
            fileWriter.close();
 | 
			
		||||
            lock.unlock();
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            lock.unlock();
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void onJoin(ServerPlayerEntity player) {
 | 
			
		||||
        UUID uuid = player.getUuid();
 | 
			
		||||
        if (!balances.containsKey(uuid)) {
 | 
			
		||||
            balances.put(uuid, 0L);
 | 
			
		||||
            NbtCompound root = new NbtCompound();
 | 
			
		||||
            root.put("Balances", nbtList);
 | 
			
		||||
 | 
			
		||||
            try (FileOutputStream fos = new FileOutputStream(balanceStorageFile);
 | 
			
		||||
                 DataOutputStream dos = new DataOutputStream(fos)) {
 | 
			
		||||
                NbtIo.write(root, dos);
 | 
			
		||||
            }
 | 
			
		||||
        } catch (IOException ignored) {
 | 
			
		||||
        } finally {
 | 
			
		||||
            lock.unlock();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void loadBalance() {
 | 
			
		||||
    public void loadBalances() {
 | 
			
		||||
        lock.lock();
 | 
			
		||||
        if (balanceStorageFile.exists()) {
 | 
			
		||||
            try {
 | 
			
		||||
                NbtCompound root = NbtIo.read(balanceStorageFile.toPath());
 | 
			
		||||
                if (root != null) {
 | 
			
		||||
                    NbtList nbtList = root.getList("Balances", 10);
 | 
			
		||||
 | 
			
		||||
                    for (NbtElement element : nbtList) {
 | 
			
		||||
                        if (element instanceof NbtCompound nbt) {
 | 
			
		||||
                            UUID uuid = nbt.getUuid("UUID");
 | 
			
		||||
                            long balance = nbt.getLong("Balance");
 | 
			
		||||
                            balances.put(uuid, balance);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } catch (
 | 
			
		||||
                    IOException ignored) {
 | 
			
		||||
            } finally {
 | 
			
		||||
                lock.unlock();
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            loadLegacy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void loadLegacy() {
 | 
			
		||||
        lock.lock();
 | 
			
		||||
        if (!balances.isEmpty()) {
 | 
			
		||||
            balances.clear();
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            Scanner scanner = new Scanner(balanceStorageFile);
 | 
			
		||||
            Scanner scanner = new Scanner(balanceStorageCSVFile);
 | 
			
		||||
            while (scanner.hasNextLine()) {
 | 
			
		||||
                String line = scanner.nextLine();
 | 
			
		||||
                String[] lineParts = line.split(",");
 | 
			
		||||
@@ -106,9 +132,10 @@ public class BalanceManager {
 | 
			
		||||
                    balances.put(uuid, amount);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            saveBalances();
 | 
			
		||||
 | 
			
		||||
        } catch (FileNotFoundException ignored) {
 | 
			
		||||
            saveBalance();
 | 
			
		||||
            saveBalances();
 | 
			
		||||
        }
 | 
			
		||||
        lock.unlock();
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,5 @@
 | 
			
		||||
package systems.brn.servershop.lib;
 | 
			
		||||
 | 
			
		||||
public class ItemPriceStorage {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,57 +1,148 @@
 | 
			
		||||
package systems.brn.servershop.lib;
 | 
			
		||||
 | 
			
		||||
import net.minecraft.item.Item;
 | 
			
		||||
import net.minecraft.item.ItemStack;
 | 
			
		||||
import net.minecraft.nbt.*;
 | 
			
		||||
import net.minecraft.registry.Registries;
 | 
			
		||||
import net.minecraft.registry.RegistryWrapper;
 | 
			
		||||
import net.minecraft.server.MinecraftServer;
 | 
			
		||||
import net.minecraft.server.world.ServerWorld;
 | 
			
		||||
import net.minecraft.util.Identifier;
 | 
			
		||||
import net.minecraft.util.WorldSavePath;
 | 
			
		||||
import systems.brn.servershop.ItemPrice;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
import java.io.FileWriter;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
import java.util.Scanner;
 | 
			
		||||
 | 
			
		||||
public class PriceStorage {
 | 
			
		||||
 | 
			
		||||
    public final MinecraftServer server;
 | 
			
		||||
    public final File priceStorageFile;
 | 
			
		||||
    public final File priceStorageCSVFile;
 | 
			
		||||
    public RegistryWrapper.WrapperLookup wrapperLookup;
 | 
			
		||||
 | 
			
		||||
    public PriceStorage(MinecraftServer server) {
 | 
			
		||||
        this.server = server;
 | 
			
		||||
        priceStorageFile = server.getSavePath(WorldSavePath.ROOT).resolve("prices.csv").toFile();
 | 
			
		||||
        priceStorageFile = server.getSavePath(WorldSavePath.ROOT).resolve("prices.dat").toFile();
 | 
			
		||||
        priceStorageCSVFile = server.getSavePath(WorldSavePath.ROOT).resolve("prices.csv").toFile();
 | 
			
		||||
        wrapperLookup = null;
 | 
			
		||||
        for (ServerWorld world : server.getWorlds()) {
 | 
			
		||||
            wrapperLookup = world.getRegistryManager();
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        load();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public final HashMap<Item, ItemPrice> prices = new HashMap<>();
 | 
			
		||||
    public final HashMap<ItemStack, ItemPrice> prices = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
    public void generateEmpty() {
 | 
			
		||||
        if (!prices.isEmpty()) {
 | 
			
		||||
            prices.clear();
 | 
			
		||||
        }
 | 
			
		||||
        for (Item item : Registries.ITEM) {
 | 
			
		||||
            ItemPrice itemPrice = new ItemPrice(0, 0);
 | 
			
		||||
            prices.put(item, itemPrice);
 | 
			
		||||
            ItemPrice itemPrice = new ItemPrice(0, 0, item.getDefaultStack());
 | 
			
		||||
            prices.put(item.getDefaultStack(), itemPrice);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean setPrices(Item item, int buyPrice, int sellPrice) {
 | 
			
		||||
        if (prices.containsKey(item)) {
 | 
			
		||||
            prices.remove(item);
 | 
			
		||||
            prices.put(item, new ItemPrice(buyPrice, sellPrice));
 | 
			
		||||
            return true;
 | 
			
		||||
    public void setPrices(ItemStack inStack, int buyPrice, int sellPrice) {
 | 
			
		||||
        boolean found = false;
 | 
			
		||||
        for (ItemStack priceStack : prices.keySet()) {
 | 
			
		||||
            if (ItemStack.areItemsAndComponentsEqual(inStack, priceStack)) {
 | 
			
		||||
                prices.put(priceStack, new ItemPrice(buyPrice, sellPrice, priceStack));
 | 
			
		||||
                found = true;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
        if (!found) {
 | 
			
		||||
            prices.put(inStack, new ItemPrice(buyPrice, sellPrice, inStack));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ItemPrice getPrices(ItemStack inStack) {
 | 
			
		||||
        for (ItemStack priceStack : prices.keySet()) {
 | 
			
		||||
            if (ItemStack.areItemsAndComponentsEqual(inStack, priceStack)) {
 | 
			
		||||
                return prices.get(priceStack);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return new ItemPrice(0, 0, inStack.copy());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void load() {
 | 
			
		||||
        if (wrapperLookup == null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        prices.clear();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            NbtCompound nbtCompound = NbtIo.read(priceStorageFile.toPath());
 | 
			
		||||
            if (nbtCompound != null && nbtCompound.contains("Prices") && priceStorageFile.exists()) {
 | 
			
		||||
                NbtList nbtList = nbtCompound.getList("Prices", 10); // 10 is the type ID for NbtCompound
 | 
			
		||||
                for (NbtElement element : nbtList) {
 | 
			
		||||
                    if (element instanceof NbtCompound nbt) {
 | 
			
		||||
                        // Deserialize the ItemStack from the NbtCompound
 | 
			
		||||
                        NbtCompound stackNbt = nbt.getCompound("ItemStack");
 | 
			
		||||
                        Optional<ItemStack> stackTemp = ItemStack.fromNbt(wrapperLookup, stackNbt);
 | 
			
		||||
                        if (stackTemp.isPresent()) {
 | 
			
		||||
                            ItemStack stack = stackTemp.get();
 | 
			
		||||
                            // Retrieve the buy and sell prices
 | 
			
		||||
                            int buyPrice = nbt.getInt("BuyPrice");
 | 
			
		||||
                            int sellPrice = nbt.getInt("SellPrice");
 | 
			
		||||
                            if(sellPrice > buyPrice && buyPrice != 0) {
 | 
			
		||||
                                buyPrice = sellPrice;
 | 
			
		||||
                            }
 | 
			
		||||
                            // Add the deserialized ItemStack and ItemPrice to the prices map
 | 
			
		||||
                            prices.put(stack, new ItemPrice(buyPrice, sellPrice, stack));
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                loadLegacy();
 | 
			
		||||
                save();
 | 
			
		||||
            }
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            generateEmpty();
 | 
			
		||||
            save();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean save() {
 | 
			
		||||
        if (wrapperLookup == null) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        NbtList nbtList = new NbtList();
 | 
			
		||||
 | 
			
		||||
        for (ItemStack stack : prices.keySet()) {
 | 
			
		||||
            ItemPrice itemPrice = prices.get(stack);
 | 
			
		||||
            if (!stack.isEmpty()) {
 | 
			
		||||
                nbtList.add(itemPrice.toNbt(wrapperLookup));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        NbtCompound nbtCompound = new NbtCompound();
 | 
			
		||||
        nbtCompound.put("Prices", nbtList);
 | 
			
		||||
 | 
			
		||||
        // Write the NbtList to a file
 | 
			
		||||
        try (FileOutputStream fos = new FileOutputStream(priceStorageFile)) {
 | 
			
		||||
            DataOutputStream dos = new DataOutputStream(fos);
 | 
			
		||||
            NbtIo.write(nbtCompound, dos);
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public void loadLegacy() {
 | 
			
		||||
        if (!prices.isEmpty()) {
 | 
			
		||||
            prices.clear();
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            Scanner scanner = new Scanner(priceStorageFile);
 | 
			
		||||
            Scanner scanner = new Scanner(priceStorageCSVFile);
 | 
			
		||||
            while (scanner.hasNextLine()) {
 | 
			
		||||
                String line = scanner.nextLine();
 | 
			
		||||
                String[] lineParts = line.split(",");
 | 
			
		||||
@@ -63,32 +154,13 @@ public class PriceStorage {
 | 
			
		||||
                        int buyPrice = Integer.parseInt(lineParts[1]);
 | 
			
		||||
                        int sellPrice = Integer.parseInt(lineParts[2]);
 | 
			
		||||
                        Item item = Registries.ITEM.get(itemIdentifier);
 | 
			
		||||
                        prices.put(item, new ItemPrice(buyPrice, sellPrice));
 | 
			
		||||
                        prices.put(item.getDefaultStack(), new ItemPrice(buyPrice, sellPrice, item.getDefaultStack()));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (FileNotFoundException ignored) {
 | 
			
		||||
            generateEmpty();
 | 
			
		||||
            save();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean save() {
 | 
			
		||||
        try {
 | 
			
		||||
            FileWriter fileWriter = new FileWriter(priceStorageFile, false);
 | 
			
		||||
            for (Item item : prices.keySet()) {
 | 
			
		||||
                ItemPrice itemPrice = prices.get(item);
 | 
			
		||||
                String itemName = item.toString();
 | 
			
		||||
                int buyPrice = itemPrice.buyPrice();
 | 
			
		||||
                int sellPrice = itemPrice.sellPrice();
 | 
			
		||||
                fileWriter.write(itemName + "," + buyPrice + "," + sellPrice + "\n");
 | 
			
		||||
            }
 | 
			
		||||
            fileWriter.close();
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
package systems.brn.servershop.lib;
 | 
			
		||||
 | 
			
		||||
import net.minecraft.command.argument.ItemStackArgumentType;
 | 
			
		||||
import net.minecraft.entity.player.PlayerInventory;
 | 
			
		||||
import net.minecraft.item.Item;
 | 
			
		||||
import net.minecraft.item.ItemStack;
 | 
			
		||||
@@ -13,10 +12,9 @@ import static systems.brn.servershop.ServerShop.priceStorage;
 | 
			
		||||
import static systems.brn.servershop.lib.Util.*;
 | 
			
		||||
 | 
			
		||||
public class ShopFunctions {
 | 
			
		||||
    public static void buy(ItemStack itemStack, ServerPlayerEntity player) {
 | 
			
		||||
        Item item = itemStack.getItem();
 | 
			
		||||
    public static void buy(ItemStack itemStack, ServerPlayerEntity player, boolean overlay) {
 | 
			
		||||
        PlayerInventory playerInventory = player.getInventory();
 | 
			
		||||
        ItemPrice price = priceStorage.prices.getOrDefault(item, new ItemPrice(0, 0));
 | 
			
		||||
        ItemPrice price = priceStorage.getPrices(itemStack);
 | 
			
		||||
        int buyPrice = price.buyPrice() * itemStack.getCount();
 | 
			
		||||
        long playerBalance = balanceManager.getBalance(player);
 | 
			
		||||
        if (buyPrice > 0) {
 | 
			
		||||
@@ -26,34 +24,36 @@ public class ShopFunctions {
 | 
			
		||||
                    int toDeduce = buyPrice - (price.buyPrice() * remaining.getCount());
 | 
			
		||||
                    int boughtCount = itemStack.getCount() - remaining.getCount();
 | 
			
		||||
                    balanceManager.removeBalance(player, toDeduce);
 | 
			
		||||
                    player.sendMessage(Text.translatable("message.servershop.buy.success", boughtCount, itemStack.getName(), toDeduce), true);
 | 
			
		||||
                    playerBalance = balanceManager.getBalance(player);
 | 
			
		||||
                    player.sendMessage(Text.translatable("message.servershop.buy.success", boughtCount, itemStack.getName(), toDeduce, playerBalance), overlay);
 | 
			
		||||
                } else {
 | 
			
		||||
                    player.sendMessage(Text.translatable("message.servershop.buy.inventory"), true);
 | 
			
		||||
                    player.sendMessage(Text.translatable("message.servershop.buy.inventory"), overlay);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                player.sendMessage(Text.translatable("message.servershop.buy.not_enough", buyPrice, playerBalance, buyPrice - playerBalance), true);
 | 
			
		||||
                player.sendMessage(Text.translatable("message.servershop.buy.not_enough", buyPrice, playerBalance, buyPrice - playerBalance), overlay);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            player.sendMessage(Text.translatable("message.servershop.buy.not_available", itemStack.getName()), true);
 | 
			
		||||
            player.sendMessage(Text.translatable("message.servershop.buy.not_available", itemStack.getName()), overlay);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void sell(ItemStack itemStack, ServerPlayerEntity player) {
 | 
			
		||||
        Item item = itemStack.getItem();
 | 
			
		||||
    public static void sell(ItemStack itemStack, ServerPlayerEntity player, boolean overlay) {
 | 
			
		||||
        PlayerInventory playerInventory = player.getInventory();
 | 
			
		||||
        ItemPrice price = priceStorage.prices.getOrDefault(item, new ItemPrice(0, 0));
 | 
			
		||||
        ItemPrice price = priceStorage.getPrices(itemStack);
 | 
			
		||||
        int sellPrice = price.sellPrice();
 | 
			
		||||
        if (sellPrice > 0) {
 | 
			
		||||
            int removed = removeFromInventory(playerInventory, itemStack.copy(), itemStack.getCount());
 | 
			
		||||
            if (removed == 0) {
 | 
			
		||||
                player.sendMessage(Text.translatable("message.servershop.sell.not_enough"), true);
 | 
			
		||||
            }
 | 
			
		||||
            int toAdd = sellPrice * (itemStack.getCount() - removed);
 | 
			
		||||
            int soldCount = itemStack.getCount() - removed;
 | 
			
		||||
            int remaining = removeFromInventory(playerInventory, itemStack.copy(), itemStack.getCount());
 | 
			
		||||
            int toAdd = sellPrice * (itemStack.getCount() - remaining);
 | 
			
		||||
            int soldCount = itemStack.getCount() - remaining;
 | 
			
		||||
            balanceManager.addBalance(player, toAdd);
 | 
			
		||||
            player.sendMessage(Text.translatable("message.servershop.sell.success", soldCount, itemStack.getName(), toAdd), true);
 | 
			
		||||
            if (soldCount == 0) {
 | 
			
		||||
                player.sendMessage(Text.translatable("message.servershop.sell.not_enough"), overlay);
 | 
			
		||||
            } else {
 | 
			
		||||
                long playerBalance = balanceManager.getBalance(player);
 | 
			
		||||
                player.sendMessage(Text.translatable("message.servershop.sell.success", soldCount, itemStack.getName(), toAdd, playerBalance), overlay);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            player.sendMessage(Text.translatable("message.servershop.sell.not_available", itemStack.getName()), true);
 | 
			
		||||
            player.sendMessage(Text.translatable("message.servershop.sell.not_available", itemStack.getName()), overlay);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,24 @@
 | 
			
		||||
package systems.brn.servershop.lib;
 | 
			
		||||
 | 
			
		||||
import eu.pb4.polymer.core.api.other.PolymerComponent;
 | 
			
		||||
import net.minecraft.component.ComponentType;
 | 
			
		||||
import net.minecraft.component.DataComponentTypes;
 | 
			
		||||
import net.minecraft.component.type.LoreComponent;
 | 
			
		||||
import net.minecraft.entity.player.PlayerInventory;
 | 
			
		||||
import net.minecraft.inventory.Inventory;
 | 
			
		||||
import net.minecraft.item.ItemStack;
 | 
			
		||||
import net.minecraft.registry.Registries;
 | 
			
		||||
import net.minecraft.registry.Registry;
 | 
			
		||||
import net.minecraft.text.*;
 | 
			
		||||
import net.minecraft.util.Formatting;
 | 
			
		||||
import net.minecraft.util.Identifier;
 | 
			
		||||
import systems.brn.servershop.ItemPrice;
 | 
			
		||||
import systems.brn.servershop.ServerShop;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.function.UnaryOperator;
 | 
			
		||||
 | 
			
		||||
public class Util {
 | 
			
		||||
 | 
			
		||||
    public static Identifier id(String path) {
 | 
			
		||||
@@ -99,4 +112,68 @@ public class Util {
 | 
			
		||||
 | 
			
		||||
        return stack;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ItemStack removePrices(ItemStack stack) {
 | 
			
		||||
        LoreComponent oldLore = stack.get(DataComponentTypes.LORE);
 | 
			
		||||
 | 
			
		||||
        if (oldLore != null) {
 | 
			
		||||
            ItemStack newStack = stack.copy();
 | 
			
		||||
            ArrayList<Text> filteredLines = new ArrayList<>();
 | 
			
		||||
            for (Text text : oldLore.styledLines()) {
 | 
			
		||||
                if (text instanceof MutableText mutableText) {
 | 
			
		||||
                    TextContent textContent = mutableText.getContent();
 | 
			
		||||
                    if (textContent instanceof TranslatableTextContent translatableTextContent) {
 | 
			
		||||
                        String key = translatableTextContent.getKey();
 | 
			
		||||
                        if (!key.equals("gui.servershop.item.buyprice") && !key.equals("gui.servershop.item.sellprice")) {
 | 
			
		||||
                            filteredLines.add(text);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            LoreComponent newLore = new LoreComponent(filteredLines);
 | 
			
		||||
 | 
			
		||||
            newStack.set(DataComponentTypes.LORE, newLore);
 | 
			
		||||
            return newStack;
 | 
			
		||||
        } else {
 | 
			
		||||
            return stack;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ItemStack addPrices(ItemPrice price) {
 | 
			
		||||
        ItemStack stack = price.stack();
 | 
			
		||||
        int buyPrice = price.buyPrice();
 | 
			
		||||
        int sellPrice = price.sellPrice();
 | 
			
		||||
        int count = stack.getCount();
 | 
			
		||||
        if (count > 0) {
 | 
			
		||||
            ItemStack newStack = stack.copy();
 | 
			
		||||
            LoreComponent lore = stack.get(DataComponentTypes.LORE);
 | 
			
		||||
            Text buyLine = Text.translatable("gui.servershop.item.buyprice", buyPrice).setStyle(Style.EMPTY.withColor(Formatting.DARK_GREEN).withItalic(true));
 | 
			
		||||
            Text sellLine = Text.translatable("gui.servershop.item.sellprice", sellPrice).setStyle(Style.EMPTY.withColor(Formatting.AQUA).withItalic(true));
 | 
			
		||||
 | 
			
		||||
            LoreComponent newLore;
 | 
			
		||||
            if (lore == null) {
 | 
			
		||||
                List<Text> loreList = new ArrayList<>();
 | 
			
		||||
                if (buyPrice > 0) {
 | 
			
		||||
                    loreList.addFirst(buyLine);
 | 
			
		||||
                }
 | 
			
		||||
                if (sellPrice > 0) {
 | 
			
		||||
                    loreList.addFirst(sellLine);
 | 
			
		||||
                }
 | 
			
		||||
                newLore = new LoreComponent(loreList);
 | 
			
		||||
            } else {
 | 
			
		||||
                List<Text> newLines = new ArrayList<>(lore.lines());
 | 
			
		||||
                if (buyPrice > 0) {
 | 
			
		||||
                    newLines.addFirst(buyLine);
 | 
			
		||||
                }
 | 
			
		||||
                if (sellPrice > 0) {
 | 
			
		||||
                    newLines.addFirst(sellLine);
 | 
			
		||||
                }
 | 
			
		||||
                newLore = new LoreComponent(newLines);
 | 
			
		||||
            }
 | 
			
		||||
            newStack.set(DataComponentTypes.LORE, newLore);
 | 
			
		||||
            return newStack;
 | 
			
		||||
        } else {
 | 
			
		||||
            return stack;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,10 +3,6 @@ package systems.brn.servershop.screens;
 | 
			
		||||
import eu.pb4.sgui.api.ClickType;
 | 
			
		||||
import eu.pb4.sgui.api.elements.GuiElementBuilder;
 | 
			
		||||
import eu.pb4.sgui.api.elements.GuiElementInterface;
 | 
			
		||||
import net.minecraft.component.DataComponentTypes;
 | 
			
		||||
import net.minecraft.component.type.LoreComponent;
 | 
			
		||||
import net.minecraft.entity.player.PlayerInventory;
 | 
			
		||||
import net.minecraft.item.Item;
 | 
			
		||||
import net.minecraft.item.ItemStack;
 | 
			
		||||
import net.minecraft.item.Items;
 | 
			
		||||
import net.minecraft.screen.slot.SlotActionType;
 | 
			
		||||
@@ -16,11 +12,9 @@ import net.minecraft.util.Formatting;
 | 
			
		||||
import systems.brn.servershop.ItemPrice;
 | 
			
		||||
import systems.brn.servershop.ServerShop;
 | 
			
		||||
import systems.brn.servershop.lib.PagedGui;
 | 
			
		||||
import systems.brn.servershop.lib.ShopFunctions;
 | 
			
		||||
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
import static systems.brn.servershop.ServerShop.balanceManager;
 | 
			
		||||
import static systems.brn.servershop.lib.ShopFunctions.buy;
 | 
			
		||||
import static systems.brn.servershop.lib.ShopFunctions.sell;
 | 
			
		||||
import static systems.brn.servershop.lib.Util.*;
 | 
			
		||||
@@ -29,7 +23,7 @@ public class ShopScreen extends PagedGui {
 | 
			
		||||
 | 
			
		||||
    public String searchQuery = "";
 | 
			
		||||
 | 
			
		||||
    final public HashMap<Item, ItemPrice> filteredPrices = new HashMap<>();
 | 
			
		||||
    final public HashMap<ItemStack, ItemPrice> filteredPrices = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
    public ShopScreen(ServerPlayerEntity player) {
 | 
			
		||||
        super(player, null);
 | 
			
		||||
@@ -50,12 +44,12 @@ public class ShopScreen extends PagedGui {
 | 
			
		||||
 | 
			
		||||
    public void filterPrices() {
 | 
			
		||||
        filteredPrices.clear();
 | 
			
		||||
        for (Item item : ServerShop.priceStorage.prices.keySet()) {
 | 
			
		||||
            String itemName = item.toString();
 | 
			
		||||
        for (ItemStack stack : ServerShop.priceStorage.prices.keySet()) {
 | 
			
		||||
            String itemName = stack.getItem().toString();
 | 
			
		||||
            if (itemName.contains(searchQuery)) {
 | 
			
		||||
                ItemPrice price = ServerShop.priceStorage.prices.get(item);
 | 
			
		||||
                ItemPrice price = ServerShop.priceStorage.getPrices(stack);
 | 
			
		||||
                if (price.buyPrice() > 0 || price.sellPrice() > 0) {
 | 
			
		||||
                    filteredPrices.put(item, price);
 | 
			
		||||
                    filteredPrices.put(stack, price);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -74,45 +68,36 @@ public class ShopScreen extends PagedGui {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean onClick(int index, ClickType type, SlotActionType action, GuiElementInterface element) {
 | 
			
		||||
        Item item = element.getItemStack().getItem();
 | 
			
		||||
        ItemStack itemStack = item.getDefaultStack();
 | 
			
		||||
        if (type.shift) {
 | 
			
		||||
            itemStack.setCount(itemStack.getMaxCount());
 | 
			
		||||
        }
 | 
			
		||||
        if (type.isLeft) { //buy
 | 
			
		||||
            buy(itemStack, player);
 | 
			
		||||
        ItemStack cursorStack = getPlayer().currentScreenHandler.getCursorStack();
 | 
			
		||||
        if (!cursorStack.isEmpty()) {
 | 
			
		||||
            sell(cursorStack, player, true);
 | 
			
		||||
        } else {
 | 
			
		||||
            ItemStack itemStack = removePrices(element.getItemStack());
 | 
			
		||||
            if (type.shift) {
 | 
			
		||||
                itemStack.setCount(itemStack.getMaxCount());
 | 
			
		||||
            }
 | 
			
		||||
            if (type.isLeft) { //buy
 | 
			
		||||
                buy(itemStack.copy(), player, true);
 | 
			
		||||
 | 
			
		||||
        } else if (type.isRight) { //sell
 | 
			
		||||
            sell(itemStack, player);
 | 
			
		||||
            } else if (type.isRight) { //sell
 | 
			
		||||
                sell(itemStack.copy(), player, true);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ItemStack getItemStack(Map.Entry<Item, ItemPrice> price) {
 | 
			
		||||
        ItemPrice itemPrice = price.getValue();
 | 
			
		||||
        Item item = price.getKey();
 | 
			
		||||
        int buyPrice = itemPrice.buyPrice();
 | 
			
		||||
        int sellPrice = itemPrice.sellPrice();
 | 
			
		||||
        ItemStack stack = item.getDefaultStack();
 | 
			
		||||
        LoreComponent originalLore = stack.getOrDefault(DataComponentTypes.LORE, new LoreComponent(List.of()));
 | 
			
		||||
 | 
			
		||||
        ArrayList<Text> lore = new ArrayList<>(originalLore.lines());
 | 
			
		||||
        if (buyPrice > 0) {
 | 
			
		||||
            lore.add(Text.translatable("gui.servershop.item.buyprice", buyPrice));
 | 
			
		||||
        }
 | 
			
		||||
        if (sellPrice > 0) {
 | 
			
		||||
            lore.add(Text.translatable("gui.servershop.item.sellprice", sellPrice));
 | 
			
		||||
        }
 | 
			
		||||
        stack.set(DataComponentTypes.LORE, new LoreComponent(lore));
 | 
			
		||||
        return stack;
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean insertItem(ItemStack stack, int startIndex, int endIndex, boolean fromLast) {
 | 
			
		||||
        sell(stack, player, true);
 | 
			
		||||
        return super.insertItem(stack, startIndex, endIndex, fromLast);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected DisplayElement getElement(int id) {
 | 
			
		||||
        List<Map.Entry<Item, ItemPrice>> list = new ArrayList<>(filteredPrices.entrySet());
 | 
			
		||||
        List<Map.Entry<ItemStack, ItemPrice>> list = new ArrayList<>(filteredPrices.entrySet());
 | 
			
		||||
        if (id < list.size()) {
 | 
			
		||||
            Map.Entry<Item, ItemPrice> itemPriceEntry = list.get(id);
 | 
			
		||||
            ItemStack stack = getItemStack(itemPriceEntry);
 | 
			
		||||
            Map.Entry<ItemStack, ItemPrice> itemPriceEntry = list.get(id);
 | 
			
		||||
            ItemStack stack = addPrices(itemPriceEntry.getValue());
 | 
			
		||||
            GuiElementBuilder elementBuilder = new GuiElementBuilder(stack);
 | 
			
		||||
            return DisplayElement.of(elementBuilder);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,13 @@
 | 
			
		||||
  "message.servershop.balance.set_other": "%s now has %d on his account",
 | 
			
		||||
  "message.servershop.buy.not_enough": "You don't have enough money (%d>%d), you need %d more",
 | 
			
		||||
  "message.servershop.buy.inventory": "You don't have enough inventory space",
 | 
			
		||||
  "message.servershop.buy.success": "You bought %d %s for %d",
 | 
			
		||||
  "message.servershop.buy.success": "You bought %d %s for %d, now you have %d",
 | 
			
		||||
  "message.servershop.buy.not_available": "This item (%s) is not available for buying",
 | 
			
		||||
  "message.servershop.sell.not_enough": "You don't have this item",
 | 
			
		||||
  "message.servershop.sell.success": "You sold %d %s for %d",
 | 
			
		||||
  "message.servershop.sell.not_available": "This item (%s) is not available for sale"
 | 
			
		||||
  "message.servershop.sell.success": "You sold %d %s for %d, now you have %d",
 | 
			
		||||
  "message.servershop.sell.not_available": "This item (%s) is not available for sale",
 | 
			
		||||
  "message.servershop.price.both" : "This item (%s) can be bought for %d and sold for %d",
 | 
			
		||||
  "message.servershop.price.buy" : "This item (%s) can be bought for %d and can't be sold",
 | 
			
		||||
  "message.servershop.price.sell" : "This item (%s) can be sold for %d and can't bought",
 | 
			
		||||
  "message.servershop.price.neither" : "This item (%s) can't be bought or sold"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/main/resources/assets/servershop/textures/icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/main/resources/assets/servershop/textures/icon.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 44 KiB  | 
@@ -7,7 +7,7 @@
 | 
			
		||||
  "authors": [],
 | 
			
		||||
  "contact": {},
 | 
			
		||||
  "license": "MIT",
 | 
			
		||||
  "icon": "assets/servershop/icon.png",
 | 
			
		||||
  "icon": "assets/servershop/textures/icon.png",
 | 
			
		||||
  "environment": "*",
 | 
			
		||||
  "entrypoints": {
 | 
			
		||||
    "main": [
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user