mirror of
https://github.com/HibiscusMC/HMCCosmetics.git
synced 2025-12-19 15:09:19 +00:00
cosmetic provider & cleanup
This commit is contained in:
@@ -2,6 +2,7 @@ package com.hibiscusmc.hmccosmetics.api;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticProvider;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menu;
|
||||
@@ -12,6 +13,7 @@ import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -143,9 +145,10 @@ public final class HMCCosmeticsAPI {
|
||||
*
|
||||
* @param id the id for the cosmetic slot
|
||||
* @return the {@link CosmeticSlot} associated with the given id
|
||||
* @apiNote this should be done in your {@link JavaPlugin#onLoad()} or it may error.
|
||||
*/
|
||||
public static @NotNull CosmeticSlot registerCosmeticSlot(@NotNull String id, BiConsumer<String, ConfigurationNode> consumer) {
|
||||
return CosmeticSlot.register(id, consumer);
|
||||
public static @NotNull CosmeticSlot registerCosmeticSlot(@NotNull String id) {
|
||||
return CosmeticSlot.register(id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,6 +156,7 @@ public final class HMCCosmeticsAPI {
|
||||
*
|
||||
* @param provider the provider to register
|
||||
* @throws IllegalArgumentException if another plugin has already registered a provider
|
||||
* @apiNote this should be done in your {@link JavaPlugin#onLoad()} or it may error.
|
||||
*/
|
||||
public static void registerCosmeticUserProvider(@NotNull CosmeticUserProvider provider) {
|
||||
CosmeticUsers.registerProvider(provider);
|
||||
@@ -167,6 +171,26 @@ public final class HMCCosmeticsAPI {
|
||||
return CosmeticUsers.getProvider();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new cosmetic user provider to use for constructing {@link Cosmetic} instances.
|
||||
*
|
||||
* @param provider the provider to register
|
||||
* @throws IllegalArgumentException if another plugin has already registered a provider
|
||||
* @apiNote this should be done in your {@link JavaPlugin#onLoad()} or it may error.
|
||||
*/
|
||||
public static void registerCosmeticProvider(@NotNull CosmeticProvider provider) {
|
||||
Cosmetics.registerProvider(provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current {@link CosmeticProvider} that is in use.
|
||||
*
|
||||
* @return the current {@link CosmeticProvider}
|
||||
*/
|
||||
public static @NotNull CosmeticProvider getCosmeticProvider() {
|
||||
return Cosmetics.getProvider();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the NMS version of the server as recognized by HMCCosmetics.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.hibiscusmc.hmccosmetics.cosmetic;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.*;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
/**
|
||||
* Allow custom implementations of a {@link Cosmetic}.
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class CosmeticProvider {
|
||||
protected static final Map<CosmeticSlot, BiFunction<String, ConfigurationNode, Cosmetic>> MAPPINGS = Map.ofEntries(
|
||||
Map.entry(CosmeticSlot.HELMET, CosmeticArmorType::new),
|
||||
Map.entry(CosmeticSlot.CHESTPLATE, CosmeticArmorType::new),
|
||||
Map.entry(CosmeticSlot.LEGGINGS, CosmeticArmorType::new),
|
||||
Map.entry(CosmeticSlot.BOOTS, CosmeticArmorType::new),
|
||||
Map.entry(CosmeticSlot.OFFHAND, CosmeticArmorType::new),
|
||||
|
||||
Map.entry(CosmeticSlot.MAINHAND, CosmeticMainhandType::new),
|
||||
|
||||
Map.entry(CosmeticSlot.BACKPACK, CosmeticBackpackType::new),
|
||||
|
||||
Map.entry(CosmeticSlot.BALLOON, CosmeticBalloonType::new),
|
||||
|
||||
Map.entry(CosmeticSlot.EMOTE, CosmeticEmoteType::new)
|
||||
);
|
||||
|
||||
private static final String EXCEPTION_MESSAGE = "Unknown slot %s provided for mapping, if you registered your own CosmeticSlot please ensure that you've also registered a custom CosmeticProvider! Or if you have already registered a custom CosmeticProvider ensure it is registered in your plugins `onLoad` method instead of `onEnable`!";
|
||||
|
||||
/**
|
||||
* Construct the {@link Cosmetic}.
|
||||
* @param id the cosmetic id
|
||||
* @param config the configuration node of the cosmetic
|
||||
* @param slot the occupying slot of the cosmetic
|
||||
* @return the {@link Cosmetic}
|
||||
* @throws IllegalArgumentException if the provided cosmetic could not be mapped
|
||||
*/
|
||||
public @NotNull Cosmetic createCosmetic(String id, ConfigurationNode config, CosmeticSlot slot) throws IllegalArgumentException {
|
||||
final var mapper = MAPPINGS.get(slot);
|
||||
if(mapper == null) {
|
||||
throw new IllegalArgumentException(
|
||||
EXCEPTION_MESSAGE.formatted(slot)
|
||||
);
|
||||
}
|
||||
|
||||
return mapper.apply(id, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the plugin that is providing this {@link CosmeticProvider}
|
||||
* @return the plugin
|
||||
*/
|
||||
public abstract Plugin getProviderPlugin();
|
||||
|
||||
/**
|
||||
* Default Implementation.
|
||||
*/
|
||||
static class Default extends CosmeticProvider {
|
||||
public static final CosmeticProvider INSTANCE = new Default();
|
||||
|
||||
@Override
|
||||
public Plugin getProviderPlugin() {
|
||||
return HMCCosmeticsPlugin.getInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,59 +1,59 @@
|
||||
package com.hibiscusmc.hmccosmetics.cosmetic;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.*;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
public class CosmeticSlot {
|
||||
private static final ConcurrentHashMap<String, CosmeticSlot> REGISTRY = new ConcurrentHashMap<>();
|
||||
|
||||
public static final CosmeticSlot HELMET = register("HELMET", CosmeticArmorType::new);
|
||||
public static final CosmeticSlot CHESTPLATE = register("CHESTPLATE", CosmeticArmorType::new);
|
||||
public static final CosmeticSlot LEGGINGS = register("LEGGINGS", CosmeticArmorType::new);
|
||||
public static final CosmeticSlot BOOTS = register("BOOTS", CosmeticArmorType::new);
|
||||
public static final CosmeticSlot MAINHAND = register("MAINHAND", CosmeticMainhandType::new);
|
||||
public static final CosmeticSlot OFFHAND = register("OFFHAND", CosmeticArmorType::new);
|
||||
public static final CosmeticSlot BACKPACK = register("BACKPACK", CosmeticBackpackType::new);
|
||||
public static final CosmeticSlot BALLOON = register("BALLOON", CosmeticBalloonType::new);
|
||||
public static final CosmeticSlot EMOTE = register("EMOTE", CosmeticEmoteType::new);
|
||||
public static final CosmeticSlot HELMET = register("HELMET");
|
||||
public static final CosmeticSlot CHESTPLATE = register("CHESTPLATE");
|
||||
public static final CosmeticSlot LEGGINGS = register("LEGGINGS");
|
||||
public static final CosmeticSlot BOOTS = register("BOOTS");
|
||||
public static final CosmeticSlot MAINHAND = register("MAINHAND");
|
||||
public static final CosmeticSlot OFFHAND = register("OFFHAND");
|
||||
public static final CosmeticSlot BACKPACK = register("BACKPACK");
|
||||
public static final CosmeticSlot BALLOON = register("BALLOON");
|
||||
public static final CosmeticSlot EMOTE = register("EMOTE");
|
||||
|
||||
private final String name;
|
||||
private final BiConsumer<String, ConfigurationNode> consumer;
|
||||
|
||||
private CosmeticSlot(@NotNull String name, @NotNull BiConsumer<String, ConfigurationNode> consumer) {
|
||||
private CosmeticSlot(@NotNull String name) {
|
||||
this.name = name;
|
||||
this.consumer = consumer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts the given id and configuration node to run the consumer relating to the ConsumerSlot
|
||||
* @param id The id of the cosmetic
|
||||
* @param config The configuration node of the cosmetic
|
||||
*/
|
||||
public void accept(@NotNull String id, @NotNull ConfigurationNode config) {
|
||||
consumer.accept(id, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new slot with the given name. If a slot with the given name already exists, it will be returned.
|
||||
* @param name The name of the slot (This will automatically be converted into all UPPERCASE)
|
||||
* @return The slot that was registered or already exists.
|
||||
* @throws IllegalArgumentException if a cosmetic slot by that name has already been registered
|
||||
*/
|
||||
@NotNull
|
||||
public static CosmeticSlot register(@NotNull String name, @NotNull BiConsumer<String, ConfigurationNode> consumer) {
|
||||
name = name.toUpperCase();
|
||||
return REGISTRY.computeIfAbsent(name, key -> new CosmeticSlot(key, consumer));
|
||||
public static CosmeticSlot register(@NotNull String name) {
|
||||
final String upperName = name.toUpperCase();
|
||||
if(REGISTRY.containsKey(upperName)) {
|
||||
throw new IllegalArgumentException("A cosmetic slot with name '" + name + "' is already registered.");
|
||||
}
|
||||
|
||||
final CosmeticSlot slot = new CosmeticSlot(upperName);
|
||||
REGISTRY.put(upperName, slot);
|
||||
return slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable map of all the slots that have been registered.
|
||||
* @return An unmodifiable map of all the slots that have been registered.
|
||||
*/
|
||||
@NotNull
|
||||
@@ -68,8 +68,8 @@ public class CosmeticSlot {
|
||||
*/
|
||||
@Nullable
|
||||
public static CosmeticSlot valueOf(@NotNull String name) {
|
||||
name = name.toUpperCase();
|
||||
return REGISTRY.get(name);
|
||||
final String upperName = name.toUpperCase();
|
||||
return REGISTRY.get(upperName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,12 +78,7 @@ public class CosmeticSlot {
|
||||
* @return True if the slot exists, false otherwise.
|
||||
*/
|
||||
public static boolean contains(@NotNull String name) {
|
||||
name = name.toUpperCase();
|
||||
return REGISTRY.containsKey(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
final String upperName = name.toUpperCase();
|
||||
return REGISTRY.containsKey(upperName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,12 @@ package com.hibiscusmc.hmccosmetics.cosmetic;
|
||||
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.hibiscusmc.hmccosmetics.api.events.CosmeticTypeRegisterEvent;
|
||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.*;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.lojosho.shaded.configurate.CommentedConfigurationNode;
|
||||
import me.lojosho.shaded.configurate.ConfigurateException;
|
||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||
import me.lojosho.shaded.configurate.yaml.YamlConfigurationLoader;
|
||||
import org.apache.commons.lang3.EnumUtils;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -22,10 +19,12 @@ import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Slf4j
|
||||
public class Cosmetics {
|
||||
|
||||
private static final HashBiMap<String, Cosmetic> COSMETICS = HashBiMap.create();
|
||||
|
||||
private static CosmeticProvider PROVIDER = CosmeticProvider.Default.INSTANCE;
|
||||
|
||||
public static void addCosmetic(Cosmetic cosmetic) {
|
||||
COSMETICS.put(cosmetic.getId(), cosmetic);
|
||||
}
|
||||
@@ -35,7 +34,7 @@ public class Cosmetics {
|
||||
}
|
||||
|
||||
public static void removeCosmetic(Cosmetic cosmetic) {
|
||||
COSMETICS.remove(cosmetic);
|
||||
COSMETICS.remove(cosmetic.getId());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -92,6 +91,31 @@ public class Cosmetics {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a custom {@link CosmeticProvider} to provide your own user implementation to
|
||||
* be used and queried.
|
||||
* @param provider the provider to register
|
||||
* @throws IllegalArgumentException if the provider is already registered by another plugin
|
||||
*/
|
||||
public static void registerProvider(final CosmeticProvider provider) {
|
||||
if(PROVIDER != CosmeticProvider.Default.INSTANCE) {
|
||||
throw new IllegalArgumentException("CosmeticProvider already registered by %s, this conflicts with %s attempting to register their own.".formatted(
|
||||
PROVIDER.getProviderPlugin().getName(),
|
||||
provider.getProviderPlugin().getName()
|
||||
));
|
||||
}
|
||||
|
||||
PROVIDER = provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the current {@link CosmeticProvider} being used.
|
||||
* @return the current {@link CosmeticProvider} being used
|
||||
*/
|
||||
public static CosmeticProvider getProvider() {
|
||||
return PROVIDER;
|
||||
}
|
||||
|
||||
private static void setupCosmetics(@NotNull CommentedConfigurationNode config) {
|
||||
for (ConfigurationNode cosmeticConfig : config.childrenMap().values()) {
|
||||
String id = cosmeticConfig.key().toString();
|
||||
@@ -107,7 +131,12 @@ public class Cosmetics {
|
||||
MessagesUtil.sendDebugMessages("Unable to create " + id + " because " + slotNode.getString() + " is not a valid slot!", Level.WARNING);
|
||||
continue;
|
||||
}
|
||||
cosmeticSlot.accept(id, cosmeticConfig);
|
||||
|
||||
try {
|
||||
addCosmetic(PROVIDER.createCosmetic(id, cosmeticConfig, cosmeticSlot));
|
||||
} catch(Exception ex) {
|
||||
log.error("Unable to construct cosmetic for {}, skipping processing it.", id, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.hibiscusmc.hmccosmetics.user;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.hibiscusmc.hmccosmetics.database.UserData;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -11,27 +10,27 @@ import java.util.UUID;
|
||||
/**
|
||||
* Allow custom implementations of a {@link CosmeticUser}.
|
||||
*/
|
||||
public interface CosmeticUserProvider {
|
||||
CosmeticUserProvider DEFAULT = new Default();
|
||||
|
||||
public abstract class CosmeticUserProvider {
|
||||
/**
|
||||
* Construct the custom {@link CosmeticUser}.
|
||||
* @param playerId the player uuid
|
||||
* @return the {@link CosmeticUser}
|
||||
* @apiNote This method is called during the {@link PlayerJoinEvent}.
|
||||
*/
|
||||
@NotNull CosmeticUser createCosmeticUser(@NotNull UUID playerId);
|
||||
public abstract @NotNull CosmeticUser createCosmeticUser(@NotNull UUID playerId);
|
||||
|
||||
/**
|
||||
* Represents the plugin that is providing this {@link CosmeticUserProvider}
|
||||
* @return the plugin
|
||||
*/
|
||||
Plugin getProviderPlugin();
|
||||
public abstract Plugin getProviderPlugin();
|
||||
|
||||
/**
|
||||
* Default implementation.
|
||||
*/
|
||||
class Default implements CosmeticUserProvider {
|
||||
static class Default extends CosmeticUserProvider {
|
||||
public static CosmeticUserProvider INSTANCE = new Default();
|
||||
|
||||
@Override
|
||||
public @NotNull CosmeticUser createCosmeticUser(@NotNull UUID playerId) {
|
||||
return new CosmeticUser(playerId);
|
||||
|
||||
@@ -13,7 +13,7 @@ import java.util.UUID;
|
||||
public class CosmeticUsers {
|
||||
private static final HashBiMap<UUID, CosmeticUser> COSMETIC_USERS = HashBiMap.create();
|
||||
|
||||
private static CosmeticUserProvider PROVIDER = CosmeticUserProvider.DEFAULT;
|
||||
private static CosmeticUserProvider PROVIDER = CosmeticUserProvider.Default.INSTANCE;
|
||||
|
||||
/**
|
||||
* Adds a user to the Hashmap of stored CosmeticUsers. This will not override an entry if it already exists. If you need to override, delete then add.
|
||||
@@ -80,7 +80,7 @@ public class CosmeticUsers {
|
||||
* @throws IllegalArgumentException if the provider is already registered by another plugin
|
||||
*/
|
||||
public static void registerProvider(final CosmeticUserProvider provider) {
|
||||
if(PROVIDER != CosmeticUserProvider.DEFAULT) {
|
||||
if(PROVIDER != CosmeticUserProvider.Default.INSTANCE) {
|
||||
throw new IllegalArgumentException("CosmeticUserProvider already registered by %s, this conflicts with %s attempting to register their own.".formatted(
|
||||
PROVIDER.getProviderPlugin().getName(),
|
||||
provider.getProviderPlugin().getName()
|
||||
|
||||
Reference in New Issue
Block a user