Здравствуйте! Я начинающий разработчик плагинов для Bedrock-серверов (работаю с ядрами Nukkit-MOT, Lumi). Опыт – 2-3 месяца. Писал легкие плагины: Buyer, Auction, экономику, клановую систему ,приваты с помощью блоков и тд . Моя цель: качественно выполненная работа для вас и ценный опыт для меня.
Кто заинтересован, пишите свой тг.
опыта мало
Спасибо за честность именно поэтому я предлагаю свои услуги бесплатно.
Особенности buyer: допустим, игрок покупает кактус 64 штуки. Цена кактуса падает на 1 и рандомно повышается в той же категории на 1 рандомный предмет: если цена предмета 1, то она уже не упадет, и рандомный предмет не повысится на 1 в той же категории. То есть, цена в buyer зависит от игроков если игроки будут много покупать кактус, то цена резко упадет, и цена на другой товар повысится в той же категории так со всеми товарами работает.
Возможно в Java тематике он не 2-3 месяца, а больше
можешь кусок кода скинуть?
окей
package auction.org;
import cn.nukkit.Player;
import cn.nukkit.Server;
import cn.nukkit.command.Command;
import cn.nukkit.command.CommandSender;
import cn.nukkit.event.EventHandler;
import cn.nukkit.event.EventPriority;
import cn.nukkit.event.Listener;
import cn.nukkit.event.inventory.InventoryClickEvent;
import cn.nukkit.event.inventory.InventoryTransactionEvent;
import cn.nukkit.event.player.PlayerQuitEvent;
import cn.nukkit.inventory.InventoryType;
import cn.nukkit.item.Item;
import cn.nukkit.item.enchantment.Enchantment;
import cn.nukkit.nbt.tag.CompoundTag;
import cn.nukkit.scheduler.PluginTask;
import cn.nukkit.utils.Config;
import cn.nukkit.utils.TextFormat;
import com.chelimus4078.RankManagerNukkitMOT;
import me.iwareq.fakeinventories.FakeInventory;
import org.chelimus4078.EconomyManager;
import org.chelimus4078.MainPlugin;
import java.util.*;
public class auctionmanager extends Command implements Listener {
private final auction plugin;
private final Config auctionData;
private final Map<UUID, FakeInventory> openInventories = new HashMap<>();
private final Map<FakeInventory, Integer> auctionPages = new HashMap<>();
private final Map<FakeInventory, Integer> storagePages = new HashMap<>();
private final Set processingPlayers = new HashSet<>();
private String sortMode = “time_desc”;
private List<Map.Entry<String, Map<String, Object>>> cachedSortedLots = null;
private Map<UUID, List<Map.Entry<String, Map<String, Object>>>> cachedSortedStorage = new HashMap<>();
private static final int ITEMS_PER_PAGE = 45;
private static final int DELAY_TICKS = 20;
public auctionmanager(auction plugin) {
super("auc", "Торговая Площадь", "/auc [sell <цена>]", new String[]{"ah", "auction"});
this.plugin = plugin;
this.auctionData = plugin.getConfig();
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@Override
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
if (!(sender instanceof Player)) {
sender.sendMessage(TextFormat.RED + "✘ Это команда только для игроков");
return true;
}
Player player = (Player) sender;
if (args.length > 0 && args[0].equalsIgnoreCase("sell")) {
return itemSell(player, args);
} else if (args.length == 0) {
openAuction(player, 1);
return true;
}
return false;
}
public void openAuction(Player player, int page) {
FakeInventory inventory = new FakeInventory(InventoryType.DOUBLE_CHEST, TextFormat.BOLD.toString() + TextFormat.AQUA + "✨ Торговая Площадь - Страница " + page);
inventory.setDefaultItemHandler((item, event) -> {
// Пустой ItemHandler для предотвращения NullPointerException
});
updateAuctionInventory(inventory, player, page);
auctionPages.put(inventory, page);
openInventories.put(player.getUniqueId(), inventory);
player.addWindow(inventory);
}
public void openStorage(Player player, int page) {
FakeInventory inventory = new FakeInventory(InventoryType.DOUBLE_CHEST, TextFormat.GREEN + "Личное Хранилище - Страница " + page);
inventory.setDefaultItemHandler((item, event) -> {
// Пустой ItemHandler для предотвращения NullPointerException
});
updateStorageInventory(inventory, player, page);
storagePages.put(inventory, page);
openInventories.put(player.getUniqueId(), inventory);
player.addWindow(inventory);
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onInventoryTransaction(InventoryTransactionEvent event) {
if (event.getTransaction().getInventories().stream().anyMatch(inv -> inv instanceof FakeInventory)) {
event.setCancelled(true);
}
}
@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
if (!(event.getInventory() instanceof FakeInventory)) {
return;
}
event.setCancelled(true);
FakeInventory inventory = (FakeInventory) event.getInventory();
Player player = event.getPlayer();
String playerKey = player.getUniqueId().toString() + ":" + System.currentTimeMillis();
if (!processingPlayers.add(playerKey)) {
return;
}
int slot = event.getSlot();
if (slot == -1) {
processingPlayers.remove(playerKey);
return;
}
Item clickedItem = inventory.getItem(slot);
if (clickedItem == null || clickedItem.getId() == 0) {
processingPlayers.remove(playerKey);
return;
}
if (auctionPages.containsKey(inventory)) {
handleAuctionClick(player, inventory, slot, playerKey);
} else if (storagePages.containsKey(inventory)) {
handleStorageClick(player, inventory, slot, playerKey);
} else {
processingPlayers.remove(playerKey);
}
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
String playerKeyPrefix = player.getUniqueId().toString() + ":";
processingPlayers.removeIf(key -> key.startsWith(playerKeyPrefix));
openInventories.remove(player.getUniqueId());
auctionPages.keySet().removeIf(inv -> inv.getViewers().contains(player));
storagePages.keySet().removeIf(inv -> inv.getViewers().contains(player));
cachedSortedStorage.remove(player.getUniqueId());
}
private void handleAuctionClick(Player player, FakeInventory inventory, int slot, String playerKey) {
Integer currentPage = auctionPages.get(inventory);
if (currentPage == null) {
player.sendMessage(TextFormat.RED + "✘ Ошибка: страница торговой площади не найдена!");
plugin.getLogger().error("Страница торговой площади не найдена! Игрок: " + player.getName());
processingPlayers.remove(playerKey);
return;
}
if (!plugin.isEnabled()) {
player.sendMessage(TextFormat.RED + "✘ Плагин отключен, действие невозможно!");
plugin.getLogger().error("Попытка выполнить действие, когда плагин отключен! Игрок: " + player.getName());
processingPlayers.remove(playerKey);
return;
}
Item clickedItem = inventory.getItem(slot);
String action = clickedItem.getNamedTag() != null ? clickedItem.getNamedTag().getString("action") : "";
if (!action.isEmpty()) {
switch (action) {
case "prev":
if (currentPage > 1) {
inventory.close(player);
openInventories.remove(player.getUniqueId());
auctionPages.remove(inventory);
Server.getInstance().getScheduler().scheduleDelayedTask(new PluginTask<>(plugin) {
@Override
public void onRun(int currentTick) {
if (player.isOnline()) {
openAuction(player, currentPage - 1);
}
processingPlayers.remove(playerKey);
}
}, DELAY_TICKS);
} else {
processingPlayers.remove(playerKey);
}
break;
case "next":
@SuppressWarnings("unchecked")
ArrayList<String> order = (ArrayList<String>) auctionData.getList("order", new ArrayList<>());
if (currentPage * ITEMS_PER_PAGE < order.size()) {
inventory.close(player);
openInventories.remove(player.getUniqueId());
auctionPages.remove(inventory);
Server.getInstance().getScheduler().scheduleDelayedTask(new PluginTask<>(plugin) {
@Override
public void onRun(int currentTick) {
if (player.isOnline()) {
openAuction(player, currentPage + 1);
}
processingPlayers.remove(playerKey);
}
}, DELAY_TICKS);
} else {
processingPlayers.remove(playerKey);
}
break;
case "sort_price_asc":
sortMode = "price_asc";
cachedSortedLots = null;
cachedSortedStorage.remove(player.getUniqueId());
inventory.close(player);
openInventories.remove(player.getUniqueId());
auctionPages.remove(inventory);
Server.getInstance().getScheduler().scheduleDelayedTask(new PluginTask<>(plugin) {
@Override
public void onRun(int currentTick) {
if (player.isOnline()) {
openAuction(player, currentPage);
}
processingPlayers.remove(playerKey);
}
}, DELAY_TICKS);
break;
case "sort_price_desc":
sortMode = "price_desc";
cachedSortedLots = null;
cachedSortedStorage.remove(player.getUniqueId());
inventory.close(player);
openInventories.remove(player.getUniqueId());
auctionPages.remove(inventory);
Server.getInstance().getScheduler().scheduleDelayedTask(new PluginTask<>(plugin) {
@Override
public void onRun(int currentTick) {
if (player.isOnline()) {
openAuction(player, currentPage);
}
processingPlayers.remove(playerKey);
}
}, DELAY_TICKS);
break;
case "sort_time_asc":
sortMode = "time_asc";
cachedSortedLots = null;
cachedSortedStorage.remove(player.getUniqueId());
inventory.close(player);
openInventories.remove(player.getUniqueId());
auctionPages.remove(inventory);
Server.getInstance().getScheduler().scheduleDelayedTask(new PluginTask<>(plugin) {
@Override
public void onRun(int currentTick) {
if (player.isOnline()) {
openAuction(player, currentPage);
}
processingPlayers.remove(playerKey);
}
}, DELAY_TICKS);
break;
case "sort_time_desc":
sortMode = "time_desc";
cachedSortedLots = null;
cachedSortedStorage.remove(player.getUniqueId());
inventory.close(player);
openInventories.remove(player.getUniqueId());
auctionPages.remove(inventory);
Server.getInstance().getScheduler().scheduleDelayedTask(new PluginTask<>(plugin) {
@Override
public void onRun(int currentTick) {
if (player.isOnline()) {
openAuction(player, currentPage);
}
processingPlayers.remove(playerKey);
}
}, DELAY_TICKS);
break;
case "sort_item_asc":
sortMode = "item_asc";
cachedSortedLots = null;
cachedSortedStorage.remove(player.getUniqueId());
inventory.close(player);
openInventories.remove(player.getUniqueId());
auctionPages.remove(inventory);
Server.getInstance().getScheduler().scheduleDelayedTask(new PluginTask<>(plugin) {
@Override
public void onRun(int currentTick) {
if (player.isOnline()) {
openAuction(player, currentPage);
}
processingPlayers.remove(playerKey);
}
}, DELAY_TICKS);
break;
case "storage":
inventory.close(player);
openInventories.remove(player.getUniqueId());
auctionPages.remove(inventory);
Server.getInstance().getScheduler().scheduleDelayedTask(new PluginTask<>(plugin) {
@Override
public void onRun(int currentTick) {
if (player.isOnline()) {
openStorage(player, 1);
}
processingPlayers.remove(playerKey);
}
}, DELAY_TICKS);
break;
case "close":
inventory.close(player);
openInventories.remove(player.getUniqueId());
auctionPages.remove(inventory);
processingPlayers.remove(playerKey);
break;
}
return;
}
List<Map.Entry<String, Map<String, Object>>> sortedLots = getSortedLots();
if (sortedLots.isEmpty()) {
player.sendMessage(TextFormat.GRAY + "Торговая площадь пуста!");
processingPlayers.remove(playerKey);
return;
}
int index = (currentPage - 1) * ITEMS_PER_PAGE + slot;
if (index >= sortedLots.size() || index < 0) {
player.sendMessage(TextFormat.RED + "✘ Ошибка: предмет не найден!");
plugin.getLogger().error("Неверный индекс предмета: " + index + ", игрок: " + player.getName());
processingPlayers.remove(playerKey);
return;
}
String auctionId = sortedLots.get(index).getKey();
Map<String, Object> entry = sortedLots.get(index).getValue();
if (entry == null) {
player.sendMessage(TextFormat.RED + "✘ Ошибка: предмет не найден!");
plugin.getLogger().error("Предмет не найден в конфиге: " + auctionId + ", игрок: " + player.getName());
processingPlayers.remove(playerKey);
return;
}
String ownerUUID = (String) entry.get("owner_uuid");
@SuppressWarnings("unchecked")
ArrayList<String> order = (ArrayList<String>) auctionData.getList("order", new ArrayList<>());
int orderIndex = order.indexOf(auctionId);
if (orderIndex == -1) {
player.sendMessage(TextFormat.RED + "✘ Ошибка: предмет не найден в списке!");
plugin.getLogger().error("Предмет не найден в order: " + auctionId + ", игрок: " + player.getName());
processingPlayers.remove(playerKey);
return;
}
if (ownerUUID.equals(player.getUniqueId().toString())) {
returnToStorage(player, auctionId, entry, order, orderIndex);
inventory.close(player);
openInventories.remove(player.getUniqueId());
auctionPages.remove(inventory);
Server.getInstance().getScheduler().scheduleDelayedTask(new PluginTask<>(plugin) {
@Override
public void onRun(int currentTick) {
if (player.isOnline()) {
openAuction(player, currentPage);
}
processingPlayers.remove(playerKey);
}
}, DELAY_TICKS);
} else {
buyItem(player, auctionId, entry, order, orderIndex);
inventory.close(player);
openInventories.remove(player.getUniqueId());
auctionPages.remove(inventory);
Server.getInstance().getScheduler().scheduleDelayedTask(new PluginTask<>(plugin) {
@Override
public void onRun(int currentTick) {
if (player.isOnline()) {
openAuction(player, currentPage);
}
processingPlayers.remove(playerKey);
}
}, DELAY_TICKS);
}
}
private void handleStorageClick(Player player, FakeInventory inventory, int slot, String playerKey) {
Integer currentPage = storagePages.get(inventory);
if (currentPage == null) {
player.sendMessage(TextFormat.RED + "✘ Ошибка: страница хранилища не найдена!");
plugin.getLogger().error("Страница хранилища не найдена! Игрок: " + player.getName());
processingPlayers.remove(playerKey);
return;
}
if (!plugin.isEnabled()) {
player.sendMessage(TextFormat.RED + "✘ Плагин отключен, действие невозможно!");
plugin.getLogger().error("Попытка выполнить действие, когда плагин отключен! Игрок: " + player.getName());
processingPlayers.remove(playerKey);
return;
}
Item clickedItem = inventory.getItem(slot);
String action = clickedItem.getNamedTag() != null ? clickedItem.getNamedTag().getString("action") : "";
if (!action.isEmpty()) {
switch (action) {
case "prev":
if (currentPage > 1) {
inventory.close(player);
openInventories.remove(player.getUniqueId());
storagePages.remove(inventory);
Server.getInstance().getScheduler().scheduleDelayedTask(new PluginTask<>(plugin) {
@Override
public void onRun(int currentTick) {
if (player.isOnline()) {
openStorage(player, currentPage - 1);
}
processingPlayers.remove(playerKey);
}
}, DELAY_TICKS);
} else {
processingPlayers.remove(playerKey);
}
break;
case "next":
@SuppressWarnings("unchecked")
ArrayList<String> storageOrder = (ArrayList<String>) auctionData.getList("storage." + player.getUniqueId(), new ArrayList<>());
if (currentPage * ITEMS_PER_PAGE < storageOrder.size()) {
inventory.close(player);
openInventories.remove(player.getUniqueId());
storagePages.remove(inventory);
Server.getInstance().getScheduler().scheduleDelayedTask(new PluginTask<>(plugin) {
@Override
public void onRun(int currentTick) {
if (player.isOnline()) {
openStorage(player, currentPage + 1);
}
processingPlayers.remove(playerKey);
}
}, DELAY_TICKS);
} else {
processingPlayers.remove(playerKey);
}
break;
case "back":
inventory.close(player);
openInventories.remove(player.getUniqueId());
storagePages.remove(inventory);
Server.getInstance().getScheduler().scheduleDelayedTask(new PluginTask<>(plugin) {
@Override
public void onRun(int currentTick) {
if (player.isOnline()) {
openAuction(player, 1);
}
processingPlayers.remove(playerKey);
}
}, DELAY_TICKS);
break;
case "close":
inventory.close(player);
openInventories.remove(player.getUniqueId());
storagePages.remove(inventory);
processingPlayers.remove(playerKey);
break;
}
return;
}
List<Map.Entry<String, Map<String, Object>>> sortedStorage = getSortedStorage(player.getUniqueId());
if (sortedStorage.isEmpty()) {
player.sendMessage(TextFormat.GRAY + "Личное хранилище пусто!");
processingPlayers.remove(playerKey);
return;
}
int index = (currentPage - 1) * ITEMS_PER_PAGE + slot;
if (index >= sortedStorage.size() || index < 0) {
player.sendMessage(TextFormat.RED + "✘ Ошибка: предмет не найден!");
plugin.getLogger().error("Неверный индекс предмета в хранилище: " + index + ", игрок: " + player.getName());
processingPlayers.remove(playerKey);
return;
}
String storageId = sortedStorage.get(index).getKey();
Map<String, Object> entry = sortedStorage.get(index).getValue();
if (entry == null) {
player.sendMessage(TextFormat.RED + "✘ Ошибка: предмет не найден!");
plugin.getLogger().error("Предмет не найден в хранилище: " + storageId + ", игрок: " + player.getName());
processingPlayers.remove(playerKey);
return;
}
Item item = createItemFromEntry(entry);
if (item == null) {
player.sendMessage(TextFormat.RED + "✘ Ошибка: предмет поврежден!");
plugin.getLogger().error("Не удалось создать предмет для storageId #" + storageId);
processingPlayers.remove(playerKey);
return;
}
if (player.getInventory().canAddItem(item)) {
player.getInventory().addItem(item);
auctionData.remove("storage_items." + storageId);
@SuppressWarnings("unchecked")
ArrayList<String> storageOrder = (ArrayList<String>) auctionData.getList("storage." + player.getUniqueId(), new ArrayList<>());
storageOrder.remove(storageId);
auctionData.set("storage." + player.getUniqueId(), storageOrder);
auctionData.save();
cachedSortedStorage.remove(player.getUniqueId());
player.sendMessage(TextFormat.GREEN + "✔ Предмет успешно забран из хранилища!");
inventory.close(player);
openInventories.remove(player.getUniqueId());
storagePages.remove(inventory);
Server.getInstance().getScheduler().scheduleDelayedTask(new PluginTask<>(plugin) {
@Override
public void onRun(int currentTick) {
if (player.isOnline()) {
openStorage(player, currentPage);
}
processingPlayers.remove(playerKey);
}
}, DELAY_TICKS);
} else {
player.sendMessage(TextFormat.RED + "✘ Ваш инвентарь полон!");
processingPlayers.remove(playerKey);
}
}
private void updateAuctionInventory(FakeInventory inventory, Player player, int page) {
@SuppressWarnings("unchecked")
ArrayList<String> order = (ArrayList<String>) auctionData.getList("order", new ArrayList<>());
List<Map.Entry<String, Map<String, Object>>> sortedLots = getSortedLots();
int maxPage = sortedLots.isEmpty() ? 1 : (sortedLots.size() + ITEMS_PER_PAGE - 1) / ITEMS_PER_PAGE;
page = Math.max(1, Math.min(page, maxPage));
inventory.clearAll();
int start = (page - 1) * ITEMS_PER_PAGE;
int end = Math.min(start + ITEMS_PER_PAGE, sortedLots.size());
for (int i = start; i < end; i++) {
String auctionId = sortedLots.get(i).getKey();
Map<String, Object> entry = sortedLots.get(i).getValue();
Item displayItem = createItemFromEntry(entry);
if (displayItem == null) {
plugin.getLogger().error("Не удалось создать предмет для auctionId #" + auctionId);
continue;
}
double price = ((Number) entry.get("price")).doubleValue();
String ownerName = (String) entry.get("owner_name");
List<String> lore = new ArrayList<>();
lore.add(TextFormat.GRAY + "Владелец: " + TextFormat.WHITE + ownerName);
lore.add(TextFormat.GRAY + "Цена: " + TextFormat.GOLD + price);
lore.add(TextFormat.GRAY + "Количество: " + TextFormat.WHITE + displayItem.getCount());
if (displayItem.getMaxDurability() > 0) {
lore.add(TextFormat.GRAY + "Прочность: " + TextFormat.WHITE + (displayItem.getMaxDurability() - displayItem.getDamage()) + "/" + displayItem.getMaxDurability());
}
if (displayItem.hasEnchantments()) {
lore.add(TextFormat.GRAY + "Чары:");
for (Enchantment ench : displayItem.getEnchantments()) {
lore.add(TextFormat.AQUA + ench.getName() + " " + ench.getLevel());
}
}
lore.add(TextFormat.YELLOW + (entry.get("owner_uuid").equals(player.getUniqueId().toString()) ? "Нажмите, чтобы вернуть" : "Нажмите, чтобы купить"));
displayItem.setLore(lore.toArray(new String[0]));
inventory.setItem(i - start, displayItem);
}
Item prevItem = Item.get(Item.ARROW);
prevItem.setNamedTag(new CompoundTag().putString("action", "prev"));
prevItem.setCustomName(page > 1 ? TextFormat.YELLOW + "Предыдущая страница" : TextFormat.GRAY + "Предыдущая страница");
inventory.setItem(48, prevItem);
Item storageItem = Item.get(Item.CHEST);
storageItem.setNamedTag(new CompoundTag().putString("action", "storage"));
storageItem.setCustomName(TextFormat.GREEN + "Личное Хранилище");
inventory.setItem(49, storageItem);
Item nextItem = Item.get(Item.ARROW);
nextItem.setNamedTag(new CompoundTag().putString("action", "next"));
nextItem.setCustomName((end < sortedLots.size()) ? TextFormat.YELLOW + "Следующая страница" : TextFormat.GRAY + "Следующая страница");
inventory.setItem(50, nextItem);
Item sortPriceAsc = Item.get(Item.GOLD_INGOT);
sortPriceAsc.setNamedTag(new CompoundTag().putString("action", "sort_price_asc"));
sortPriceAsc.setCustomName(TextFormat.AQUA + " По стоимости (возр.)");
inventory.setItem(45, sortPriceAsc);
Item sortPriceDesc = Item.get(Item.GOLD_INGOT);
sortPriceDesc.setNamedTag(new CompoundTag().putString("action", "sort_price_desc"));
sortPriceDesc.setCustomName(TextFormat.AQUA + " По стоимости (убыв.)");
inventory.setItem(46, sortPriceDesc);
Item sortTimeAsc = Item.get(Item.CLOCK);
sortTimeAsc.setNamedTag(new CompoundTag().putString("action", "sort_time_asc"));
sortTimeAsc.setCustomName(TextFormat.AQUA + "\uE12C По дате (старые)");
inventory.setItem(47, sortTimeAsc);
Item sortTimeDesc = Item.get(Item.CLOCK);
sortTimeDesc.setNamedTag(new CompoundTag().putString("action", "sort_time_desc"));
sortTimeDesc.setCustomName(TextFormat.AQUA + " По дате (новые)");
inventory.setItem(51, sortTimeDesc);
Item sortItemAsc = Item.get(Item.BOOK);
sortItemAsc.setNamedTag(new CompoundTag().putString("action", "sort_item_asc"));
sortItemAsc.setCustomName(TextFormat.AQUA + " По алфавиту (A-Я)");
inventory.setItem(52, sortItemAsc);
Item closeButton = Item.get(Item.BARRIER);
closeButton.setNamedTag(new CompoundTag().putString("action", "close"));
closeButton.setCustomName(TextFormat.BOLD.toString() + TextFormat.RED + "✖ Закрыть");
inventory.setItem(53, closeButton);
auctionPages.put(inventory, page);
}
private void updateStorageInventory(FakeInventory inventory, Player player, int page) {
@SuppressWarnings("unchecked")
ArrayList<String> storageOrder = (ArrayList<String>) auctionData.getList("storage." + player.getUniqueId(), new ArrayList<>());
List<Map.Entry<String, Map<String, Object>>> sortedStorage = getSortedStorage(player.getUniqueId());
int maxPage = sortedStorage.isEmpty() ? 1 : (sortedStorage.size() + ITEMS_PER_PAGE - 1) / ITEMS_PER_PAGE;
page = Math.max(1, Math.min(page, maxPage));
inventory.clearAll();
int start = (page - 1) * ITEMS_PER_PAGE;
int end = Math.min(start + ITEMS_PER_PAGE, sortedStorage.size());
for (int i = start; i < end; i++) {
String storageId = sortedStorage.get(i).getKey();
Map<String, Object> entry = sortedStorage.get(i).getValue();
Item displayItem = createItemFromEntry(entry);
if (displayItem == null) {
plugin.getLogger().error("Не удалось создать предмет для storageId #" + storageId);
continue;
}
List<String> lore = new ArrayList<>();
lore.add(TextFormat.GRAY + "Количество: " + TextFormat.WHITE + displayItem.getCount());
if (displayItem.getMaxDurability() > 0) {
lore.add(TextFormat.GRAY + "Прочность: " + TextFormat.WHITE + (displayItem.getMaxDurability() - displayItem.getDamage()) + "/" + displayItem.getMaxDurability());
}
if (displayItem.hasEnchantments()) {
lore.add(TextFormat.GRAY + "Чары:");
for (Enchantment ench : displayItem.getEnchantments()) {
lore.add(TextFormat.AQUA + ench.getName() + " " + ench.getLevel());
}
}
lore.add(TextFormat.YELLOW + "Нажмите, чтобы забрать");
displayItem.setLore(lore.toArray(new String[0]));
inventory.setItem(i - start, displayItem);
}
Item prevItem = Item.get(Item.ARROW);
prevItem.setNamedTag(new CompoundTag().putString("action", "prev"));
prevItem.setCustomName(page > 1 ? TextFormat.YELLOW + "Предыдущая страница" : TextFormat.GRAY + "Предыдущая страница");
inventory.setItem(48, prevItem);
Item backItem = Item.get(Item.COMPASS);
backItem.setNamedTag(new CompoundTag().putString("action", "back"));
backItem.setCustomName(TextFormat.RED + "Вернуться на Торговую Площадь");
inventory.setItem(49, backItem);
Item nextItem = Item.get(Item.ARROW);
nextItem.setNamedTag(new CompoundTag().putString("action", "next"));
nextItem.setCustomName((end < sortedStorage.size()) ? TextFormat.YELLOW + "Следующая страница" : TextFormat.GRAY + "Следующая страница");
inventory.setItem(50, nextItem);
Item closeButton = Item.get(Item.BARRIER);
closeButton.setNamedTag(new CompoundTag().putString("action", "close"));
closeButton.setCustomName(TextFormat.BOLD.toString() + TextFormat.RED + "✖ Закрыть");
inventory.setItem(53, closeButton);
storagePages.put(inventory, page);
}
private List<Map.Entry<String, Map<String, Object>>> getSortedLots() {
if (cachedSortedLots != null) {
return cachedSortedLots;
}
List<Map.Entry<String, Map<String, Object>>> lots = new ArrayList<>();
@SuppressWarnings("unchecked")
ArrayList<String> order = (ArrayList<String>) auctionData.getList("order", new ArrayList<>());
for (String auctionId : order) {
Map<String, Object> lot = (Map<String, Object>) auctionData.get("auctions." + auctionId);
if (lot == null || !lot.containsKey("timestamp") || !lot.containsKey("price") || !lot.containsKey("owner_uuid") || !lot.containsKey("item_id")) {
plugin.getLogger().error("Лот #" + auctionId + " поврежден (отсутствуют обязательные ключи) и будет пропущен: " + (lot != null ? lot.toString() : "null"));
continue;
}
lots.add(new AbstractMap.SimpleEntry<>(auctionId, lot));
}
lots.sort((entry1, entry2) -> {
Map<String, Object> lot1 = entry1.getValue();
Map<String, Object> lot2 = entry2.getValue();
switch (sortMode) {
case "price_asc":
return Double.compare(((Number) lot1.get("price")).doubleValue(), ((Number) lot2.get("price")).doubleValue());
case "price_desc":
return Double.compare(((Number) lot2.get("price")).doubleValue(), ((Number) lot1.get("price")).doubleValue());
case "time_asc":
case "time_desc":
Long timestamp1 = (Long) lot1.get("timestamp");
Long timestamp2 = (Long) lot2.get("timestamp");
long t1 = timestamp1 != null ? timestamp1 : 0;
long t2 = timestamp2 != null ? timestamp2 : 0;
return sortMode.equals("time_asc") ? Long.compare(t1, t2) : Long.compare(t2, t1);
case "item_asc":
Item item1 = createItemFromEntry(lot1);
Item item2 = createItemFromEntry(lot2);
String name1 = item1 != null ? (item1.hasCustomName() ? item1.getCustomName() : item1.getName()) : "";
String name2 = item2 != null ? (item2.hasCustomName() ? item2.getCustomName() : item2.getName()) : "";
return name1.compareToIgnoreCase(name2);
default:
return 0;
}
});
cachedSortedLots = lots;
return lots;
}
private List<Map.Entry<String, Map<String, Object>>> getSortedStorage(UUID playerUUID) {
List<Map.Entry<String, Map<String, Object>>> cached = cachedSortedStorage.get(playerUUID);
if (cached != null) {
return cached;
}
List<Map.Entry<String, Map<String, Object>>> items = new ArrayList<>();
@SuppressWarnings("unchecked")
ArrayList<String> storageOrder = (ArrayList<String>) auctionData.getList("storage." + playerUUID, new ArrayList<>());
for (String storageId : storageOrder) {
Map<String, Object> item = (Map<String, Object>) auctionData.get("storage_items." + storageId);
if (item == null || !item.containsKey("timestamp") || !item.containsKey("item_id")) {
plugin.getLogger().error("Предмет хранилища #" + storageId + " поврежден (отсутствуют обязательные ключи) и будет пропущен: " + (item != null ? item.toString() : "null"));
continue;
}
items.add(new AbstractMap.SimpleEntry<>(storageId, item));
}
items.sort((entry1, entry2) -> {
Map<String, Object> item1 = entry1.getValue();
Map<String, Object> item2 = entry2.getValue();
switch (sortMode) {
case "price_asc":
case "price_desc":
return sortMode.equals("price_asc") ?
Integer.compare(((Number) item1.get("item_id")).intValue(), ((Number) item2.get("item_id")).intValue()) :
Integer.compare(((Number) item2.get("item_id")).intValue(), ((Number) item1.get("item_id")).intValue());
case "time_asc":
case "time_desc":
Long timestamp1 = (Long) item1.get("timestamp");
Long timestamp2 = (Long) item2.get("timestamp");
long t1 = timestamp1 != null ? timestamp1 : 0;
long t2 = timestamp2 != null ? timestamp2 : 0;
return sortMode.equals("time_asc") ? Long.compare(t1, t2) : Long.compare(t2, t1);
case "item_asc":
Item itemObj1 = createItemFromEntry(item1);
Item itemObj2 = createItemFromEntry(item2);
String name1 = itemObj1 != null ? (itemObj1.hasCustomName() ? itemObj1.getCustomName() : itemObj1.getName()) : "";
String name2 = itemObj2 != null ? (itemObj2.hasCustomName() ? itemObj2.getCustomName() : itemObj2.getName()) : "";
return name1.compareToIgnoreCase(name2);
default:
return 0;
}
});
cachedSortedStorage.put(playerUUID, items);
return items;
}
private Item createItemFromEntry(Map<String, Object> entry) {
try {
int itemId = ((Number) entry.get("item_id")).intValue();
int itemDamage = ((Number) entry.get("item_damage")).intValue();
int itemCount = ((Number) entry.get("item_count")).intValue();
int itemDurability = ((Number) entry.get("item_durability")).intValue();
Item item = Item.get(itemId, itemDamage, itemCount);
if (itemDurability > 0) {
item.setDamage(item.getMaxDurability() - itemDurability);
}
@SuppressWarnings("unchecked")
ArrayList<Map<String, Object>> enchantmentsList = (ArrayList<Map<String, Object>>) entry.get("enchantments");
for (Map<String, Object> enchData : enchantmentsList) {
int enchId = ((Number) enchData.get("id")).intValue();
int level = ((Number) enchData.get("level")).intValue();
Enchantment ench = Enchantment.getEnchantment(enchId).setLevel(level);
item.addEnchantment(ench);
}
return item;
} catch (Exception e) {
plugin.getLogger().error("Ошибка при создании предмета: " + e.getMessage());
return null;
}
}
private Map<String, Integer> getRankLimits(Player player) {
RankManagerNukkitMOT rankManager = (RankManagerNukkitMOT) plugin.getServer().getPluginManager().getPlugin("RankManagerNukkit-MOT");
String rank = rankManager != null ? rankManager.getPlayerRank(player) : "default";
return plugin.getRankLimits(rank);
}
public boolean itemSell(Player player, String[] args) {
if (args.length < 2) {
player.sendMessage(TextFormat.DARK_RED + "✘ Использование: " + TextFormat.AQUA + "/auc " + TextFormat.GOLD + "sell " + TextFormat.GRAY + "цена");
return true;
}
// Проверка лимита лотов на аукционе
Map<String, Integer> limits = getRankLimits(player);
int auctionLimit = limits.get("auction");
@SuppressWarnings("unchecked")
ArrayList<String> order = (ArrayList<String>) auctionData.getList("order", new ArrayList<>());
long playerLots = order.stream()
.filter(id -> {
Map<String, Object> lot = (Map<String, Object>) auctionData.get("auctions." + id);
return lot != null && lot.get("owner_uuid").equals(player.getUniqueId().toString());
})
.count();
if (playerLots >= auctionLimit) {
player.sendMessage(TextFormat.DARK_RED + "✘ Вы достигли лимита лотов на аукционе (" + auctionLimit + ") для вашего ранга!");
return true;
}
double price;
try {
price = Double.parseDouble(args[1]);
if (price <= 0) {
player.sendMessage(TextFormat.DARK_RED + "✘ Цена должна быть " + TextFormat.GOLD + "положительным " + TextFormat.GRAY + "числом!");
return true;
}
} catch (NumberFormatException e) {
player.sendMessage(TextFormat.DARK_RED + "✘ Цена должна быть " + TextFormat.GOLD + "числом " + TextFormat.GRAY + "(например, 10 или 10.5)!");
return true;
}
MainPlugin mainPlugin = MainPlugin.getInstance();
if (mainPlugin == null) {
player.sendMessage(TextFormat.RED + "✘ Ошибка экономической системы!");
plugin.getLogger().error("MainPlugin не инициализирован! Игрок: " + player.getName());
return true;
}
EconomyManager economyManager = mainPlugin.getEconomyManager();
if (economyManager == null) {
player.sendMessage(TextFormat.RED + "✘ Экономика не инициализирована!");
plugin.getLogger().error("EconomyManager не инициализирован! Игрок: " + player.getName());
return true;
}
Item itemInHand = player.getInventory().getItemInHand();
if (itemInHand == null || itemInHand.getId() == 0) {
player.sendMessage(TextFormat.RED + "✘ В руке нет предмета! " + TextFormat.GOLD + "Возьмите в руку предмет " + TextFormat.GRAY + "чтобы продать");
return true;
}
int itemId = itemInHand.getId();
int itemCount = itemInHand.getCount();
int itemDamage = itemInHand.getDamage();
int itemDurability = itemInHand.getMaxDurability() > 0 ? itemInHand.getMaxDurability() - itemInHand.getDamage() : 0;
Enchantment[] enchantments = itemInHand.getEnchantments();
ArrayList<Map<String, Object>> enchantmentsList = new ArrayList<>();
for (Enchantment enchantment : enchantments) {
Map<String, Object> enchantmentData = new HashMap<>();
enchantmentData.put("id", enchantment.getId());
enchantmentData.put("level", enchantment.getLevel());
enchantmentData.put("name", enchantment.getName());
enchantmentsList.add(enchantmentData);
}
player.getInventory().setItemInHand(Item.get(0));
String auctionEntryId = UUID.randomUUID().toString();
Map<String, Object> auctionEntry = new HashMap<>();
auctionEntry.put("owner_uuid", player.getUniqueId().toString());
auctionEntry.put("owner_name", player.getName());
auctionEntry.put("item_id", itemId);
auctionEntry.put("item_count", itemCount);
auctionEntry.put("item_damage", itemDamage);
auctionEntry.put("item_durability", itemDurability);
auctionEntry.put("enchantments", enchantmentsList);
auctionEntry.put("price", price);
auctionEntry.put("timestamp", System.currentTimeMillis());
auctionData.set("auctions." + auctionEntryId, auctionEntry);
order.add(0, auctionEntryId);
auctionData.set("order", order);
auctionData.save();
cachedSortedLots = null;
player.sendMessage(TextFormat.GREEN + "✔ Предмет успешно выставлен на торговую площадь за " + TextFormat.GOLD + price + TextFormat.GRAY + "!");
return true;
}
private void returnToStorage(Player player, String auctionId, Map<String, Object> entry, ArrayList<String> order, int index) {
// Проверка лимита хранилища
Map<String, Integer> limits = getRankLimits(player);
int storageLimit = limits.get("storage");
@SuppressWarnings("unchecked")
ArrayList<String> storageOrder = (ArrayList<String>) auctionData.getList("storage." + player.getUniqueId(), new ArrayList<>());
if (storageOrder.size() >= storageLimit) {
player.sendMessage(TextFormat.DARK_RED + "✘ Ваше хранилище заполнено! Лимит: " + storageLimit + " предметов для вашего ранга.");
return;
}
String storageEntryId = UUID.randomUUID().toString();
Map<String, Object> storageEntry = new HashMap<>();
storageEntry.put("item_id", entry.get("item_id"));
storageEntry.put("item_damage", entry.get("item_damage"));
storageEntry.put("item_count", entry.get("item_count"));
storageEntry.put("item_durability", entry.get("item_durability"));
storageEntry.put("enchantments", entry.get("enchantments"));
storageEntry.put("timestamp", System.currentTimeMillis());
auctionData.set("storage_items." + storageEntryId, storageEntry);
storageOrder.add(0, storageEntryId);
auctionData.set("storage." + player.getUniqueId(), storageOrder);
auctionData.remove("auctions." + auctionId);
order.remove(index);
auctionData.set("order", order);
auctionData.save();
cachedSortedLots = null;
cachedSortedStorage.remove(player.getUniqueId());
player.sendMessage(TextFormat.GREEN + "✔ Ваш предмет возвращен в личное хранилище!");
}
private void buyItem(Player player, String auctionId, Map<String, Object> entry, ArrayList<String> order, int index) {
MainPlugin mainPlugin = MainPlugin.getInstance();
if (mainPlugin == null) {
player.sendMessage(TextFormat.RED + "✘ Ошибка экономической системы!");
plugin.getLogger().error("MainPlugin не инициализирован! Игрок: " + player.getName());
return;
}
EconomyManager economyManager = mainPlugin.getEconomyManager();
if (economyManager == null) {
player.sendMessage(TextFormat.RED + "✘ Экономика не инициализирована!");
plugin.getLogger().error("EconomyManager не инициализирован! Игрок: " + player.getName());
return;
}
Map<String, Integer> limits = getRankLimits(player);
int storageLimit = limits.get("storage");
@SuppressWarnings("unchecked")
ArrayList<String> storageOrder = (ArrayList<String>) auctionData.getList("storage." + player.getUniqueId(), new ArrayList<>());
if (storageOrder.size() >= storageLimit) {
player.sendMessage(TextFormat.DARK_RED + "✘ Ваше хранилище заполнено! Лимит: " + storageLimit + " предметов для вашего ранга.");
return;
}
double price = ((Number) entry.get("price")).doubleValue();
String ownerUUID = (String) entry.get("owner_uuid");
double balance = economyManager.getBalance(player.getUniqueId());
if (balance < price) {
player.sendMessage(TextFormat.DARK_RED + "✘ Недостаточно средств!");
return;
}
boolean success = economyManager.transferMoney(player, UUID.fromString(ownerUUID), price);
if (!success) {
player.sendMessage(TextFormat.RED + "✘ Ошибка перевода средств!");
plugin.getLogger().error("Ошибка перевода средств для игрока: " + player.getName());
return;
}
String storageEntryId = UUID.randomUUID().toString();
Map<String, Object> storageEntry = new HashMap<>();
storageEntry.put("item_id", entry.get("item_id"));
storageEntry.put("item_damage", entry.get("item_damage"));
storageEntry.put("item_count", entry.get("item_count"));
storageEntry.put("item_durability", entry.get("item_durability"));
storageEntry.put("enchantments", entry.get("enchantments"));
storageEntry.put("timestamp", System.currentTimeMillis());
auctionData.set("storage_items." + storageEntryId, storageEntry);
storageOrder.add(0, storageEntryId);
auctionData.set("storage." + player.getUniqueId(), storageOrder);
auctionData.remove("auctions." + auctionId);
order.remove(index);
auctionData.set("order", order);
auctionData.save();
cachedSortedLots = null;
cachedSortedStorage.remove(player.getUniqueId());
player.sendMessage(TextFormat.GREEN + "✔ Предмет успешно куплен за " + TextFormat.GOLD + price + " и отправлен в личное хранилище!");
Optional<Player> owner = plugin.getServer().getPlayer(UUID.fromString(ownerUUID));
owner.ifPresent(p -> p.sendMessage(TextFormat.GREEN + player.getName() + " купил твой предмет за " + TextFormat.GOLD + price + "!"));
}
}
ООП бы еще , а так для 2-3х месяцев хорошо
нет, фигня
забыл что за 2-3 месяца писал?)
Спасибо, просто я школьник, из-за этого много свободного времени. лето = много свободного времени.
в целом если будешь развиваться в java и улучшать код, то все окей будет
его код - гпт бредятина, а тогда я писал не в сознании и не восхвалял свою работу как сейчас
возможно, в этот код он внес свой вклад, но гпт саму основу написал
не знаю что из чела выйдет, но если есть желание развиваться то даже не знаю
ну это ■■■■■■, гпт явный

