EpicHeads/src/main/java/com/songoda/epicheads/EpicHeads.java

331 lines
12 KiB
Java

package com.songoda.epicheads;
import com.songoda.core.SongodaCore;
import com.songoda.core.SongodaPlugin;
import com.songoda.core.commands.CommandManager;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.configuration.Config;
import com.songoda.core.database.DataMigrationManager;
import com.songoda.core.database.DatabaseConnector;
import com.songoda.core.database.SQLiteConnector;
import com.songoda.core.gui.GuiManager;
import com.songoda.core.hooks.EconomyManager;
import com.songoda.core.hooks.PluginHook;
import com.songoda.core.hooks.economies.Economy;
import com.songoda.epicheads.commands.*;
import com.songoda.epicheads.database.DataManager;
import com.songoda.epicheads.database.migrations._1_InitialMigration;
import com.songoda.epicheads.head.Category;
import com.songoda.epicheads.head.Head;
import com.songoda.epicheads.head.HeadManager;
import com.songoda.epicheads.listeners.DeathListeners;
import com.songoda.epicheads.listeners.ItemListeners;
import com.songoda.epicheads.listeners.LoginListeners;
import com.songoda.epicheads.players.EPlayer;
import com.songoda.epicheads.players.PlayerManager;
import com.songoda.epicheads.settings.Settings;
import com.songoda.epicheads.utils.storage.Storage;
import com.songoda.epicheads.utils.storage.StorageRow;
import com.songoda.epicheads.utils.storage.types.StorageYaml;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.plugin.PluginManager;
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.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public class EpicHeads extends SongodaPlugin {
private static EpicHeads INSTANCE;
private final GuiManager guiManager = new GuiManager(this);
private HeadManager headManager;
private PlayerManager playerManager;
private CommandManager commandManager;
private PluginHook itemEconomyHook;
private DatabaseConnector databaseConnector;
private DataManager dataManager;
public static EpicHeads getInstance() {
return INSTANCE;
}
@Override
public void onPluginLoad() {
INSTANCE = this;
this.itemEconomyHook = PluginHook.addHook(Economy.class, "EpicHeads", com.songoda.epicheads.utils.ItemEconomy.class);
}
@Override
public void onPluginDisable() {
shutdownDataManager(this.dataManager);
this.databaseConnector.closeConnection();
}
@Override
public void onPluginEnable() {
// Run Songoda Updater
SongodaCore.registerPlugin(this, 26, CompatibleMaterial.PLAYER_HEAD);
// Load Economy
EconomyManager.load();
// Setup Managers
this.headManager = new HeadManager();
this.playerManager = new PlayerManager();
// Setup Config
Settings.setupConfig();
this.setLocale(Settings.LANGUGE_MODE.getString(), false);
// Set economy preference
String ecoPreference = Settings.ECONOMY_PLUGIN.getString();
if (ecoPreference.equalsIgnoreCase("item")) {
EconomyManager.getManager().setPreferredHook(itemEconomyHook);
} else {
EconomyManager.getManager().setPreferredHook(ecoPreference);
}
// Register commands
this.commandManager = new CommandManager(this);
this.commandManager.addCommand(new CommandEpicHeads(guiManager))
.addSubCommands(
new CommandAdd(this),
new CommandBase64(this),
new CommandGive(this),
new CommandGiveToken(this),
new CommandHelp(this),
new CommandReload(this),
new CommandSearch(guiManager),
new CommandSettings(guiManager),
new CommandUrl(this)
);
// Register Listeners
guiManager.init();
PluginManager pluginManager = Bukkit.getPluginManager();
pluginManager.registerEvents(new DeathListeners(this), this);
pluginManager.registerEvents(new ItemListeners(this), this);
pluginManager.registerEvents(new LoginListeners(this), this);
// Download Heads
downloadHeads();
// Load Heads
loadHeads();
int timeout = Settings.AUTOSAVE.getInt() * 60 * 20;
Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> dataManager.saveAllPlayers(), timeout, timeout);
}
@Override
public void onDataLoad() {
// Database stuff.
this.databaseConnector = new SQLiteConnector(this);
this.getLogger().info("Data handler connected using SQLite.");
this.dataManager = new DataManager(this.databaseConnector, this);
DataMigrationManager dataMigrationManager = new DataMigrationManager(this.databaseConnector, this.dataManager,
new _1_InitialMigration());
dataMigrationManager.runMigrations();
Bukkit.getScheduler().runTaskAsynchronously(this, () -> {
// Legacy data! Yay!
File folder = getDataFolder();
File dataFile = new File(folder, "data.yml");
boolean converted = false;
if (dataFile.exists()) {
converted = true;
Storage storage = new StorageYaml(this);
if (storage.containsGroup("players")) {
console.sendMessage("[" + getDescription().getName() + "] " + ChatColor.RED +
"Conversion process starting. Do NOT turn off your server. " +
"EpicHeads hasn't fully loaded yet, so make sure users don't" +
"interact with the plugin until the conversion process is complete.");
List<EPlayer> players = new ArrayList<>();
for (StorageRow row : storage.getRowsByGroup("players")) {
if (row.get("uuid").asObject() == null) {
continue;
}
players.add(new EPlayer(
UUID.fromString(row.get("uuid").asString()),
(List<String>) row.get("favorites").asObject()));
}
dataManager.migratePlayers(players);
}
if (storage.containsGroup("local")) {
for (StorageRow row : storage.getRowsByGroup("local")) {
String tagStr = row.get("category").asString();
Optional<Category> tagOptional = headManager.getCategories().stream()
.filter(t -> t.getName().equalsIgnoreCase(tagStr)).findFirst();
Category category = tagOptional.orElseGet(() -> new Category(tagStr));
Head head = new Head(row.get("id").asInt(),
row.get("name").asString(),
row.get("url").asString(),
category,
true,
null,
(byte) 0);
dataManager.createLocalHead(head);
}
if (storage.containsGroup("disabled")) {
List<Integer> ids = new ArrayList<>();
for (StorageRow row : storage.getRowsByGroup("disabled")) {
ids.add(row.get("id").asInt());
}
dataManager.migrateDisabledHead(ids);
}
}
dataFile.delete();
}
final boolean finalConverted = converted;
dataManager.queueAsync(() -> {
if (finalConverted) {
console.sendMessage("[" + getDescription().getName() + "] " + ChatColor.GREEN + "Conversion complete :)");
}
this.dataManager.getLocalHeads((heads) -> {
this.headManager.addLocalHeads(heads);
getLogger().info("Loaded " + headManager.getHeads().size() + " heads");
});
this.dataManager.getDisabledHeads((ids) -> {
for (int id : ids) {
headManager.disableHead(new Head(id, false));
}
});
}, "create");
});
}
private void downloadHeads() {
try {
InputStream is = new URL("https://songoda.github.io/EpicHeads/heads.json").openStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
String jsonText = readAll(rd);
JSONParser parser = new JSONParser();
JSONArray json = (JSONArray) parser.parse(jsonText);
try (FileWriter file = new FileWriter(new File(getDataFolder(), "heads.json"))) {
file.write(json.toJSONString());
}
} catch (Exception ex) {
getLogger().warning("Failed to download heads: " + ex.getMessage());
}
}
private boolean loadHeads() {
try {
this.headManager.clear();
this.headManager.addCategory(new Category(getLocale()
.getMessage("general.word.latestpack").getMessage(), true));
JSONParser parser = new JSONParser();
JSONArray jsonArray = (JSONArray) parser.parse(new FileReader(getDataFolder() + "/heads.json"));
for (Object o : jsonArray) {
JSONObject jsonObject = (JSONObject) o;
String categoryStr = (String) jsonObject.get("tags");
Optional<Category> tagOptional = headManager.getCategories().stream().filter(t -> t.getName().equalsIgnoreCase(categoryStr)).findFirst();
Category category = tagOptional.orElseGet(() -> new Category(categoryStr));
int id = Integer.parseInt((String) jsonObject.get("id"));
Head head = new Head(id,
(String) jsonObject.get("name"),
(String) jsonObject.get("url"),
category,
false,
(String) jsonObject.get("pack"),
Byte.parseByte((String) jsonObject.get("staff_picked")));
if (head.getName() == null || head.getName().equals("null")
|| head.getPack() != null && head.getPack().equals("null")) continue;
if (!tagOptional.isPresent())
headManager.addCategory(category);
headManager.addHead(head);
}
} catch (IOException | ParseException ex) {
getLogger().warning(() -> {
if (ex instanceof ParseException) {
return "Disabling plugin, failed to parse heads: " + ex.getMessage();
}
return "Disabling plugin, failed to load heads: " + ex.getMessage();
});
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();
}
@Override
public void onConfigReload() {
this.setLocale(getConfig().getString("System.Language Mode"), true);
this.locale.reloadMessages();
downloadHeads();
loadHeads();
}
@Override
public List<Config> getExtraConfig() {
return null;
}
public CommandManager getCommandManager() {
return commandManager;
}
public HeadManager getHeadManager() {
return headManager;
}
public PlayerManager getPlayerManager() {
return playerManager;
}
public DatabaseConnector getDatabaseConnector() {
return databaseConnector;
}
public DataManager getDataManager() {
return dataManager;
}
}