The plugin part of the commit.

This commit is contained in:
Brianna 2019-05-05 03:28:55 -04:00
parent 59df9ab932
commit 3067532b6f
10 changed files with 689 additions and 2 deletions

View File

@ -1,9 +1,15 @@
package com.songoda.epicheads;
import com.songoda.epicheads.command.CommandManager;
import com.songoda.epicheads.head.Head;
import com.songoda.epicheads.head.HeadManager;
import com.songoda.epicheads.head.Tag;
import com.songoda.epicheads.listeners.ItemListeners;
import com.songoda.epicheads.players.PlayerManager;
import com.songoda.epicheads.utils.Methods;
import com.songoda.epicheads.utils.ServerVersion;
import com.songoda.epicheads.utils.SettingsManager;
import com.songoda.epicheads.utils.gui.AbstractGUI;
import com.songoda.epicheads.utils.updateModules.LocaleModule;
import com.songoda.update.Plugin;
import com.songoda.update.SongodaUpdate;
@ -11,6 +17,15 @@ import org.apache.commons.lang.ArrayUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.java.JavaPlugin;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.*;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Optional;
public class EpicHeads extends JavaPlugin {
private static CommandSender console = Bukkit.getConsoleSender();
@ -19,6 +34,8 @@ public class EpicHeads extends JavaPlugin {
private ServerVersion serverVersion = ServerVersion.fromPackageName(Bukkit.getServer().getClass().getPackage().getName());
private HeadManager headManager;
private PlayerManager playerManager;
private SettingsManager settingsManager;
private CommandManager commandManager;
@ -53,8 +70,20 @@ public class EpicHeads extends JavaPlugin {
this.references = new References();
// Setup Managers
this.headManager = new HeadManager();
this.playerManager = new PlayerManager();
this.commandManager = new CommandManager(this);
// Register Listeners
AbstractGUI.initializeListeners(this);
Bukkit.getPluginManager().registerEvents(new ItemListeners(this), this);
// Download Heads
downloadHeads();
// Load Heads
loadHeads();
console.sendMessage(Methods.formatText("&a============================="));
}
@ -66,6 +95,76 @@ public class EpicHeads extends JavaPlugin {
console.sendMessage(Methods.formatText("&a============================="));
}
private void downloadHeads() {
try {
InputStream is = new URL("http://www.head-db.com/dump").openStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
String jsonText = readAll(rd);
JSONParser parser = new JSONParser();
JSONArray json = (JSONArray) parser.parse(jsonText);
try (FileWriter file = new FileWriter(getDataFolder() + "/heads.json")) {
file.write(json.toJSONString());
}
} catch (Exception e) {
System.out.println("Failed to download heads.");
}
}
private boolean loadHeads() {
try {
JSONParser parser = new JSONParser();
JSONArray jsonArray = (JSONArray) parser.parse(new FileReader(getDataFolder() + "/heads.json"));
for (Object o : jsonArray) {
JSONObject jsonObject = (JSONObject) o;
String tags = (String) jsonObject.get("tags");
Optional<Tag> tagOptional = headManager.getTags().stream().filter(t -> t.getName().equalsIgnoreCase(tags)).findFirst();
Tag tag = tagOptional.orElseGet(() -> new Tag(tags, -1));
Head head = new Head(Integer.parseInt((String) jsonObject.get("id")),
(String) jsonObject.get("name"),
(String) jsonObject.get("url"),
tag,
Byte.parseByte((String) jsonObject.get("staff_picked")));
if (head.getName() == null ||
head.getName().equals("null")) continue;
if (!tagOptional.isPresent())
headManager.addTag(tag);
headManager.addHead(head);
}
for (Tag tag : headManager.getTags()) {
tag.setCount(Math.toIntExact(headManager.getHeads().stream().filter(head -> head.getTag() == tag).count()));
}
System.out.println("loaded " + headManager.getHeads().size() + " Heads.");
} catch (IOException e) {
System.out.println("Heads file not found. Plugin disabling.");
return false;
} catch (ParseException e) {
System.out.println("Failed to parse heads file. Plugin disabling.");
return false;
}
return true;
}
private static String readAll(Reader rd) throws IOException {
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
return sb.toString();
}
public ServerVersion getServerVersion() {
return serverVersion;
}
@ -102,6 +201,14 @@ public class EpicHeads extends JavaPlugin {
return references;
}
public HeadManager getHeadManager() {
return headManager;
}
public PlayerManager getPlayerManager() {
return playerManager;
}
public CommandManager getCommandManager() {
return commandManager;
}

View File

@ -0,0 +1,203 @@
package com.songoda.epicheads.gui;
import com.songoda.epicheads.EpicHeads;
import com.songoda.epicheads.head.Head;
import com.songoda.epicheads.head.Tag;
import com.songoda.epicheads.players.EPlayer;
import com.songoda.epicheads.utils.AbstractChatConfirm;
import com.songoda.epicheads.utils.gui.AbstractGUI;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class GUIHeads extends AbstractGUI {
private final EpicHeads plugin;
private List<Head> heads;
private int page = 0;
private int maxPage;
private String query;
public GUIHeads(EpicHeads plugin, Player player, String query, List<Head> heads) {
super(player);
this.plugin = plugin;
this.query = query;
List<Integer> favorites = plugin.getPlayerManager().getPlayer(player).getFavorites();
this.heads = heads.stream()
.sorted(Comparator.comparing(Head::getName))
.sorted(Comparator.comparingInt(head -> (head.getStaffPicked() == 1 ? 0 : 1)))
.sorted(Comparator.comparingInt(head -> (favorites.contains(head.getId()) ? 0 : 1)))
.collect(Collectors.toList());
updateTitle();
}
private void updateTitle() {
int numHeads = this.heads.size();
if (numHeads == 0) {
player.sendMessage("No heads found.");
return;
}
Tag tag = heads.get(0).getTag();
this.maxPage = (int) Math.floor(numHeads / 45.0);
init((query != null ? "Query: " + query : tag.getName()) + " (" + numHeads + ") Page " + (page + 1) + "/" + (maxPage + 1), 54);
constructGUI();
}
@Override
protected void constructGUI() {
resetClickables();
registerClickables();
List<Head> heads = this.heads.stream().skip(page * 45).limit(45)
.collect(Collectors.toList());
if (page - 2 > 0) {
createButton(0, Material.ARROW, "Back");
registerClickable(0, ((player1, inventory1, cursor, slot, type) -> {
page -= 3;
updateTitle();
}));
inventory.getItem(0).setAmount(page - 2);
}
if (page - 1 > 0) {
createButton(1, Material.ARROW, "Back");
registerClickable(1, ((player1, inventory1, cursor, slot, type) -> {
page -= 2;
updateTitle();
}));
inventory.getItem(1).setAmount(page - 1);
}
if (page != 0) {
createButton(2, Material.ARROW, "Back");
registerClickable(2, ((player1, inventory1, cursor, slot, type) -> {
page--;
updateTitle();
}));
inventory.getItem(2).setAmount(page);
}
createButton(3, Material.COMPASS, "Create Search");
createButton(4, Material.MAP, "Back To Categories");
inventory.getItem(4).setAmount(page + 1);
if (heads.size() > 1)
createButton(5, Material.COMPASS, "Refine Search");
if (page != maxPage) {
createButton(6, Material.ARROW, "Next");
registerClickable(6, ((player1, inventory1, cursor, slot, type) -> {
page++;
updateTitle();
}));
inventory.getItem(6).setAmount(page + 2);
}
if (page + 1 < maxPage) {
createButton(7, Material.ARROW, "Next");
registerClickable(7, ((player1, inventory1, cursor, slot, type) -> {
page += 2;
updateTitle();
}));
inventory.getItem(7).setAmount(page + 3);
}
if (page + 2 < maxPage) {
createButton(8, Material.ARROW, "Next");
registerClickable(8, ((player1, inventory1, cursor, slot, type) -> {
page += 3;
updateTitle();
}));
inventory.getItem(8).setAmount(page + 4);
}
List<Integer> favorites = plugin.getPlayerManager().getPlayer(player).getFavorites();
for (int i = 0; i < heads.size(); i++) {
Head head = heads.get(i);
if (head.getName() == null) continue;
ItemStack item = head.asItemStack(favorites.contains(head.getId()));
inventory.setItem(i + 9, item);
registerClickable(i + 9, ((player1, inventory1, cursor, slot, type) -> {
if (type == ClickType.SHIFT_LEFT || type == ClickType.SHIFT_RIGHT) {
EPlayer ePlayer = plugin.getPlayerManager().getPlayer(player);
if (!ePlayer.getFavorites().contains(head.getId()))
ePlayer.addFavorite(head.getId());
else
ePlayer.removeFavorite(head.getId());
updateTitle();
return;
}
ItemMeta meta = item.getItemMeta();
meta.setLore(new ArrayList<>());
item.setItemMeta(meta);
player.getInventory().addItem(item);
}));
}
}
@Override
protected void registerClickables() {
registerClickable(4, ((player1, inventory1, cursor, slot, type) ->
new GUIOverview(plugin, player)));
registerClickable(3, ((player1, inventory1, cursor, slot, type) ->
doSearch(player1)));
if (heads.size() > 1) {
registerClickable(5, ((player1, inventory1, cursor, slot, type) -> {
player.sendMessage("Refine your search...");
AbstractChatConfirm abstractChatConfirm = new AbstractChatConfirm(player, event -> {
this.page = 0;
this.heads = this.heads.stream().filter(head -> head.getName().toLowerCase()
.contains(event.getMessage().toLowerCase())).collect(Collectors.toList());
if (query == null)
this.query = event.getMessage();
else
this.query += ", " + event.getMessage();
});
abstractChatConfirm.setOnClose(this::updateTitle);
}));
}
}
@Override
protected void registerOnCloses() {
}
public static void doSearch(Player player) {
player.sendMessage("Enter your query...");
new AbstractChatConfirm(player, event -> {
List<Head> heads = EpicHeads.getInstance().getHeadManager().getHeads().stream()
.filter(head -> head.getName().toLowerCase().contains(event.getMessage().toLowerCase()))
.collect(Collectors.toList());
Bukkit.getScheduler().scheduleSyncDelayedTask(EpicHeads.getInstance(), () ->
new GUIHeads(EpicHeads.getInstance(), player, event.getMessage(), heads), 0L);
});
}
}

View File

@ -1,9 +1,14 @@
package com.songoda.epicheads.gui;
import com.songoda.epicheads.EpicHeads;
import com.songoda.epicheads.head.Tag;
import com.songoda.epicheads.utils.Methods;
import com.songoda.epicheads.utils.gui.AbstractGUI;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.List;
public class GUIOverview extends AbstractGUI {
private final EpicHeads plugin;
@ -12,17 +17,63 @@ public class GUIOverview extends AbstractGUI {
super(player);
this.plugin = plugin;
init("Heads", 54);
init("EpicHeads (" + plugin.getHeadManager().getHeads().size() + " heads)", 45);
}
@Override
protected void constructGUI() {
createButton(5, Material.STONE, "&6&lView Favorites",
"Shift click any head",
"to save as a favorite.");
inventory.setItem(0, Methods.getBackgroundGlass(true));
inventory.setItem(1, Methods.getBackgroundGlass(true));
inventory.setItem(9, Methods.getBackgroundGlass(true));
inventory.setItem(7, Methods.getBackgroundGlass(true));
inventory.setItem(8, Methods.getBackgroundGlass(true));
inventory.setItem(17, Methods.getBackgroundGlass(true));
inventory.setItem(27, Methods.getBackgroundGlass(true));
inventory.setItem(36, Methods.getBackgroundGlass(true));
inventory.setItem(37, Methods.getBackgroundGlass(true));
inventory.setItem(35, Methods.getBackgroundGlass(true));
inventory.setItem(43, Methods.getBackgroundGlass(true));
inventory.setItem(44, Methods.getBackgroundGlass(true));
inventory.setItem(2, Methods.getBackgroundGlass(false));
inventory.setItem(6, Methods.getBackgroundGlass(false));
inventory.setItem(38, Methods.getBackgroundGlass(false));
inventory.setItem(42, Methods.getBackgroundGlass(false));
List<Tag> tags = plugin.getHeadManager().getTags();
int add = 0;
for (int i = 0; i < tags.size(); i++) {
if (i + add == 7 || i + add == 16) add = add + 2;
Tag tag = plugin.getHeadManager().getTags().get(i);
createButton(i + 10 + add, Material.STONE, "&c&l" + tag.getName(), "&e" + tag.getCount() + " heads");
registerClickable(i + 10 + add, ((player1, inventory1, cursor, slot, type) -> new GUIHeads(plugin, player, null, plugin.getHeadManager().getHeadsByTag(tag))));
}
createButton(39, Material.COMPASS, "Search");
createButton(41, Material.STONE,
"Add or request new heads",
"in our discord server.");
}
@Override
protected void registerClickables() {
registerClickable(5, ((player1, inventory1, cursor, slot, type) ->
new GUIHeads(plugin, player, null, plugin.getPlayerManager().getPlayer(player).getFavoritesAsHeads())));
registerClickable(39, ((player1, inventory1, cursor, slot, type) ->
GUIHeads.doSearch(player1)));
}
@Override

View File

@ -0,0 +1,79 @@
package com.songoda.epicheads.head;
import com.songoda.epicheads.utils.Methods;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.List;
public class Head {
private final int id;
private final String name;
private final String URL;
private final byte staffPicked;
private final Tag tag;
public Head(int id, String name, String URL, Tag tag, byte staffPicked) {
this.id = id;
this.name = name;
this.URL = URL;
this.tag = tag;
this.staffPicked = staffPicked;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public String getURL() {
return URL;
}
public Tag getTag() {
return tag;
}
public byte getStaffPicked() {
return staffPicked;
}
public ItemStack asItemStack() {
return asItemStack(false);
}
public ItemStack asItemStack(boolean favorite) {
ItemStack item = Methods.addTexture(new ItemStack(Material.PLAYER_HEAD, 1, (byte) 3),
this.URL);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(Methods.formatText((favorite ? "&6⭐ " : "") + "&9" + name));
List<String> lore = new ArrayList<>();
if (this.staffPicked == 1)
lore.add(Methods.formatText("&8Staff Favorite"));
lore.add(Methods.formatText("&8ID: &7" + this.id));
meta.setLore(lore);
item.setItemMeta(meta);
return item;
}
@Override
public String toString() {
return "Head:{"
+ "Id:\"" + id + "\","
+ "Name:\"" + name + "\","
+ "URL:\"" + URL + "\","
+ "Tags:\"" + tag.getName() + "\","
+ "StaffPicked:\"" + staffPicked + "\""
+ "}";
}
}

View File

@ -0,0 +1,57 @@
package com.songoda.epicheads.head;
import java.util.*;
import java.util.stream.Collectors;
public class HeadManager {
private static final Set<Head> registeredHeads = new HashSet<>();
private static final List<Tag> registeredTags = new ArrayList<>();
public Head addHead(Head head) {
registeredHeads.add(head);
return head;
}
public void addHeads(Head... heads) {
registeredHeads.addAll(Arrays.asList(heads));
}
public void addHeads(Collection<Head> heads) {
registeredHeads.addAll(heads);
}
public Head getHead(String name) {
return registeredHeads.stream().filter(head -> head.getName().equals(name)).findFirst().orElse(null);
}
public List<Head> getHeadsByQuery(String query) {
List<Head> result = registeredHeads.stream().filter(head -> head.getName().contains(query)).collect(Collectors.toList());
if (result.isEmpty()) {
for (Tag tag : registeredTags) {
if (!tag.getName().equalsIgnoreCase(query)) continue;
return registeredHeads.stream().filter(head -> head.getTag() == tag).collect(Collectors.toList());
}
}
return result;
}
public List<Head> getHeadsByTag(Tag tag) {
return registeredHeads.stream().filter(head -> head.getTag() == tag).collect(Collectors.toList());
}
public Set<Head> getHeads() {
return Collections.unmodifiableSet(registeredHeads);
}
public Tag addTag(Tag tag) {
registeredTags.add(tag);
return tag;
}
public List<Tag> getTags() {
return Collections.unmodifiableList(registeredTags);
}
}

View File

@ -0,0 +1,24 @@
package com.songoda.epicheads.head;
public class Tag {
private final String name;
private int count;
public Tag(String name, int count) {
this.name = name;
this.count = count;
}
public String getName() {
return name;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}

View File

@ -0,0 +1,57 @@
package com.songoda.epicheads.listeners;
import com.songoda.epicheads.EpicHeads;
import com.songoda.epicheads.head.Head;
import com.songoda.epicheads.utils.Methods;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.metadata.FixedMetadataValue;
import java.util.ArrayList;
import java.util.Optional;
public class ItemListeners implements Listener {
private final EpicHeads plugin;
public ItemListeners(EpicHeads plugin) {
this.plugin = plugin;
}
@EventHandler
public void itemPickupEvent(EntityPickupItemEvent event) {
ItemStack item = event.getItem().getItemStack();
if (item.getType() != Material.PLAYER_HEAD || event.getItem().hasMetadata("EHE")) return;
event.getItem().removeMetadata("EHE", plugin);
String url = Methods.getDecodedTexture(item);
if (url == null) return;
Optional<Head> optional = plugin.getHeadManager().getHeads().stream()
.filter(head -> url.equals(head.getURL())).findFirst();
if (optional.isPresent()) {
event.setCancelled(true);
event.getItem().setMetadata("EHE", new FixedMetadataValue(plugin, true));
ItemStack itemNew = optional.get().asItemStack();
itemNew.setAmount(item.getAmount());
ItemMeta meta = itemNew.getItemMeta();
meta.setLore(new ArrayList<>());
itemNew.setItemMeta(meta);
event.getItem().getWorld().dropItemNaturally(event.getEntity().getLocation().add(1, 1, 0), itemNew.clone());
event.getItem().setItemStack(itemNew);
}
}
}

View File

@ -0,0 +1,42 @@
package com.songoda.epicheads.players;
import com.songoda.epicheads.EpicHeads;
import com.songoda.epicheads.head.Head;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
public class EPlayer {
private final UUID uuid;
private List<Integer> favorites = new ArrayList<>();
public EPlayer(UUID uuid) {
this.uuid = uuid;
}
public UUID getUuid() {
return uuid;
}
public List<Integer> getFavorites() {
return new ArrayList<>(favorites);
}
public List<Head> getFavoritesAsHeads() {
return EpicHeads.getInstance().getHeadManager().getHeads().stream()
.filter(head -> favorites.contains(head.getId())).collect(Collectors.toList());
}
public void addFavorite(Integer integer) {
favorites.add(integer);
}
public void removeFavorite(Integer integer) {
favorites.remove(integer);
}
}

View File

@ -0,0 +1,21 @@
package com.songoda.epicheads.players;
import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class PlayerManager {
private static final Map<UUID, EPlayer> registeredHeads = new HashMap<>();
public EPlayer getPlayer(UUID uuid) {
return registeredHeads.computeIfAbsent(uuid, u -> new EPlayer(uuid));
}
public EPlayer getPlayer(Player player) {
return getPlayer(player.getUniqueId());
}
}

View File

@ -1,13 +1,59 @@
package com.songoda.epicheads.utils;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import com.songoda.epicheads.EpicHeads;
import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.Iterator;
import java.util.UUID;
public class Methods {
public static ItemStack addTexture(ItemStack item, String headURL) {
SkullMeta meta = (SkullMeta) item.getItemMeta();
GameProfile profile = new GameProfile(UUID.nameUUIDFromBytes(headURL.getBytes()), null);
byte[] encodedData = Base64.getEncoder().encode(String.format("{textures:{SKIN:{url:\"http://textures.minecraft.net/texture/%s\"}}}", new Object[]{headURL}).getBytes());
profile.getProperties().put("textures", new Property("textures", new String(encodedData)));
Field profileField;
try {
profileField = meta.getClass().getDeclaredField("profile");
profileField.setAccessible(true);
profileField.set(meta, profile);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
item.setItemMeta(meta);
return item;
}
public static String getDecodedTexture(ItemStack item) {
try {
SkullMeta localSkullMeta = (SkullMeta) item.getItemMeta();
Field localField = localSkullMeta.getClass().getDeclaredField("profile");
localField.setAccessible(true);
GameProfile localGameProfile = (GameProfile) localField.get(localSkullMeta);
Iterator localIterator = localGameProfile.getProperties().get("textures").iterator();
if (localIterator.hasNext()) {
Property localProperty = (Property) localIterator.next();
byte[] decoded = Base64.getDecoder().decode(localProperty.getValue());
return StringUtils.substringBetween(new String(decoded), "texture/", "\"");
}
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
public static ItemStack getGlass() {
EpicHeads instance = EpicHeads.getInstance();
return Methods.getGlass(instance.getConfig().getBoolean("Interfaces.Replace Glass Type 1 With Rainbow Glass"), instance.getConfig().getInt("Interfaces.Glass Type 1"));