Skip to content

Commit

Permalink
* Head database finished.
Browse files Browse the repository at this point in the history
  • Loading branch information
Hempfest committed Jun 22, 2021
1 parent 1611a74 commit 3713a96
Show file tree
Hide file tree
Showing 9 changed files with 273 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,22 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* getServerVersion 2.1 of the License, or (at your option) any later getServerVersion.
* version 2.1 of the License, or (at your option) any later version.
* </p>
* -
* <p>
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* </p>
* -
* <p>
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
* <p>
* </p>
* Sanctum, hereby disclaims all copyright interest in the original features of this spigot library.
*/
public final class Labyrinth extends JavaPlugin implements Listener {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,15 @@ public boolean execute(@NotNull CommandSender sender, @NotNull String commandLab
}
} else {
if (builder.playerResultingExecutor != null) {
return builder.playerResultingExecutor.run((Player) sender, commandLabel, args);
if (builder.permission != null) {
if (testPermission(sender)) {
return builder.playerResultingExecutor.run((Player) sender, commandLabel, args);
} else {
return true;
}
} else {
return builder.playerResultingExecutor.run((Player) sender, commandLabel, args);
}
}
return true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.github.sanctum.skulls;

import com.github.sanctum.labyrinth.Labyrinth;
import com.github.sanctum.labyrinth.library.Item;
import com.github.sanctum.labyrinth.library.Items;
import java.util.ArrayList;
import java.util.Arrays;
Expand All @@ -20,11 +21,15 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public abstract class CustomHead {
/**
* A custom skinned player skull with an attached reference to its category and possible owner. If no owner is present then this head
*/
public abstract class CustomHead implements SkullObject {

private static final boolean LOADED;
private static final List<CustomHead> HEADS;

protected static boolean LOADED;
protected UUID owner;
protected static final List<CustomHead> HEADS;

protected CustomHead() {
}
Expand All @@ -33,19 +38,37 @@ protected CustomHead(UUID owner) {
this.owner = owner;
}

abstract @NotNull ItemStack get();
@Override
public abstract @NotNull ItemStack get();

abstract @NotNull String name();
@Override
public abstract @NotNull String name();

abstract @NotNull String category();
@Override
public abstract @NotNull String category();

@Override
public Optional<UUID> id() {
return Optional.ofNullable(this.owner);
}

@Override
public SkullType getType() {
return this.id().isPresent() ? SkullType.PLAYER : SkullType.CUSTOM;
}

public static class Manager {

/**
* Load a custom head object into cache.
*
* @param object The custom head object.
*/
public static void load(CustomHead object) {
boolean isNew = Arrays.stream(Material.values()).map(Material::name).collect(Collectors.toList()).contains("PLAYER_HEAD");
Material type = Items.getMaterial(isNew ? "PLAYER_HEAD" : "SKULL_ITEM");
if (object.get().getType() != type)
throw new IllegalStateException(object.get().getType().name() + " is not a direct representation of " + type.name());
HEADS.add(object);
}

Expand All @@ -64,6 +87,12 @@ protected static List<CustomHead> loadOffline() {
return list;
}

/**
* Using {@link CustomHead.Manager#newLoader(FileConfiguration)} or {@link CustomHead.Manager#newLoader(Plugin, String, String)} load configured head values
* from your specified file location.
*
* @param loader The head loader instance.
*/
public static void load(CustomHeadLoader loader) {
if (loader.isLoaded()) {
for (Map.Entry<HeadText, ItemStack> entry : loader.getHeads().entrySet()) {
Expand All @@ -76,6 +105,14 @@ public static void load(CustomHeadLoader loader) {
}
}

/**
* Get a local player's head.
* <p>
* Results are cached. If a result is already found within the query it is instead returned.
*
* @param player The player to fetch.
* @return The head of the specified player or null if not found.
*/
public static @Nullable ItemStack get(OfflinePlayer player) {

CustomHead ch = HEADS.stream().filter(h -> h.id().isPresent() && h.id().get().equals(player.getUniqueId())).findFirst().orElseGet(() -> {
Expand All @@ -92,6 +129,14 @@ public static void load(CustomHeadLoader loader) {
return ch != null ? ch.get() : null;
}

/**
* Get the head of either a local player or one that has <strong>never</strong> logged onto the server before.
* <p>
* As long as the id has a valid link to a player from the mojang api results are cached.
*
* @param id The valid player id.
* @return The head of the specified user or null if not found.
*/
public static @Nullable ItemStack get(UUID id) {

CustomHead ch = HEADS.stream().filter(h -> h.id().isPresent() && h.id().get().equals(id)).findFirst().orElseGet(() -> {
Expand All @@ -108,6 +153,14 @@ public static void load(CustomHeadLoader loader) {
return ch != null ? ch.get() : null;
}

/**
* Get the head of either a local player or one that has <strong>never</strong> logged onto the server before.
* <p>
* As long as the id has a valid link to a player from the mojang api results are cached.
*
* @param name The name of the player.
* @return The head of the specified user or null if not found.
*/
public static @Nullable ItemStack get(String name) {

CustomHead ch = HEADS.stream().filter(h -> h.name().equals(name)).findFirst().orElseGet(() -> {
Expand All @@ -124,7 +177,15 @@ public static void load(CustomHeadLoader loader) {
return ch != null ? ch.get() : null;
}

public static @Nullable CustomHead find(String name) {
/**
* Get the head of either a local player or one that has <strong>never</strong> logged onto the server before.
* <p>
* As long as the id has a valid link to a player from the mojang api results are cached.
*
* @param name The name of the player.
* @return The head of the specified user or null if not found.
*/
public static @Nullable CustomHead pick(String name) {
return HEADS.stream().filter(h -> h.name().equals(name)).findFirst().orElseGet(() -> {

OnlineHeadSearch search = new OnlineHeadSearch(name);
Expand All @@ -137,25 +198,99 @@ public static void load(CustomHeadLoader loader) {
});
}

/**
* Get the head of either a local player or one that has <strong>never</strong> logged onto the server before.
* <p>
* As long as the id has a valid link to a player from the mojang api results are cached.
*
* @param id The valid player id.
* @return The head of the specified user or null if not found.
*/
public static @Nullable CustomHead pick(UUID id) {
return HEADS.stream().filter(h -> h.id().isPresent() && h.id().get().equals(id)).findFirst().orElseGet(() -> {

OnlineHeadSearch search = new OnlineHeadSearch(id);
if (search.getResult() != null) {
CustomHead head = new LabyrinthHeadImpl(Bukkit.getOfflinePlayer(id).getName(), "Human", search.getResult(), id);
HEADS.add(head);
return head;
}
return null;
});
}

/**
* Get a local player's head.
* <p>
* Results are cached. If a result is already found within the query it is instead returned.
*
* @param player The player to fetch.
* @return The head of the specified player or null if not found.
*/
public static @Nullable CustomHead pick(OfflinePlayer player) {
return HEADS.stream().filter(h -> h.id().isPresent() && h.id().get().equals(player.getUniqueId())).findFirst().orElseGet(() -> {

OnlineHeadSearch search = new OnlineHeadSearch(player.getUniqueId());
if (search.getResult() != null) {
CustomHead head = new LabyrinthHeadImpl(player.getName(), "Human", search.getResult(), player.getUniqueId());
HEADS.add(head);
return head;
}
return null;
});
}

/**
* Get all known custom head categories.
*
* @return Every known custom head category.
*/
public static List<String> getCategories() {
return HEADS.stream().map(CustomHead::category).collect(Collectors.toList());
}

/**
* Get all known custom heads as an {@link ItemStack} specified by a category.
* <p>
* If the specified category isn't found an empty list is returned.
*
* @param category The valid category to search.
* @return All categorized heads or an empty list if ill-informed.
*/
public static List<ItemStack> getCategory(String category) {
if (!getCategories().contains(category)) {
return new ArrayList<>();
}
return HEADS.stream().filter(h -> h.category().equals(category)).map(CustomHead::get).collect(Collectors.toList());
}

public static List<ItemStack> getGallery() {
return Collections.unmodifiableList(HEADS.stream().map(CustomHead::get).collect(Collectors.toList()));
/**
* Get all currently cached custom heads.
*
* @return A list of <strong>ALL</strong> known custom heads.
*/
public static List<CustomHead> getHeads() {
return Collections.unmodifiableList(HEADS);
}

/**
* Assign the loading of additional configured head elements.
*
* @param plugin The source plugin.
* @param fileName The name of the file to use.
* @param directory The directory of the file.
* @return A new head loader instance.
*/
public static CustomHeadLoader newLoader(Plugin plugin, String fileName, String directory) {
return new CustomHeadLoader(plugin, fileName, directory);
}

/**
* Assign the loading of additional configured head elements.
*
* @param configuration The config to source the additions from
* @return A new head loader instance.
*/
public static CustomHeadLoader newLoader(FileConfiguration configuration) {
return new CustomHeadLoader(configuration);
}
Expand All @@ -178,6 +313,25 @@ protected static void load(String name, String category, ItemStack item) {
load(new LabyrinthHeadImpl(name, category, item));
}

/**
* Copy all lore from a targeted player head and change the owner to one specified.
*
* @param item The item to modify.
* @param name The name of the new owner.
* @return The modified item stack.
*/
public static ItemStack modifyItemStack(ItemStack item, String name) {
boolean isNew = Arrays.stream(Material.values()).map(Material::name).collect(Collectors.toList()).contains("PLAYER_HEAD");
Material type = Items.getMaterial(isNew ? "PLAYER_HEAD" : "SKULL_ITEM");

if (item.getType() != type)
throw new IllegalStateException(item.getType().name() + " is not a direct representation of " + type.name());

CustomHead head = pick(name);
return head != null ? new Item.Edit(head.get()).setTitle(item.getItemMeta() != null ? item.getItemMeta().getDisplayName() : head.name()).setLore(item.getItemMeta() != null && item.getItemMeta().getLore() != null ? item.getItemMeta().getLore().toArray(new String[0]) : new String[]{""}).build() : item;

}

}

static {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ protected CustomHeadLoader(Plugin plugin, String fileName, String directory) {
this.additions = new HashMap<>();
}

/**
* Search through a specific section in your config for the heads.
*
* @param section The standard node {@link org.bukkit.configuration.Configuration} section from your file to use.
* Example: <strong>ConfigHeader.My_heads</strong>
* @return The same head loader instance with attempted values.
*/
public CustomHeadLoader look(String section) {
if (manager.isConfigurationSection(section)) {
for (String id : manager.getConfigurationSection(section).getKeys(false)) {
Expand Down Expand Up @@ -77,6 +84,9 @@ public CustomHeadLoader look(String section) {
return this;
}

/**
* @return Optionally pre-load all player related requests. (Handled internally)
*/
public CustomHeadLoader load() {
this.loaded = true;
for (Map.Entry<HeadText, OnlineHeadSearch> entry : this.que.entrySet()) {
Expand All @@ -90,6 +100,9 @@ public CustomHeadLoader load() {
return this;
}

/**
* Complete the requirements to load the desired head database into cache.
*/
public void complete() {
if (!getHeads().isEmpty()) {
CustomHead.Manager.load(this);
Expand All @@ -109,7 +122,7 @@ protected boolean isLoaded() {

/**
* Apply Base64 data for a custom skin value.
* <p>
*
* *NOTE: Not cached.
*
* @param headValue The target head value to apply to a skull item.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@ final class LabyrinthHeadImpl extends CustomHead {
}

@Override
@NotNull ItemStack get() {
public @NotNull ItemStack get() {
return this.item;
}

@Override
@NotNull String name() {
public @NotNull String name() {
return this.name;
}

@Override
@NotNull String category() {
public @NotNull String category() {
return this.category;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
import org.jetbrains.annotations.Nullable;

/**
* Encapsulate data and search online for results.
* Encapsulate player data and search online for skin results.
*/
public class OnlineHeadSearch {

private String name = null;
private String id = null;
private String value = null;
protected String name = null;
protected String id = null;
protected String value = null;

public OnlineHeadSearch(String name) {
this.name = name;
Expand Down

0 comments on commit 3713a96

Please sign in to comment.