mirror of
https://github.com/TotalFreedomMC/TF-Marriage.git
synced 2025-02-05 14:22:45 +00:00
update converter
This commit is contained in:
parent
22ac8e9538
commit
589798c1b6
8 changed files with 140 additions and 357 deletions
|
@ -3,6 +3,7 @@ package com.lenis0012.bukkit.marriage2.commands;
|
|||
import com.lenis0012.bukkit.marriage2.config.Permissions;
|
||||
import com.lenis0012.bukkit.marriage2.config.Settings;
|
||||
import com.lenis0012.bukkit.marriage2.internal.Dependencies;
|
||||
import com.lenis0012.pluginutils.modules.configuration.mapping.ConfigOption;
|
||||
import net.milkbowl.vault.economy.EconomyResponse;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
|
@ -169,8 +170,8 @@ public abstract class Command {
|
|||
this.hidden = hidden;
|
||||
}
|
||||
|
||||
protected void setExecutionFee(Settings<Double> setting) {
|
||||
if(!Settings.ECONOMY_ENABLED.value() || !Settings.ECONOMY_SHOW.value()) {
|
||||
protected void setExecutionFee(ConfigOption<Double> setting) {
|
||||
if(!Settings.ECONOMY_ENABLED.value() || !Settings.ECONOMY_SHOW_PRICE.value()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,113 +1,60 @@
|
|||
package com.lenis0012.bukkit.marriage2.config;
|
||||
|
||||
import java.util.List;
|
||||
import com.lenis0012.pluginutils.modules.configuration.mapping.ConfigHeader;
|
||||
import com.lenis0012.pluginutils.modules.configuration.mapping.ConfigOption;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import com.lenis0012.bukkit.marriage2.internal.MarriageCore;
|
||||
|
||||
public class Settings<T> {
|
||||
private static final List<Settings<?>> cache = Lists.newArrayList();
|
||||
|
||||
public class Settings {
|
||||
/**
|
||||
* Uncatagorized settings
|
||||
* Uncatagorized ConfigOption
|
||||
*/
|
||||
public static final Settings<Integer> REQUEST_EXPRY = new Settings<>("requestExpiry", 60);
|
||||
public static final Settings<Boolean> ENABLE_PRIEST = new Settings<>("enable-priests", false);
|
||||
public static final ConfigOption<Integer> REQUEST_EXPRY = new ConfigOption<>("requestExpiry", 60);
|
||||
public static final ConfigOption<Boolean> ENABLE_PRIEST = new ConfigOption<>("enable-priests", false);
|
||||
|
||||
/**
|
||||
* Cooldown
|
||||
*/
|
||||
public static final Settings<Integer> COOLDOWN_KISS = new Settings<>("cooldown.kiss", 2);
|
||||
public static final ConfigOption<Integer> COOLDOWN_KISS = new ConfigOption<>("cooldown.kiss", 2);
|
||||
|
||||
/**
|
||||
* Chat
|
||||
*/
|
||||
public static final Settings<String> PM_FORMAT = new Settings<>("chat.pm-format", "&4{heart}&c{name}&4{heart} &7{message}");
|
||||
public static final Settings<String> CHAT_FORMAT = new Settings<>("chat.status-format", "&4&l<3 &r");
|
||||
public static final Settings<Boolean> FORCE_FORMAT = new Settings<>("chat.force-status-format", true);
|
||||
@ConfigHeader(path = "chat", value = {
|
||||
"Chat, set the format of private messages and in-chat status.",
|
||||
"Supported tags for chat: {heart}, {partner}. for pm: {heart}, {name}, {message}",
|
||||
"If you use a custom chat plugin, put {marriage_status} in the format and set force-status-format to false"
|
||||
})
|
||||
public static final ConfigOption<String> PM_FORMAT = new ConfigOption<>("chat.pm-format", "&4{heart}&c{name}&4{heart} &7{message}");
|
||||
public static final ConfigOption<String> CHAT_FORMAT = new ConfigOption<>("chat.status-format", "&4&l<3 &r");
|
||||
public static final ConfigOption<Boolean> FORCE_FORMAT = new ConfigOption<>("chat.force-status-format", true);
|
||||
|
||||
/**
|
||||
* Kissing
|
||||
*/
|
||||
public static final Settings<Boolean> KISSES_ENABLED = new Settings<>("kisses.enabled", true);
|
||||
public static final Settings<Integer> KISSES_AMOUNT_MIN = new Settings<>("kisses.amount-min", 5);
|
||||
public static final Settings<Integer> KISSES_AMOUNT_MAX = new Settings<>("kisses.amount-max", 10);
|
||||
@ConfigHeader(path = "kisses", value = {
|
||||
"Kissing, display hearts when 2 married players kiss eachother.",
|
||||
"The amount of hearts is a random number between min and max."
|
||||
})
|
||||
public static final ConfigOption<Boolean> KISSES_ENABLED = new ConfigOption<>("kisses.enabled", true);
|
||||
public static final ConfigOption<Integer> KISSES_AMOUNT_MIN = new ConfigOption<>("kisses.amount-min", 5);
|
||||
public static final ConfigOption<Integer> KISSES_AMOUNT_MAX = new ConfigOption<>("kisses.amount-max", 10);
|
||||
|
||||
/**
|
||||
* Economy
|
||||
*/
|
||||
public static final Settings<Boolean> ECONOMY_ENABLED = new Settings<>("economy.enabled", false);
|
||||
public static final Settings<Boolean> ECONOMY_SHOW = new Settings<>("economy.show-on-help", true);
|
||||
public static final Settings<Double> PRICE_MARRY = new Settings<>("economy.marriage-price", 100.0);
|
||||
public static final Settings<Double> PRICE_TELEPORT = new Settings<>("economy.teleport-price", 0.0);
|
||||
public static final Settings<Double> PRICE_SETHOME = new Settings<>("economy.sethome-price", 0.0);
|
||||
public static final Settings<Double> PRICE_DIVORCE = new Settings<>("economy.divorce", 0.0);
|
||||
@ConfigHeader({"Economy settings, uses Vault.", "enable 'show-on-help' to show prices in help command."})
|
||||
public static final ConfigOption<Boolean> ECONOMY_ENABLED = new ConfigOption<>("economy.enabled", false);
|
||||
public static final ConfigOption<Boolean> ECONOMY_SHOW_PRICE = new ConfigOption<>("economy.show-on-help", true);
|
||||
public static final ConfigOption<Double> PRICE_MARRY = new ConfigOption<>("economy.marriage-price", 100.0);
|
||||
public static final ConfigOption<Double> PRICE_TELEPORT = new ConfigOption<>("economy.teleport-price", 0.0);
|
||||
public static final ConfigOption<Double> PRICE_SETHOME = new ConfigOption<>("economy.sethome-price", 0.0);
|
||||
public static final ConfigOption<Double> PRICE_DIVORCE = new ConfigOption<>("economy.divorce-price", 0.0);
|
||||
|
||||
public static final Settings<Boolean> ENABLE_UPDATE_CHACKER = new Settings<>("updater.enabled", true);
|
||||
public static final Settings<Boolean> ENABLE_CHANGELOG = new Settings<>("updater.changelog", true);
|
||||
|
||||
|
||||
|
||||
private final String key;
|
||||
private final T def;
|
||||
private T value;
|
||||
|
||||
private Settings(String key, T def) {
|
||||
cache.add(this);
|
||||
this.key = key;
|
||||
this.def = def;
|
||||
}
|
||||
|
||||
public T value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
private void writeToConfig(FileConfiguration config) {
|
||||
config.set(key, value);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void reload(FileConfiguration config) {
|
||||
if(config.contains(key)) {
|
||||
this.value = (T) config.get(key);
|
||||
} else {
|
||||
this.value = def;
|
||||
}
|
||||
}
|
||||
|
||||
public static final void reloadAll(MarriageCore core, boolean initial) {
|
||||
FileConfiguration config = core.getPlugin().getConfig();
|
||||
for(Settings<?> setting : cache) {
|
||||
setting.reload(config);
|
||||
}
|
||||
|
||||
if(initial) {
|
||||
// Reset config
|
||||
for(String key : config.getKeys(false)) {
|
||||
config.set(key, null);
|
||||
}
|
||||
|
||||
// Write current values
|
||||
for(Settings<?> setting : cache) {
|
||||
setting.writeToConfig(config);
|
||||
}
|
||||
|
||||
// Write header
|
||||
config.options().header("Marriage Reloaded 2.X\n\n" +
|
||||
"Expiry & Cool down is in seconds.\n\n" +
|
||||
"PM format supports: {heart}, {name}, {message}. Chat format supports {heart}, {partner}\n" +
|
||||
"Note: If you have a custom chat plugin, set forced to false and put {marriage_status}\n" +
|
||||
"somewhere in your chat plugin's format.\n\n" +
|
||||
"Economy setting show-on-help shows the fee when hovering over command.\n\n" +
|
||||
"The rest should be straight forward. if not, comment on bukkitdev.");
|
||||
core.getPlugin().saveConfig();
|
||||
}
|
||||
}
|
||||
|
||||
public static final List<Settings<?>> values() {
|
||||
return cache;
|
||||
}
|
||||
/**
|
||||
* Updater
|
||||
*/
|
||||
@ConfigHeader(path = "updater", value = {
|
||||
"Updater settings, checks for updates. We recommend to keep this enabled."
|
||||
})
|
||||
public static final ConfigOption<Boolean> ENABLE_UPDATE_CHACKER = new ConfigOption<>("updater.enabled", true);
|
||||
public static final ConfigOption<Boolean> ENABLE_CHANGELOG = new ConfigOption<>("updater.changelog", true);
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package com.lenis0012.bukkit.marriage2.internal;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -10,7 +9,7 @@ import com.lenis0012.bukkit.marriage2.MData;
|
|||
import com.lenis0012.bukkit.marriage2.config.Permissions;
|
||||
import com.lenis0012.bukkit.marriage2.internal.Register.Type;
|
||||
import com.lenis0012.bukkit.marriage2.internal.data.DataConverter;
|
||||
import com.lenis0012.pluginutils.modules.configuration.Configuration;
|
||||
import com.lenis0012.pluginutils.modules.configuration.ConfigurationModule;
|
||||
import com.lenis0012.updater.api.Updater;
|
||||
import com.lenis0012.updater.api.UpdaterFactory;
|
||||
import org.bukkit.Bukkit;
|
||||
|
@ -40,26 +39,15 @@ public class MarriageCore extends MarriageBase {
|
|||
public void loadConfig() {
|
||||
// plugin.saveDefaultConfig();
|
||||
enable();
|
||||
Settings.reloadAll(this, true);
|
||||
|
||||
// Settings
|
||||
ConfigurationModule module = plugin.getModule(ConfigurationModule.class);
|
||||
module.registerSettings(Settings.class);
|
||||
module.reloadSettings(Settings.class, true);
|
||||
|
||||
// Messages
|
||||
Message.reloadAll(this);
|
||||
Permissions.setupChildRelations();
|
||||
|
||||
File file = new File("test.yml");
|
||||
Configuration config = new Configuration(file);
|
||||
if(file.exists()) {
|
||||
config.reload();
|
||||
config.set("settings.economy.currency", "dollars");
|
||||
} else {
|
||||
config.header("settings.economy", "Economy settings are in dollars.", "Enable to hook with vault");
|
||||
config.header("settings.x", "A value that decides how old you are");
|
||||
config.set("settings.economy.enabled", false);
|
||||
config.set("setting.economy.price", 50.0);
|
||||
config.set("settings.x", 15);
|
||||
config.set("settings.y", 33);
|
||||
config.set("settings.z", 12);
|
||||
}
|
||||
|
||||
config.save();
|
||||
}
|
||||
|
||||
@Register(name = "dependencies", type = Type.ENABLE, priority = 1)
|
||||
|
|
|
@ -6,11 +6,14 @@ import java.util.List;
|
|||
import java.util.logging.Level;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.lenis0012.pluginutils.PluginHolder;
|
||||
import com.lenis0012.pluginutils.modules.configuration.ConfigurationModule;
|
||||
import com.lenis0012.pluginutils.modules.packets.PacketModule;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import com.lenis0012.bukkit.marriage2.Marriage;
|
||||
|
||||
public class MarriagePlugin extends JavaPlugin {
|
||||
public class MarriagePlugin extends PluginHolder {
|
||||
private static MarriageCore core;
|
||||
|
||||
public static Marriage getInstance() {
|
||||
|
@ -21,6 +24,8 @@ public class MarriagePlugin extends JavaPlugin {
|
|||
private final List<Method>[] methods = new List[Register.Type.values().length];
|
||||
|
||||
public MarriagePlugin() {
|
||||
super(PacketModule.class,
|
||||
ConfigurationModule.class);
|
||||
core = new MarriageCore(this);
|
||||
|
||||
//Scan methods
|
||||
|
@ -57,12 +62,12 @@ public class MarriagePlugin extends JavaPlugin {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
public void enable() {
|
||||
executeMethods(Register.Type.ENABLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
public void disable() {
|
||||
executeMethods(Register.Type.DISABLE);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,9 +7,11 @@ import com.lenis0012.bukkit.marriage2.internal.MarriageCore;
|
|||
import com.lenis0012.bukkit.marriage2.misc.UUIDFetcher;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.craftbukkit.v1_9_R1.CraftServer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
@ -36,43 +38,87 @@ public class DataConverter {
|
|||
File[] files = dir.listFiles();
|
||||
int totalFiles = files.length;
|
||||
core.getLogger().log(Level.INFO, "Converting " + totalFiles + " old database entries...");
|
||||
core.getLogger().log(Level.INFO, "Retrieving UUIDs...");
|
||||
|
||||
// Retrieve UUIDs from mojang
|
||||
Map<String, UUID> uuidMap = Maps.newHashMap();
|
||||
UUIDFetcher uuidFetcher = new UUIDFetcher(new ArrayList<String>());
|
||||
int ranThroughMojang = 0;
|
||||
int failed = 0;
|
||||
for(int completed = 0; completed < totalFiles; completed++) {
|
||||
File file = files[completed];
|
||||
String name = file.getName().replace(".yml", "");
|
||||
if(files.length > 50000) {
|
||||
// Over 500 requests, check for marriage
|
||||
try {
|
||||
FileConfiguration cnf = YamlConfiguration.loadConfiguration(file);
|
||||
cnf.load(file);
|
||||
String partner = cnf.getString("partner");
|
||||
if(partner == null) continue;
|
||||
} catch(Exception e) {
|
||||
continue; // skip
|
||||
}
|
||||
}
|
||||
|
||||
uuidFetcher.addName(name);
|
||||
if(uuidFetcher.size() >= 100 || completed >= totalFiles - 1) {
|
||||
try {
|
||||
uuidMap.putAll(uuidFetcher.call());
|
||||
uuidFetcher = new UUIDFetcher(new ArrayList<String>());
|
||||
} catch(Exception e) {
|
||||
core.getLogger().log(Level.WARNING, "Failed to retrieve UUID for 100 players!");
|
||||
}
|
||||
}
|
||||
|
||||
// status report
|
||||
double progress = (completed + 1.0) / (double) totalFiles;
|
||||
if(System.currentTimeMillis() >= lastMessage) {
|
||||
lastMessage = System.currentTimeMillis() + 2500; // Update every 2.5 seconds
|
||||
reportStatus(progress);
|
||||
}
|
||||
|
||||
// Pull from cache
|
||||
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(name);
|
||||
if(offlinePlayer != null) {
|
||||
UUID userId = offlinePlayer.getUniqueId();
|
||||
if(userId != null) {
|
||||
uuidMap.put(name, userId);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Pull from mojang
|
||||
if(ranThroughMojang >= 50000) { // Max 500 requests
|
||||
failed += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
uuidFetcher.addName(name);
|
||||
ranThroughMojang += 1;
|
||||
if(uuidFetcher.size() == 100) {
|
||||
try {
|
||||
uuidMap.putAll(uuidFetcher.call());
|
||||
} catch(Exception e){
|
||||
core.getLogger().log(Level.WARNING, "Failed to retrieve UUID for 100 players!");
|
||||
}
|
||||
uuidFetcher = new UUIDFetcher(new ArrayList<String>());
|
||||
}
|
||||
}
|
||||
|
||||
core.getLogger().log(Level.INFO, String.format("Converted %s entries. %s locally, %s through mojang, %s failed.",
|
||||
totalFiles, totalFiles - ranThroughMojang - failed, ranThroughMojang, failed));
|
||||
core.getLogger().log(Level.INFO, "Failed entries are likely from inactive players.");
|
||||
|
||||
// for(int completed = 0; completed < totalFiles; completed++) {
|
||||
// File file = files[completed];
|
||||
// String name = file.getName().replace(".yml", "");
|
||||
// if(files.length > 50000) {
|
||||
// // Over 500 requests, check for marriage
|
||||
// try {
|
||||
// FileConfiguration cnf = YamlConfiguration.loadConfiguration(file);
|
||||
// cnf.load(file);
|
||||
// String partner = cnf.getString("partner");
|
||||
// if(partner == null) continue;
|
||||
// } catch(Exception e) {
|
||||
// continue; // skip
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// uuidFetcher.addName(name);
|
||||
// if(uuidFetcher.size() >= 100 || completed >= totalFiles - 1) {
|
||||
// try {
|
||||
// uuidMap.putAll(uuidFetcher.call());
|
||||
// uuidFetcher = new UUIDFetcher(new ArrayList<String>());
|
||||
// } catch(Exception e) {
|
||||
// core.getLogger().log(Level.WARNING, "Failed to retrieve UUID for 100 players!");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// double progress = (completed + 1.0) / (double) totalFiles;
|
||||
// if(System.currentTimeMillis() >= lastMessage) {
|
||||
// lastMessage = System.currentTimeMillis() + 2500; // Update every 2.5 seconds
|
||||
// reportStatus(progress);
|
||||
// }
|
||||
// }
|
||||
|
||||
// Insert data into new DB...
|
||||
core.getLogger().log(Level.INFO, "Inserting user data into new database...");
|
||||
int completed = 0;
|
||||
|
|
|
@ -5,8 +5,9 @@ import com.lenis0012.bukkit.marriage2.MPlayer;
|
|||
import com.lenis0012.bukkit.marriage2.config.Settings;
|
||||
import com.lenis0012.bukkit.marriage2.internal.MarriageCore;
|
||||
import com.lenis0012.bukkit.marriage2.misc.Cooldown;
|
||||
import com.lenis0012.bukkit.marriage2.misc.reflection.Packets;
|
||||
import com.lenis0012.bukkit.marriage2.misc.reflection.Reflection;
|
||||
import com.lenis0012.pluginutils.misc.Reflection;
|
||||
import com.lenis0012.pluginutils.modules.packets.Packet;
|
||||
import com.lenis0012.pluginutils.modules.packets.PacketModule;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -69,18 +70,18 @@ public class KissListener implements Listener {
|
|||
int min = Settings.KISSES_AMOUNT_MIN.value();
|
||||
int max = Settings.KISSES_AMOUNT_MAX.value();
|
||||
int amount = min + random.nextInt(max - min + 1);
|
||||
Object packet = Packets.createPacket("PacketPlayOutWorldParticles");
|
||||
Packets.set(packet, "a", Reflection.invokeMethod(GET_PARTICLE_BY_ID, null, 34));
|
||||
Packets.set(packet, "b", (float) l.getX());
|
||||
Packets.set(packet, "c", (float) l.getY());
|
||||
Packets.set(packet, "d", (float) l.getZ());
|
||||
Packets.set(packet, "e", 0.3F);
|
||||
Packets.set(packet, "f", 0.3F);
|
||||
Packets.set(packet, "g", 0.3F);
|
||||
Packets.set(packet, "h", 1F);
|
||||
Packets.set(packet, "i", amount);
|
||||
for(Player player : l.getWorld().getPlayers()) {
|
||||
Packets.send(player, packet);
|
||||
}
|
||||
|
||||
PacketModule module = core.getPlugin().getModule(PacketModule.class);
|
||||
Packet packet = module.createPacket("PacketPlayOutWorldParticles");
|
||||
packet.write("a", Reflection.invokeMethod(GET_PARTICLE_BY_ID, null, 34));
|
||||
packet.write("b", (float) l.getX());
|
||||
packet.write("c", (float) l.getY());
|
||||
packet.write("d", (float) l.getZ());
|
||||
packet.write("e", 0.3F);
|
||||
packet.write("f", 0.3F);
|
||||
packet.write("g", 0.3F);
|
||||
packet.write("h", 1F);
|
||||
packet.write("i", amount);
|
||||
module.broadcastPacket(l.getWorld(), packet);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
package com.lenis0012.bukkit.marriage2.misc.reflection;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.lenis0012.bukkit.marriage2.misc.reflection.Reflection.ClassReflection;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
public class Packets {
|
||||
private static final Map<String, ClassReflection> packetClasses = Maps.newConcurrentMap();
|
||||
private static final Method GET_HANDLE = Reflection.getCBMethod("entity.CraftPlayer", "getHandle");
|
||||
private static final Field PLAYER_CONNECTION = Reflection.getNMSField("EntityPlayer", "playerConnection");
|
||||
private static final Method SEND_PACKET = Reflection.getNMSMethod("PlayerConnection", "sendPacket", Reflection.getNMSClass("Packet"));
|
||||
|
||||
public static Object createPacket(String name) {
|
||||
ClassReflection ref = packetClasses.get(name);
|
||||
if(ref == null) {
|
||||
ref = new ClassReflection(Reflection.getNMSClass(name));
|
||||
packetClasses.put(name, ref);
|
||||
}
|
||||
|
||||
return ref.newInstance();
|
||||
}
|
||||
|
||||
public static void set(Object packet, String fieldName, Object value) {
|
||||
ClassReflection ref = packetClasses.get(packet.getClass().getSimpleName());
|
||||
ref.setFieldValue(fieldName, packet, value);
|
||||
}
|
||||
|
||||
public static void send(Player player, Object packet) {
|
||||
Object entityPlayer = Reflection.invokeMethod(GET_HANDLE, player);
|
||||
Object playerConnection = Reflection.getFieldValue(PLAYER_CONNECTION, entityPlayer);
|
||||
Reflection.invokeMethod(SEND_PACKET, playerConnection, packet);
|
||||
}
|
||||
}
|
|
@ -1,168 +0,0 @@
|
|||
package com.lenis0012.bukkit.marriage2.misc.reflection;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Reflection {
|
||||
private static final String NMS_VERSION;
|
||||
private static final String NMS_ROOT;
|
||||
private static final String CB_ROOT;
|
||||
|
||||
static {
|
||||
String fullname = Bukkit.getServer().getClass().getName();
|
||||
NMS_VERSION = fullname.substring("org.bukkit.craftbukkit.".length()).split(Pattern.quote("."))[0];
|
||||
NMS_ROOT = "net.minecraft.server." + NMS_VERSION + ".";
|
||||
CB_ROOT = "org.bukkit.craftbukkit." + NMS_VERSION + ".";
|
||||
}
|
||||
|
||||
public static Class<?> getNMSClass(String name) {
|
||||
try {
|
||||
return Class.forName(NMS_ROOT + name);
|
||||
} catch(ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Class<?> getCBClass(String name) {
|
||||
try {
|
||||
return Class.forName(CB_ROOT + name);
|
||||
} catch(ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Field getField(Class<?> host, String name) {
|
||||
try {
|
||||
Field field = host.getDeclaredField(name);
|
||||
field.setAccessible(true);
|
||||
return field;
|
||||
} catch(Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Field getNMSField(String hostName, String fieldName) {
|
||||
return getField(getNMSClass(hostName), fieldName);
|
||||
}
|
||||
|
||||
public static Field getCBField(String hostName, String fieldName) {
|
||||
return getField(getCBClass(hostName), fieldName);
|
||||
}
|
||||
|
||||
public static void setFieldValue(Field field, Object instance, Object value) {
|
||||
try {
|
||||
field.set(instance, value);
|
||||
} catch(IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Object getFieldValue(Field field, Object instance) {
|
||||
try {
|
||||
return field.get(instance);
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T getFieldValue(Field field, Object instance, Class<T> type) {
|
||||
return type.cast(getFieldValue(field, instance));
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> host, String methodName, Class<?>... params) {
|
||||
try {
|
||||
Method method = host.getDeclaredMethod(methodName, params);
|
||||
method.setAccessible(true);
|
||||
return method;
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Method getNMSMethod(String hostName, String methodName, Class<?>... params) {
|
||||
return getMethod(getNMSClass(hostName), methodName, params);
|
||||
}
|
||||
|
||||
public static Method getCBMethod(String hostName, String methodName, Class<?>... params) {
|
||||
return getMethod(getCBClass(hostName), methodName, params);
|
||||
}
|
||||
|
||||
public static Object invokeMethod(Method method, Object instance, Object... args) {
|
||||
try {
|
||||
return method.invoke(instance, args);
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T invokeMethod(Class<T> type, Method method, Object instance, Object... args) {
|
||||
return type.cast(invokeMethod(method, instance, args));
|
||||
}
|
||||
|
||||
public static final class ClassReflection {
|
||||
private final Class<?> handle;
|
||||
private final Map<String, Field> fields = Maps.newConcurrentMap();
|
||||
private final Map<String, Method> methods = Maps.newConcurrentMap();
|
||||
|
||||
public ClassReflection(Class<?> handle) {
|
||||
this.handle = handle;
|
||||
scanFields(handle);
|
||||
scanMethods(handle);
|
||||
}
|
||||
|
||||
private void scanFields(Class<?> host) {
|
||||
if(host.getSuperclass() != null) {
|
||||
scanFields(host.getSuperclass());
|
||||
}
|
||||
|
||||
for(Field field : host.getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
fields.put(field.getName(), field);
|
||||
}
|
||||
}
|
||||
|
||||
private void scanMethods(Class<?> host) {
|
||||
if(host.getSuperclass() != null) {
|
||||
scanMethods(host.getSuperclass());
|
||||
}
|
||||
|
||||
for(Method method : host.getDeclaredMethods()) {
|
||||
method.setAccessible(true);
|
||||
methods.put(method.getName(), method);
|
||||
}
|
||||
}
|
||||
|
||||
public Object newInstance() {
|
||||
try {
|
||||
return handle.newInstance();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Field getField(String name) {
|
||||
return fields.get(name);
|
||||
}
|
||||
|
||||
public void setFieldValue(String fieldName, Object instance, Object value) {
|
||||
Reflection.setFieldValue(getField(fieldName), instance, value);
|
||||
}
|
||||
|
||||
public <T> T getFieldValue(String fieldName, Object instance, Class<T> type) {
|
||||
return Reflection.getFieldValue(getField(fieldName), instance, type);
|
||||
}
|
||||
|
||||
public Method getMethod(String name) {
|
||||
return methods.get(name);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue