3
0
Mirror von https://github.com/TheSilentPro/HeadDB.git synchronisiert 2024-12-26 19:02:39 +01:00

start work for rc1

Dieser Commit ist enthalten in:
Silent 2022-11-13 03:07:05 +01:00
Ursprung 396a6ba858
Commit 796652ed95
13 geänderte Dateien mit 202 neuen und 20 gelöschten Zeilen

Datei anzeigen

@ -80,7 +80,7 @@
<dependency>
<groupId>com.github.TheSilentPro</groupId>
<artifactId>Warehouse</artifactId>
<version>f40f72cb19</version>
<version>882b42fc75</version>
</dependency>
<dependency>
<groupId>net.wesjd</groupId>

Datei anzeigen

@ -1,5 +1,6 @@
package tsp.headdb;
import org.bukkit.command.PluginCommand;
import tsp.headdb.core.command.CommandCategory;
import tsp.headdb.core.command.CommandGive;
import tsp.headdb.core.command.CommandHelp;
@ -15,6 +16,7 @@ import tsp.headdb.core.command.CommandUpdate;
import tsp.headdb.core.economy.BasicEconomyProvider;
import tsp.headdb.core.economy.VaultProvider;
import tsp.headdb.core.listener.PlayerJoinListener;
import tsp.headdb.core.storage.Storage;
import tsp.headdb.core.task.UpdateTask;
import tsp.headdb.core.util.BuildProperties;
@ -35,6 +37,7 @@ public class HeadDB extends SmartPlugin {
private PluginLogger logger;
private BuildProperties buildProperties;
private TranslatableLocalization localization;
private Storage storage;
private BasicEconomyProvider economyProvider;
private CommandManager commandManager;
@ -49,15 +52,14 @@ public class HeadDB extends SmartPlugin {
new UpdateTask(getConfig().getLong("refresh", 86400L)).schedule(this);
instance.logger.info("Loaded " + loadLocalization() + " languages!");
instance.initStorage();
instance.initEconomy();
new PaneListener(this);
new PlayerJoinListener();
//new PlayerJoinListener();
instance.commandManager = new CommandManager();
loadCommands();
//noinspection ConstantConditions
instance.getCommand("headdb").setExecutor(new CommandMain());
new Metrics(this, 9152);
ensureLatestVersion();
@ -66,7 +68,9 @@ public class HeadDB extends SmartPlugin {
@Override
public void onDisable() {
// todo: save storage
if (storage != null) {
storage.getPlayerStorage().suspend();
}
}
private void ensureLatestVersion() {
@ -78,6 +82,13 @@ public class HeadDB extends SmartPlugin {
});
}
// Loaders
private void initStorage() {
storage = new Storage(getConfig().getInt("storage.threads"));
storage.getPlayerStorage().init();
}
private int loadLocalization() {
instance.localization = new TranslatableLocalization(this, "messages");
try {
@ -108,6 +119,16 @@ public class HeadDB extends SmartPlugin {
}
private void loadCommands() {
PluginCommand main = getCommand("headdb");
if (main != null) {
main.setExecutor(new CommandMain());
main.setTabCompleter(new CommandMain());
} else {
instance.logger.error("Could not find main 'headdb' command!");
this.setEnabled(false);
return;
}
new CommandHelp().register();
new CommandCategory().register();
new CommandSearch().register();
@ -119,6 +140,12 @@ public class HeadDB extends SmartPlugin {
new CommandInfo().register();
}
// Getters
public Storage getStorage() {
return storage;
}
public CommandManager getCommandManager() {
return commandManager;
}

Datei anzeigen

@ -3,6 +3,7 @@ package tsp.headdb.core.api;
import org.bukkit.Bukkit;
import tsp.headdb.HeadDB;
import tsp.headdb.core.storage.PlayerData;
import tsp.headdb.core.util.Utils;
import tsp.headdb.implementation.category.Category;
import tsp.headdb.implementation.head.Head;
@ -18,6 +19,7 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
/**
@ -152,7 +154,7 @@ public final class HeadAPI {
/**
* Retrieve a {@link Set} of local heads.
* Note that this calculates the heads on every try.
* Note that this calculates the heads on every call.
*
* @return {@link Set<LocalHead> Local Heads}
*/
@ -161,6 +163,24 @@ public final class HeadAPI {
return Arrays.stream(Bukkit.getOfflinePlayers()).map(player -> new LocalHead(player.getUniqueId(), player.getName())).collect(Collectors.toSet());
}
/**
* Retrieve a {@link Set} of favorite heads for the specified {@link UUID player id}.
* Note that this calculates the heads on every call.
*
* @param player The players id
* @return {@link Set<Head> Favorite Heads}
*/
@Nonnull
public static List<Head> getFavoriteHeads(UUID player) {
List<Head> result = new ArrayList<>();
Optional<PlayerData> data = HeadDB.getInstance().getStorage().getPlayerStorage().get(player);
data.ifPresent(playerData -> playerData.favorites()
.forEach(texture -> getHeadByTexture(texture)
.ifPresent(result::add))
);
return result;
}
/**
* Retrieve the main {@link HeadDatabase} used by the plugin.
*

Datei anzeigen

@ -80,7 +80,7 @@ public class CommandMain extends HeadDBCommand implements CommandExecutor, TabCo
}
})
.text("Query")
.title(getLocalization().getMessage(player.getUniqueId(), "menu.main.category.page.name").orElse("Enter page"))
.title(StringUtils.colorize(getLocalization().getMessage(player.getUniqueId(), "menu.main.category.page.name").orElse("Enter page")))
.plugin(getInstance())
.open(player);
}
@ -90,7 +90,20 @@ public class CommandMain extends HeadDBCommand implements CommandExecutor, TabCo
// Set meta buttons
pane.setButton(getInstance().getConfig().getInt("gui.main.meta.favorites.slot"), new Button(Utils.getItemFromConfig("gui.main.meta.favorites.item", Material.BOOK), e -> {
e.setCancelled(true);
// TODO: favorites
List<Head> heads = HeadAPI.getFavoriteHeads(player.getUniqueId());
PagedPane main = Utils.createPaged(player, Utils.translateTitle(getLocalization().getMessage(player.getUniqueId(), "menu.main.favorites").orElse("Favorites"), heads.size(), "Favorites"));
for (Head head : heads) {
main.addButton(new Button(head.getItem(player.getUniqueId()), fe -> {
if (fe.isLeftClick()) {
ItemStack favoriteItem = head.getItem(player.getUniqueId());
if (fe.isShiftClick()) {
favoriteItem.setAmount(64);
}
player.getInventory().addItem(favoriteItem);
}
}));
}
}));
pane.setButton(getInstance().getConfig().getInt("gui.main.meta.search.slot"), new Button(Utils.getItemFromConfig("gui.main.meta.search.item", Material.DARK_OAK_SIGN), e -> {
@ -140,8 +153,6 @@ public class CommandMain extends HeadDBCommand implements CommandExecutor, TabCo
}
player.getInventory().addItem(localItem);
} else if (le.isRightClick()) {
// todo: remove from favorites
}
}));
}

Datei anzeigen

@ -14,7 +14,6 @@ public final class PlayerJoinListener implements Listener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
// todo: favorites
//HeadDB.getInstance().getStorage().getPlayerStorage().register(new PlayerData(event.getPlayer().getUniqueId(), ""));
}

Datei anzeigen

@ -0,0 +1,20 @@
package tsp.headdb.core.storage;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
public final class HeadDBThreadFactory implements ThreadFactory {
private HeadDBThreadFactory() {}
public static final HeadDBThreadFactory FACTORY = new HeadDBThreadFactory();
private final AtomicInteger ID = new AtomicInteger(1);
@Override
public Thread newThread(@NotNull Runnable r) {
return new Thread(r, "headdb-thread-" + ID.getAndIncrement());
}
}

Datei anzeigen

@ -0,0 +1,7 @@
package tsp.headdb.core.storage;
import java.io.Serializable;
import java.util.Set;
import java.util.UUID;
public record PlayerData(UUID uniqueId, Set<String> favorites) implements Serializable {}

Datei anzeigen

@ -0,0 +1,62 @@
package tsp.headdb.core.storage;
import tsp.headdb.HeadDB;
import tsp.warehouse.storage.file.SerializableFileDataManager;
import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
public class PlayerStorage extends SerializableFileDataManager<Collection<PlayerData>> {
private final Map<UUID, PlayerData> players = new HashMap<>();
public PlayerStorage(Storage storage) {
super(new File("data/players.data"), storage.getExecutor());
}
public void set(PlayerData data) {
this.players.put(data.uniqueId(), data);
}
public Optional<PlayerData> get(UUID uuid) {
return Optional.ofNullable(players.get(uuid));
}
public Map<UUID, PlayerData> getPlayersMap() {
return Collections.unmodifiableMap(players);
}
public void init() {
load().whenComplete((data, ex) -> {
for (PlayerData entry : data) {
players.put(entry.uniqueId(), entry);
}
HeadDB.getInstance().getLog().debug("Loaded " + players.values().size() + " player data!");
});
}
public void backup() {
save(players.values()).whenComplete((success, ex) -> HeadDB.getInstance().getLog().debug("Saved " + players.values().size() + " player data!"));
}
public void suspend() {
Boolean saved = save(players.values())
.exceptionally(ex -> {
HeadDB.getInstance().getLog().error("Failed to save player data! | Stack Trace: ");
ex.printStackTrace();
return false;
})
.join();
if (Boolean.TRUE.equals(saved)) {
HeadDB.getInstance().getLog().debug("Saved " + players.values().size() + " player data!");
}
}
}

Datei anzeigen

@ -0,0 +1,24 @@
package tsp.headdb.core.storage;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class Storage {
private final Executor executor;
private final PlayerStorage playerStorage;
public Storage(int threads) {
executor = Executors.newFixedThreadPool(threads, HeadDBThreadFactory.FACTORY);
playerStorage = new PlayerStorage(this);
}
public PlayerStorage getPlayerStorage() {
return playerStorage;
}
public Executor getExecutor() {
return executor;
}
}

Datei anzeigen

@ -15,6 +15,8 @@ import tsp.headdb.core.api.HeadAPI;
import tsp.headdb.core.api.event.HeadPurchaseEvent;
import tsp.headdb.core.economy.BasicEconomyProvider;
import tsp.headdb.core.hook.Hooks;
import tsp.headdb.core.storage.PlayerData;
import tsp.headdb.core.storage.PlayerStorage;
import tsp.headdb.implementation.category.Category;
import tsp.headdb.implementation.head.Head;
import tsp.smartplugin.inventory.Button;
@ -33,6 +35,7 @@ import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
@ -121,7 +124,7 @@ public class Utils {
purchase(player, head, amount);
} else if (e.isRightClick()) {
// todo: favorites
HeadDB.getInstance().getStorage().getPlayerStorage().get(player.getUniqueId()).orElse(new PlayerData(player.getUniqueId(), new HashSet<>())).favorites().add(head.getTexture());
}
}));
}

Datei anzeigen

@ -9,6 +9,7 @@ import tsp.headdb.implementation.requester.Requester;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
public class HeadDatabase {
@ -16,14 +17,14 @@ public class HeadDatabase {
private final JavaPlugin plugin;
private final BukkitScheduler scheduler;
private final Requester requester;
private final Map<Category, List<Head>> heads;
private final ConcurrentHashMap<Category, List<Head>> heads;
private long timestamp;
public HeadDatabase(JavaPlugin plugin, HeadProvider provider) {
this.plugin = plugin;
this.scheduler = plugin.getServer().getScheduler();
this.requester = new Requester(plugin, provider);
this.heads = new HashMap<>();
this.heads = new ConcurrentHashMap<>();
}
public Map<Category, List<Head>> getHeads() {

Datei anzeigen

@ -1,14 +1,15 @@
# How often the database should be updated in seconds.
refresh: 86400
# If local heads should be enabled. Only starts keeping track of joined players when enabled!
# If local heads should be enabled.
# Local heads are heads from players that have joined your server at least once.
localHeads: true
# If enabled categories will require a permission to be used
# If enabled categories will require a permission to be used.
# Permission: headdb.category.<category>
requireCategoryPermission: false
# If enabled, the menu will close after purchasing a head (even if the purchase fails)
# If enabled, the menu will close after purchasing a head (even if the purchase fails).
closeOnPurchase: false
# Economy Options
@ -28,7 +29,7 @@ economy:
monsters: 100
plants: 100
# Command Configuration. Supports PlaceholderAPI
# Command Configuration. Supports PlaceholderAPI.
commands:
# Commands to run ONLY if the purchase is successful.
# They are run as CONSOLE after the player has receiver the head in their inventory.
@ -83,8 +84,13 @@ gui:
# The archive is static so some heads may be missing, this will only be used when all else fails.
fallback: true
# Shows more plugin information in /hdb info
# Shows more plugin information. (/hdb info)
showAdvancedPluginInfo: true
# Storage Options
storage:
# Amount of threads in the executor pool used for storage.
threads: 2
# Debug Mode
debug: false

Datei anzeigen

@ -17,7 +17,7 @@ itemTexture: "&7Texture: &6%texture%"
itemNoTexture: "&cThis item does not have a texture!"
copyTexture: "&6Click to copy texture!"
#
# Only shown if economy is enabled
processPayment: "&7Purchasing &6%name% &7for &6%cost%&7! Please wait..."
completePayment: "&7Received &6%name% &7for &6%cost%"
@ -34,6 +34,8 @@ menu:
lore:
- "&7Left-Click to open"
- "&7Right-Click to open specific page"
favorites:
name: "&6Favorites"
search:
name: "&6Search"
local: