commit 59a75c455371a56fe4602f4e428a2bb7f9429376 Author: NorbiPeti Date: Mon Oct 24 19:08:53 2016 +0200 Added files diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..10f8ea2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,224 @@ +################# +## Eclipse +################# + +*.pydevproject +.project +.metadata/ +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath +target/ +.project + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + + +################# +## Visual Studio +################# + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results + +[Dd]ebug/ +[Rr]elease/ +x64/ +build/ +[Bb]in/ +[Oo]bj/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.log +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml +*.pubxml +*.publishproj + +# NuGet Packages Directory +## TODO: If you have NuGet Package Restore enabled, uncomment the next line +#packages/ + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml +*.pfx +*.publishsettings + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +App_Data/*.mdf +App_Data/*.ldf + +############# +## Windows detritus +############# + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Mac crap +.DS_Store + + +############# +## Python +############# + +*.py[cod] + +# Packages +*.egg +*.egg-info +dist/ +build/ +eggs/ +parts/ +var/ +sdist/ +develop-eggs/ +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg +.metadata/* +TheButtonAutoFlair/out/artifacts/Autoflair/Autoflair.jar +*.iml +*.name +.idea/compiler.xml +*.xml diff --git a/README.md b/README.md new file mode 100644 index 0000000..fda2dc0 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# ButtonLib +A library that stores everything common to the TBMC plugins diff --git a/jitpack.yml b/jitpack.yml new file mode 100644 index 0000000..219eab8 --- /dev/null +++ b/jitpack.yml @@ -0,0 +1,10 @@ +jdk: + - oraclejdk8 +#before_install: +# - ./prepareEnvironment.sh +install: + - echo "Downloading Towny JAR..." + - 'wget -O "Towny.jar" --header="Accept-Language: en-us,en;q=0.5" http://palmergames.com/file-repo/Towny%20Advanced/Development/0.91.1.5/Towny.jar' + - mvn install:install-file -Dfile=Towny.jar -DgroupId=com.github.TBMCPlugins.ButtonCore -DartifactId=Towny -Dversion=master-SNAPSHOT -Dpackaging=jar + - mvn clean install -DskipTests +# - rm -r ~/.m2/repository/com/palmergames/Towny/ \ No newline at end of file diff --git a/src/main/java/buttondevteam/lib/EventExceptionHandler.java b/src/main/java/buttondevteam/lib/EventExceptionHandler.java new file mode 100644 index 0000000..7c64e4f --- /dev/null +++ b/src/main/java/buttondevteam/lib/EventExceptionHandler.java @@ -0,0 +1,154 @@ +package buttondevteam.lib; + +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.Validate; +import org.bukkit.event.Event; +import org.bukkit.event.EventException; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.plugin.EventExecutor; +import org.bukkit.plugin.IllegalPluginAccessException; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.RegisteredListener; + +import com.google.common.collect.Lists; + +public abstract class EventExceptionHandler { // https://gist.github.com/aadnk/5430459 + // For wrapping a registered listener + private static class ExceptionRegisteredListener extends RegisteredListener { + /** + * Represents an event executor that does nothing. This is not really necessary in the current + * implementation of CraftBukkit, but we will take no chances. + */ + private static EventExecutor NULL_EXECUTOR = new EventExecutor() { + @Override + public void execute(Listener listener, Event event) throws EventException { + // Do nothing + } + }; + + private final RegisteredListener delegate; + private final EventExceptionHandler handler; + + public ExceptionRegisteredListener(RegisteredListener delegate, EventExceptionHandler handler) { + super(delegate.getListener(), NULL_EXECUTOR, delegate.getPriority(), + delegate.getPlugin(), delegate.isIgnoringCancelled()); + this.delegate = delegate; + this.handler = handler; + } + + @Override + public void callEvent(Event event) throws EventException { + try { + delegate.callEvent(event); + } catch (EventException e) { + if (!handler.handle(e.getCause(), event)) { + throw e; + } + } catch (Throwable e) { + if (!handler.handle(e, event)) { + doThrow(e); + } + } + } + + // WARNING: HORRIBLE, HORRIBLE HACK to get around checked exceptions + private static void doThrow(Throwable e) { + ExceptionRegisteredListener. doThrowInner(e); + } + + @SuppressWarnings("unchecked") + private static void doThrowInner(Throwable e) throws E { + throw (E) e; + } + } + + /** + * Register Bukkit event handlers with a given exception handler. + * @param listener - a class of event handlers. + * @param plugin - the current plugin. + * @param handler - exception handler. + */ + public static void registerEvents(Listener listener, Plugin plugin, EventExceptionHandler handler) { + Validate.notNull(plugin, "Plugin cannot be NULL."); + + registerEvents(plugin.getServer().getPluginManager(), listener, plugin, handler); + } + + /** + * Register Bukkit event handlers with a given exception handler. + * @param manager - the current plugin manager. + * @param listener - a class of event handlers. + * @param plugin - the current plugin. + * @param handler - exception handler. + */ + public static void registerEvents(PluginManager manager, Listener listener, Plugin plugin, EventExceptionHandler handler) { + Validate.notNull(manager, "Manager cannot be NULL."); + Validate.notNull(listener, "Listener cannot be NULL."); + Validate.notNull(plugin, "Plugin cannot be NULL."); + Validate.notNull(handler, "Handler cannot be NULL."); + + if (!plugin.isEnabled()) { + throw new IllegalPluginAccessException("Plugin attempted to register " + listener + " while not enabled"); + } + + // Create normal listeners + for (Map.Entry, Set> entry : + plugin.getPluginLoader().createRegisteredListeners(listener, plugin).entrySet()) { + + // Wrap these listeners in our exception handler + getHandlerList(entry.getKey()).registerAll(wrapAll(entry.getValue(), handler)); + } + } + + /** + * Wrap every listener in the given collection around an exception handler. + * @param listeners - the listeners to wrap. + * @param handler - the exception handler to add. + * @return The wrapped listeners. + */ + private static Collection wrapAll(Collection listeners, EventExceptionHandler handler) { + List output = Lists.newArrayList(); + + for (RegisteredListener listener : listeners) { + output.add(new ExceptionRegisteredListener(listener, handler)); + } + return output; + } + + /** + * Retrieve the handler list associated with the given class. + * @param clazz - given event class. + * @return Associated handler list. + */ + private static HandlerList getHandlerList(Class clazz) { + // Class must have Event as its superclass + while (clazz.getSuperclass() != null && Event.class.isAssignableFrom(clazz.getSuperclass())) { + try { + Method method = clazz.getDeclaredMethod("getHandlerList"); + method.setAccessible(true); + return (HandlerList) method.invoke(null); + } catch (NoSuchMethodException e) { + // Keep on searching + clazz = clazz.getSuperclass().asSubclass(Event.class); + } catch (Exception e) { + throw new IllegalPluginAccessException(e.getMessage()); + } + } + throw new IllegalPluginAccessException("Unable to find handler list for event " + clazz.getName()); + } + + /** + * Handle a given exception. + * @param ex - the exception to handle. + * @param event - the event that was being handled. + * @return TRUE to indicate that the exception has been handled, FALSE to rethrow it. + */ + public abstract boolean handle(Throwable ex, Event event); +} \ No newline at end of file diff --git a/src/main/java/buttondevteam/lib/TBMCCoreAPI.java b/src/main/java/buttondevteam/lib/TBMCCoreAPI.java new file mode 100644 index 0000000..6e1775d --- /dev/null +++ b/src/main/java/buttondevteam/lib/TBMCCoreAPI.java @@ -0,0 +1,94 @@ +package buttondevteam.lib; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.bukkit.Bukkit; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +public final class TBMCCoreAPI { + /** + * Updates or installs the specified plugin. The plugin must use Maven. + * + * @param name + * The plugin's repository name. + * @return Error message or empty string + */ + public static String UpdatePlugin(String name) { + List plugins = GetPluginNames(); + String correctname = null; + for (String plugin : plugins) { + if (plugin.equalsIgnoreCase(name)) { + correctname = plugin; // Fixes capitalization + break; + } + } + if (correctname == null) { + Bukkit.getLogger().warning("There was an error while updating TBMC plugin: " + name); + return "Can't find plugin: " + name; + } + Bukkit.getLogger().info("Updating TBMC plugin: " + correctname); + String ret = ""; + URL url; + try { + url = new URL("https://jitpack.io/com/github/TBMCPlugins/" + + (correctname.equals("ButtonCore") ? "ButtonCore/ButtonCore" : correctname) + "/master-SNAPSHOT/" + + correctname + "-master-SNAPSHOT.jar"); // ButtonCore exception required since it hosts Towny as well + FileUtils.copyURLToFile(url, new File("plugins/" + correctname + ".jar")); + } catch (FileNotFoundException e) { + ret = "Can't find JAR, the build probably failed. Build log (scroll to bottom):\nhttps://jitpack.io/com/github/TBMCPlugins/" + + correctname + "/master-SNAPSHOT/build.log"; + } catch (IOException e) { + ret = "IO error!\n" + e.getMessage(); + } catch (Exception e) { + Bukkit.getLogger().warning("Error!\n" + e); + ret = e.toString(); + } + return ret; + } + + /** + * Retrieves all the repository names from the GitHub organization. + * + * @return A list of names + */ + public static List GetPluginNames() { + List ret = new ArrayList<>(); + try { + String resp = DownloadString("https://api.github.com/orgs/TBMCPlugins/repos"); + JsonArray arr = new JsonParser().parse(resp).getAsJsonArray(); + for (JsonElement obj : arr) { + JsonObject jobj = obj.getAsJsonObject(); + ret.add(jobj.get("name").getAsString()); + } + } catch (Exception e) { + e.printStackTrace(); + } + return ret; + } + + public static String DownloadString(String urlstr) throws MalformedURLException, IOException { + URL url = new URL(urlstr); + URLConnection con = url.openConnection(); + con.setRequestProperty("User-Agent", "TBMCPlugins"); + InputStream in = con.getInputStream(); + String encoding = con.getContentEncoding(); + encoding = encoding == null ? "UTF-8" : encoding; + String body = IOUtils.toString(in, encoding); + in.close(); + return body; + } +} diff --git a/src/main/java/buttondevteam/lib/TBMCPlayer.java b/src/main/java/buttondevteam/lib/TBMCPlayer.java new file mode 100644 index 0000000..8a0840a --- /dev/null +++ b/src/main/java/buttondevteam/lib/TBMCPlayer.java @@ -0,0 +1,150 @@ +package buttondevteam.lib; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.configuration.file.YamlConfiguration; +import com.palmergames.bukkit.towny.Towny; +import com.palmergames.bukkit.towny.object.Resident; +import com.palmergames.bukkit.towny.object.TownyUniverse; + +/** + *

+ * The class for holding data common to all TBMC plugins + *

+ *

+ * Listen to the load and save events from this package to load and save plugin-specific data + *

+ * + * @author Norbi + * + */ +public class TBMCPlayer { + private static final String TBMC_PLAYERS_DIR = "TBMC/players"; + + public String PlayerName; + + public UUID UUID; + + public T AsPluginPlayer(Class cl) { + T obj = null; + try { + obj = cl.newInstance(); + obj.UUID = UUID; + obj.PlayerName = PlayerName; + } catch (Exception e) { + e.printStackTrace(); + } + return obj; + } + + public static HashMap OnlinePlayers = new HashMap<>(); + + /** + * @param name + * The player's name + * @return The {@link TBMCPlayer} object for the player + */ + public static TBMCPlayer GetFromName(String name) { + @SuppressWarnings("deprecation") + OfflinePlayer p = Bukkit.getOfflinePlayer(name); + if (p != null) + return GetPlayer(p); + else + return null; + } + + /** + * @param p + * The Player object + * @return The {@link TBMCPlayer} object for the player + */ + public static TBMCPlayer GetPlayer(OfflinePlayer p) { + if (TBMCPlayer.OnlinePlayers.containsKey(p.getUniqueId())) + return TBMCPlayer.OnlinePlayers.get(p.getUniqueId()); + else + return TBMCPlayer.LoadPlayer(p); + } + + protected static TBMCPlayer LoadPlayer(OfflinePlayer p) { + if (OnlinePlayers.containsKey(p.getUniqueId())) + return OnlinePlayers.get(p.getUniqueId()); + File file = new File(TBMC_PLAYERS_DIR); + file.mkdirs(); + file = new File(TBMC_PLAYERS_DIR, p.getUniqueId().toString() + ".yml"); + if (!file.exists()) + return AddPlayer(p); + else { + final YamlConfiguration yc = new YamlConfiguration(); + try { + yc.load(file); + } catch (Exception e) { + new Exception("Failed to load player data for " + p.getUniqueId(), e).printStackTrace(); + return null; + } + TBMCPlayer player = new TBMCPlayer(); + player.UUID = p.getUniqueId(); + player.PlayerName = yc.getString("playername"); + System.out.println("Player name: " + player.PlayerName); + if (player.PlayerName == null) { + player.PlayerName = p.getName(); + System.out.println("Player name saved: " + player.PlayerName); + } else if (!p.getName().equals(player.PlayerName)) { + System.out.println("Renaming " + player.PlayerName + " to " + p.getName()); + TownyUniverse tu = Towny.getPlugin(Towny.class).getTownyUniverse(); + Resident resident = tu.getResidentMap().get(player.PlayerName); + if (resident == null) + System.out.println("Resident not found - couldn't rename in Towny."); + else if (tu.getResidentMap().contains(p.getName())) + System.out.println("Target resident name is already in use."); // TODO: Handle + else + resident.setName(p.getName()); + player.PlayerName = p.getName(); + System.out.println("Renaming done."); + } + + // Load in other plugins + Bukkit.getServer().getPluginManager().callEvent(new TBMCPlayerLoadEvent(yc, player)); + return player; + } + } + + static TBMCPlayer AddPlayer(OfflinePlayer p) { + TBMCPlayer player = new TBMCPlayer(); + player.UUID = p.getUniqueId(); + player.PlayerName = p.getName(); + OnlinePlayers.put(p.getUniqueId(), player); + Bukkit.getServer().getPluginManager().callEvent(new TBMCPlayerAddEvent(player)); + SavePlayer(player); + return player; + } + + static void SavePlayer(TBMCPlayer player) { + YamlConfiguration yc = new YamlConfiguration(); + yc.set("playername", player.PlayerName); + Bukkit.getServer().getPluginManager().callEvent(new TBMCPlayerSaveEvent(yc, player)); + try { + yc.save(TBMC_PLAYERS_DIR + "/" + player.UUID + ".yml"); + } catch (IOException e) { + new Exception("Failed to save player data for " + player.PlayerName, e).printStackTrace(); + } + } + + static void JoinPlayer(TBMCPlayer player) { + OnlinePlayers.put(player.UUID, player); + Bukkit.getServer().getPluginManager().callEvent(new TBMCPlayerJoinEvent(player)); + } + + static void QuitPlayer(TBMCPlayer player) { + OnlinePlayers.remove(player.UUID); + Bukkit.getServer().getPluginManager().callEvent(new TBMCPlayerQuitEvent(player)); + } + + T GetAs(Class cl) { // TODO: Serialize player classes + return null; + } +} diff --git a/src/main/java/buttondevteam/lib/TBMCPlayerAddEvent.java b/src/main/java/buttondevteam/lib/TBMCPlayerAddEvent.java new file mode 100644 index 0000000..ae576ec --- /dev/null +++ b/src/main/java/buttondevteam/lib/TBMCPlayerAddEvent.java @@ -0,0 +1,36 @@ +package buttondevteam.lib; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + *

+ * This event gets called when a new player joins. After this event, the + * {@link TBMCPlayerSaveEvent} will be called. + *

+ * + * @author Norbi + * + */ +public class TBMCPlayerAddEvent extends Event { + private static final HandlerList handlers = new HandlerList(); + + private TBMCPlayer player; + + public TBMCPlayerAddEvent(TBMCPlayer player) { + this.player = player; + } + + public TBMCPlayer GetPlayer() { + return player; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/main/java/buttondevteam/lib/TBMCPlayerJoinEvent.java b/src/main/java/buttondevteam/lib/TBMCPlayerJoinEvent.java new file mode 100644 index 0000000..fbcc3d0 --- /dev/null +++ b/src/main/java/buttondevteam/lib/TBMCPlayerJoinEvent.java @@ -0,0 +1,27 @@ +package buttondevteam.lib; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class TBMCPlayerJoinEvent extends Event { + private static final HandlerList handlers = new HandlerList(); + + private TBMCPlayer player; + + public TBMCPlayerJoinEvent(TBMCPlayer player) { + this.player = player; + } + + public TBMCPlayer GetPlayer() { + return player; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/main/java/buttondevteam/lib/TBMCPlayerLoadEvent.java b/src/main/java/buttondevteam/lib/TBMCPlayerLoadEvent.java new file mode 100644 index 0000000..2d017ce --- /dev/null +++ b/src/main/java/buttondevteam/lib/TBMCPlayerLoadEvent.java @@ -0,0 +1,34 @@ +package buttondevteam.lib; + +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class TBMCPlayerLoadEvent extends Event { + private static final HandlerList handlers = new HandlerList(); + + private YamlConfiguration yaml; + private TBMCPlayer player; + + public TBMCPlayerLoadEvent(YamlConfiguration yaml, TBMCPlayer player) { + this.yaml = yaml; + this.player = player; + } + + public YamlConfiguration GetPlayerConfig() { + return yaml; + } + + public TBMCPlayer GetPlayer() { + return player; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/main/java/buttondevteam/lib/TBMCPlayerQuitEvent.java b/src/main/java/buttondevteam/lib/TBMCPlayerQuitEvent.java new file mode 100644 index 0000000..3835605 --- /dev/null +++ b/src/main/java/buttondevteam/lib/TBMCPlayerQuitEvent.java @@ -0,0 +1,27 @@ +package buttondevteam.lib; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class TBMCPlayerQuitEvent extends Event { + private static final HandlerList handlers = new HandlerList(); + + private TBMCPlayer player; + + public TBMCPlayerQuitEvent(TBMCPlayer player) { + this.player = player; + } + + public TBMCPlayer GetPlayer() { + return player; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/main/java/buttondevteam/lib/TBMCPlayerSaveEvent.java b/src/main/java/buttondevteam/lib/TBMCPlayerSaveEvent.java new file mode 100644 index 0000000..114aea0 --- /dev/null +++ b/src/main/java/buttondevteam/lib/TBMCPlayerSaveEvent.java @@ -0,0 +1,34 @@ +package buttondevteam.lib; + +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class TBMCPlayerSaveEvent extends Event { + private static final HandlerList handlers = new HandlerList(); + + private YamlConfiguration yaml; + private TBMCPlayer player; + + public TBMCPlayerSaveEvent(YamlConfiguration yaml, TBMCPlayer player) { + this.yaml = yaml; + this.player = player; + } + + public YamlConfiguration GetPlayerConfig() { + return yaml; + } + + public TBMCPlayer GetPlayer() { + return player; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..f64dc39 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,4 @@ +name: ButtonPluginBucket +main: buttondevteam.bucket.MainPlugin +version: 1.0 +author: TBMCPlugins \ No newline at end of file