Updatee
This commit is contained in:
parent
346a14c2be
commit
3fbc86e658
@ -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) {
|
||||
ServerShop.priceStorage.setPrices(stack, buyPrice, sellPrice);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
fileWriter.close();
|
||||
lock.unlock();
|
||||
} catch (IOException e) {
|
||||
lock.unlock();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
NbtCompound nbtCompound = new NbtCompound();
|
||||
nbtCompound.putUuid("UUID", uuid);
|
||||
nbtCompound.putLong("Balance", balances.get(uuid));
|
||||
nbtList.add(nbtCompound);
|
||||
}
|
||||
|
||||
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 {
|
||||
player.sendMessage(Text.translatable("message.servershop.sell.not_available", itemStack.getName()), true);
|
||||
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()), 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();
|
||||
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, player);
|
||||
buy(itemStack.copy(), player, true);
|
||||
|
||||
} else if (type.isRight) { //sell
|
||||
sell(itemStack, player);
|
||||
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": [
|
||||
|
Loading…
Reference in New Issue
Block a user