Add 'ButtonLib/' from commit '77aca9d5c17322eac7af4fe57b3b8d4bd74874bb'

git-subtree-dir: ButtonLib
git-subtree-mainline: da8e278c15
git-subtree-split: 77aca9d5c1
This commit is contained in:
Norbi Peti 2016-11-01 22:55:18 +01:00
commit c439a34294
17 changed files with 1492 additions and 0 deletions

223
ButtonLib/.gitignore vendored Normal file
View file

@ -0,0 +1,223 @@
#################
## 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

2
ButtonLib/README.md Normal file
View file

@ -0,0 +1,2 @@
# ButtonLib
A library that stores everything common to the TBMC plugins

10
ButtonLib/jitpack.yml Normal file
View file

@ -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.ButtonLib -DartifactId=Towny -Dversion=master-SNAPSHOT -Dpackaging=jar
- mvn clean install -DskipTests
# - rm -r ~/.m2/repository/com/palmergames/Towny/

122
ButtonLib/pom.xml Normal file
View file

@ -0,0 +1,122 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.TBMCPlugins.ButtonLib</groupId>
<artifactId>ButtonLib</artifactId>
<version>master-SNAPSHOT</version>
<name>ButtonLib</name>
<description>ButtonCore</description>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>*.properties</include>
<include>*.yml</include>
<include>*.csv</include>
<include>*.txt</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
<finalName>ButtonCore</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- <<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId>
<version>2.4.2</version> <executions> <execution> <phase>package</phase>
<goals> <goal>shade</goal> </goals> <configuration> <artifactSet> <includes>
</includes> </artifactSet> <pluginExecution> <action> <execute /> </action>
</pluginExecution> </configuration> </execution> </executions> </plugin> -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>copy</id>
<phase>compile</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>target</outputDirectory>
<resources>
<resource>
<directory>resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.9.2-R0.1-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.github.TBMCPlugins.ButtonLib</groupId>
<artifactId>Towny</artifactId>
<version>master-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.reflections/reflections -->
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.10</version>
</dependency>
</dependencies>
<organization>
<name>TBMCPlugins</name>
<url>https://github.com/TBMCPlugins</url>
</organization>
<distributionManagement>
<repository>
<id>internal.repo</id>
<name>Temporary Staging Repository</name>
<url>file://${project.build.directory}/mvn-repo/${project.name}</url>
</repository>
</distributionManagement>
<properties>
<!-- github server corresponds to entry in ~/.m2/settings.xml -->
<github.global.server>github</github.global.server>
</properties>
<scm>
<url>https://github.com/TBMCPlugins/mvn-repo</url>
<connection>scm:git:https://github.com/TBMCPlugins/mvn-repo.git</connection>
<developerConnection>scm:git:https://github.com/TBMCPlugins/mvn-repo.git</developerConnection>
</scm>
</project>

View file

@ -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.<RuntimeException> doThrowInner(e);
}
@SuppressWarnings("unchecked")
private static <E extends Throwable> 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<Class<? extends Event>, Set<RegisteredListener>> 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<RegisteredListener> wrapAll(Collection<RegisteredListener> listeners, EventExceptionHandler handler) {
List<RegisteredListener> 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<? extends Event> 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);
}

View file

@ -0,0 +1,99 @@
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<String> 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 + "/master-SNAPSHOT/" + correctname
+ "-master-SNAPSHOT.jar"); // ButtonLib exception not required, not a separate plugin
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<String> GetPluginNames() {
List<String> 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;
}
public static void SendException(String sourcemsg, Exception e) {
Bukkit.getPluginManager().callEvent(new TBMCExceptionEvent(sourcemsg, e));
Bukkit.getLogger().warning(sourcemsg);
e.printStackTrace();
}
}

View file

@ -0,0 +1,57 @@
package buttondevteam.lib;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import buttondevteam.lib.TBMCPlayer.InfoTarget;
/**
* <p>
* This event gets called (ideally) each time an exception occurs in a TBMC plugin. To call it, use {@link TBMCCoreAPI#SendException(String, Exception)}.
* </p>
*
* @author Norbi
*
*/
public class TBMCExceptionEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private String sourcemsg;
private Exception exception;
TBMCExceptionEvent(String sourcemsg, Exception exception) {
this.sourcemsg = sourcemsg;
this.exception = exception;
}
/**
* Gets the source message (where did this exception occur, etc.)
*
* @return The message
*/
public String getSourceMessage() {
return sourcemsg;
}
/**
* Gets the exception
*
* @return The exception
*/
public Exception getException() {
return exception;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View file

@ -0,0 +1,465 @@
package buttondevteam.lib;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map.Entry;
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;
/**
* <p>
* The class for holding data common to all TBMC plugins
* </p>
* <p>
* Use {@link #asPluginPlayer(Class)} to get plugin-specific data
* </p>
*
* @author Norbi
*
*/
public class TBMCPlayer implements AutoCloseable {
private static final String TBMC_PLAYERS_DIR = "TBMC/players";
private HashMap<String, Object> data = new HashMap<>();
/**
* <p>
* Gets a player data entry for the caller plugin returning the desired type.<br>
* <i>It will automatically determine the key and the return type.</i><br>
* Usage:
* </p>
*
* <pre>
* {@code
* public String getPlayerName() {
* return getData();
* }
* </pre>
*
* @return The value or null if not found
*/
@SuppressWarnings("unchecked")
protected <T> T getData() {
StackTraceElement st = new Exception().getStackTrace()[1];
String mname = st.getMethodName();
if (!mname.startsWith("get"))
throw new UnsupportedOperationException("Can only use getData from a getXYZ method");
Object ret = getLoadedPlayers().get(uuid).data.get(mname.substring("get".length()).toLowerCase());
if (Integer.class.isAssignableFrom(ret.getClass()))
throw new UnsupportedOperationException("For integers use getIntData()");
return (T) ret;
}
/**
* Sets a player data entry <i>based on the caller method</i><br>
* Usage:
* </p>
*
* <pre>
* {@code
* public String setPlayerName(String value) {
* return setData(value);
* }
* </pre>
*
* @param value
* The value to set
*/
protected void setData(Object value) {
StackTraceElement st = new Exception().getStackTrace()[1];
String mname = st.getMethodName();
if (!mname.startsWith("set"))
throw new UnsupportedOperationException("Can only use setData from a setXYZ method");
getLoadedPlayers().get(uuid).data.put(mname.substring("set".length()).toLowerCase(), value);
}
/**
* <p>
* Gets a player data entry for the caller plugin returning the desired type, <b>which is an enum</b><br>
* <i>It will automatically determine the key and the return type.</i><br>
* Usage:
* </p>
*
* <pre>
* {@code
* public String getSomeEnum() {
* return getEnumData();
* }
* </pre>
*
* @return The value or null if not found
*/
protected <T extends Enum<T>> T getEnumData(Class<T> cl) {
StackTraceElement st = new Exception().getStackTrace()[1];
String mname = st.getMethodName();
if (!mname.startsWith("get"))
throw new UnsupportedOperationException("Can only use getEnumData from a getXYZ method");
final String retstr = (String) getLoadedPlayers().get(uuid).data
.get(mname.substring("get".length()).toLowerCase());
if (retstr != null)
return Enum.valueOf(cl, retstr);
else
return null;
}
/**
* Sets a player data entry <i>based on the caller method</i><br>
* Usage:
* </p>
*
* <pre>
* {@code
* public String setSomeEnum(SomeEnum value) {
* return setEnumData(value);
* }
* </pre>
*
* @param value
* The value to set
*/
protected void setEnumData(Enum<?> value) {
StackTraceElement st = new Exception().getStackTrace()[1];
String mname = st.getMethodName();
if (!mname.startsWith("set"))
throw new UnsupportedOperationException("Can only use setEnumData from a setXYZ method");
getLoadedPlayers().get(uuid).data.put(mname.substring("set".length()).toLowerCase(), value.toString());
}
/**
* <p>
* Gets a player data entry for the caller plugin returning the desired type, <b>which is a number</b><br>
* <i>It will automatically determine the key and the return type.</i><br>
* Usage:
* </p>
*
* <pre>
* {@code
* public short getNumber() {
* return getIntData();
* }
* </pre>
*
* @return The value or null if not found
*/
@SuppressWarnings("unchecked")
protected <T extends Number> T getIntData(Class<T> cl) {
StackTraceElement st = new Exception().getStackTrace()[1];
String mname = st.getMethodName();
if (!mname.startsWith("get"))
throw new UnsupportedOperationException("Can only use getIntData from a getXYZ method");
Object obj = getLoadedPlayers().get(uuid).data.get(mname.substring("get".length()).toLowerCase());
if (!(obj instanceof Integer))
throw new UnsupportedOperationException("The retrieved object isn't a number: " + obj);
Integer int_ = (Integer) obj;
if (Short.class.isAssignableFrom(cl))
return (T) (Object) int_.shortValue();
else
return (T) (Object) int_;
}
/**
* Sets a player data entry <i>based on the caller method</i><br>
* Usage:
* </p>
*
* <pre>
* {@code
* public String setNumber(short value) {
* return setIntData(value);
* }
* </pre>
*
* @param value
* The value to set
*/
protected void setIntData(Number value) {
StackTraceElement st = new Exception().getStackTrace()[1];
String mname = st.getMethodName();
if (!mname.startsWith("set"))
throw new UnsupportedOperationException("Can only use setIntData from a setXYZ method");
getLoadedPlayers().get(uuid).data.put(mname.substring("set".length()).toLowerCase(), value);
}
/**
* Gets the player's Minecraft name
*
* @return The player's Minecraft name
*/
public String getPlayerName() {
return getData();
}
/**
* Sets the player's Minecraft name
*
* @param playerName
* the new name
*/
public void setPlayerName(String playerName) {
setData(playerName);
}
private UUID uuid; // Do not save it in the file
/**
* Get the player's UUID
*
* @return The Minecraft UUID of the player
*/
public UUID getUuid() {
return uuid;
}
/**
* Gets the TBMCPlayer object as a specific plugin player, keeping it's data *
*
* @param p
* Player to get
* @param cl
* The TBMCPlayer subclass
*/
public <T extends TBMCPlayer> T asPluginPlayer(Class<T> cl) {
T obj = null;
try {
obj = cl.newInstance();
((TBMCPlayer) obj).uuid = uuid;
((TBMCPlayer) obj).data.putAll(data);
} catch (Exception e) {
e.printStackTrace();
}
return obj;
}
private static HashMap<UUID, TBMCPlayer> LoadedPlayers = new HashMap<>();
/**
* This method returns a TBMC player from their name. Calling this method may return an offline player which will load it, therefore it's highly recommended to use {@link #close()} to unload the
* player data. Using try-with-resources may be the easiest way to achieve this. Example:
*
* <pre>
* {@code
* try(TBMCPlayer player = getFromName(p))
* {
* ...
* }
* </pre>
*
* @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;
}
/**
* This method returns a TBMC player from a Bukkit player. Calling this method may return an offline player, therefore it's highly recommended to use {@link #close()} to unload the player data.
* Using try-with-resources may be the easiest way to achieve this. Example:
*
* <pre>
* {@code
* try(TBMCPlayer player = getPlayer(p))
* {
* ...
* }
* </pre>
*
* @param p
* The Player object
* @return The {@link TBMCPlayer} object for the player
*/
public static TBMCPlayer getPlayer(OfflinePlayer p) {
if (TBMCPlayer.getLoadedPlayers().containsKey(p.getUniqueId()))
return TBMCPlayer.getLoadedPlayers().get(p.getUniqueId());
else
return TBMCPlayer.loadPlayer(p);
}
/**
* This method returns a TBMC player from a player UUID. Calling this method may return an offline player, therefore it's highly recommended to use {@link #close()} to unload the player data.
* Using try-with-resources may be the easiest way to achieve this. Example:
*
* <pre>
* {@code
* try(TBMCPlayer player = getPlayer(p))
* {
* ...
* }
* </pre>
*
* @param p
* The Player object
* @return The {@link TBMCPlayer} object for the player
*/
public static TBMCPlayer getPlayer(UUID uuid) {
if (TBMCPlayer.getLoadedPlayers().containsKey(uuid))
return TBMCPlayer.getLoadedPlayers().get(uuid);
else
return TBMCPlayer.loadPlayer(Bukkit.getOfflinePlayer(uuid));
}
/**
* This is a convenience method for {@link #getPlayer(OfflinePlayer)}.{@link #asPluginPlayer(Class)}.
*
* See those methods for more information.
*
* @param p
* Player to get
* @param cl
* The TBMCPlayer subclass
* @return The player as a subtype of TBMCPlayer
*/
public static <T extends TBMCPlayer> T getPlayerAs(OfflinePlayer p, Class<T> cl) {
return getPlayer(p).asPluginPlayer(cl);
}
/**
* This is a convenience method for {@link #getPlayer(UUID)}.{@link #asPluginPlayer(Class)}
*
* See those methods for more information.
*
* @param uuid
* The UUID of the player to get
* @param cl
* The TBMCPlayer subclass
* @return The player as a subtype of TBMCPlayer
*/
public static <T extends TBMCPlayer> T getPlayerAs(UUID uuid, Class<T> cl) {
return getPlayer(uuid).asPluginPlayer(cl);
}
/**
* Only intended to use from ButtonCore
*/
public static TBMCPlayer loadPlayer(OfflinePlayer p) {
if (getLoadedPlayers().containsKey(p.getUniqueId()))
return getLoadedPlayers().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.data.putAll(yc.getValues(true));
getLoadedPlayers().put(p.getUniqueId(), player); // Accessing any value requires it to be in the map
Bukkit.getLogger().info("Loaded player: " + player.getPlayerName());
if (player.getPlayerName() == null) {
player.setPlayerName(p.getName());
Bukkit.getLogger().info("Player name saved: " + player.getPlayerName());
} else if (!p.getName().equals(player.getPlayerName())) {
Bukkit.getLogger().info("Renaming " + player.getPlayerName() + " to " + p.getName());
TownyUniverse tu = Towny.getPlugin(Towny.class).getTownyUniverse();
Resident resident = tu.getResidentMap().get(player.getPlayerName());
if (resident == null)
Bukkit.getLogger().warning("Resident not found - couldn't rename in Towny.");
else if (tu.getResidentMap().contains(p.getName()))
Bukkit.getLogger().warning("Target resident name is already in use."); // TODO: Handle
else
resident.setName(p.getName());
player.setPlayerName(p.getName());
Bukkit.getLogger().info("Renaming done.");
}
// Load in other plugins
Bukkit.getServer().getPluginManager().callEvent(new TBMCPlayerLoadEvent(yc, player));
return player;
}
}
/**
* Only intended to use from ButtonCore
*/
public static TBMCPlayer addPlayer(OfflinePlayer p) {
TBMCPlayer player = new TBMCPlayer();
player.uuid = p.getUniqueId();
getLoadedPlayers().put(p.getUniqueId(), player); // Accessing any value requires it to be in the map
player.setPlayerName(p.getName());
Bukkit.getServer().getPluginManager().callEvent(new TBMCPlayerAddEvent(player));
savePlayer(player);
return player;
}
/**
* Only intended to use from ButtonCore
*/
public static void savePlayer(TBMCPlayer player) {
YamlConfiguration yc = new YamlConfiguration();
for (Entry<String, Object> item : player.data.entrySet())
yc.set(item.getKey(), item.getValue());
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.getPlayerName(), e).printStackTrace();
}
}
/**
* Only intended to use from ButtonCore
*/
public static void joinPlayer(TBMCPlayer player) {
getLoadedPlayers().put(player.uuid, player);
Bukkit.getServer().getPluginManager().callEvent(new TBMCPlayerJoinEvent(player));
}
/**
* Only intended to use from ButtonCore
*/
public static void quitPlayer(TBMCPlayer player) {
getLoadedPlayers().remove(player.uuid);
Bukkit.getServer().getPluginManager().callEvent(new TBMCPlayerQuitEvent(player));
}
/**
* By default the player data will only get cleaned from memory when the player quits. Therefore this method must be called when accessing an offline player to clean the player data up. Calling
* this method will have no effect on online players.<br>
* Therefore, the recommended use is to call it when using {@link #GetPlayer} or use try-with-resources.
*/
@Override
public void close() {
if (!Bukkit.getPlayer(uuid).isOnline())
getLoadedPlayers().remove(uuid);
}
public static HashMap<UUID, TBMCPlayer> getLoadedPlayers() {
return LoadedPlayers;
}
/**
* Get player information. This method calls the {@link TBMCPlayerGetInfoEvent} to get all the player information across the TBMC plugins.
*
* @param target
* The {@link InfoTarget} to return the info for.
* @return The player information.
*/
public String getInfo(InfoTarget target) {
TBMCPlayerGetInfoEvent event = new TBMCPlayerGetInfoEvent(this, target);
Bukkit.getServer().getPluginManager().callEvent(event);
return event.getResult();
}
public enum InfoTarget {
MCHover, MCCommand, Discord
}
}

View file

@ -0,0 +1,36 @@
package buttondevteam.lib;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* <p>
* This event gets called when a new player joins. After this event, the
* {@link TBMCPlayerSaveEvent} will be called.
* </p>
*
* @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;
}
}

View file

@ -0,0 +1,73 @@
package buttondevteam.lib;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import buttondevteam.lib.TBMCPlayer.InfoTarget;
/**
* <p>
* This event gets called when player information is requested. It can be used to give more per-plugin information about a player.
* </p>
*
* @author Norbi
*
*/
public class TBMCPlayerGetInfoEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private TBMCPlayer player;
private List<String> infolines;
private TBMCPlayer.InfoTarget target;
TBMCPlayerGetInfoEvent(TBMCPlayer player, TBMCPlayer.InfoTarget target) {
this.player = player;
infolines = new ArrayList<>();
this.target = target;
}
/**
* Get the {@link TBMCPlayer} object
*
* @return A player object
*/
public TBMCPlayer getPlayer() {
return player;
}
/**
* Add a line to the information text. The line should be in the format of <i>key: value</i> .
*
* @param infoline
* The line to add
*/
public void addInfo(String infoline) {
infolines.add(infoline);
}
/**
* Get the {@link InfoTarget} we want the information for. Use this to format the returned string.
*
* @return The target of the information.
*/
public TBMCPlayer.InfoTarget getTarget() {
return target;
}
String getResult() {
return infolines.stream().collect(Collectors.joining("\n"));
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -0,0 +1,99 @@
package buttondevteam.lib.chat;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
import org.bukkit.plugin.java.JavaPlugin;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import buttondevteam.lib.TBMCPlayer;
public class TBMCChatAPI {
private static HashMap<String, TBMCCommandBase> commands = new HashMap<String, TBMCCommandBase>();
public static HashMap<String, TBMCCommandBase> GetCommands() {
return commands;
}
public static String[] GetSubCommands(TBMCCommandBase command) {
ArrayList<String> cmds = new ArrayList<String>();
cmds.add("§6---- Subcommands ----");
for (TBMCCommandBase cmd : TBMCChatAPI.GetCommands().values()) {
if (cmd.GetCommandPath().startsWith(command.GetCommandPath() + "/")) {
int ind = cmd.GetCommandPath().indexOf('/', command.GetCommandPath().length() + 2);
if (ind >= 0)
continue;
cmds.add(cmd.GetCommandPath().replace('/', ' '));
}
}
return cmds.toArray(new String[cmds.size()]);
}
/**
* <p>
* This method adds a plugin's commands to help and sets their executor.
* </p>
* <p>
* The <u>command must be registered</u> in the caller plugin's plugin.yml. Otherwise the plugin will output a messsage to console.
* </p>
* <p>
* <i>Using this method after the server is done loading will have no effect.</i>
* </p>
*
* @param plugin
* The caller plugin
* @param acmdclass
* A command's class to get the package name for commands. The provided class's package and subpackages are scanned for commands.
*/
public static void AddCommands(JavaPlugin plugin, Class<? extends TBMCCommandBase> acmdclass) {
plugin.getLogger().info("Registering commands for " + plugin.getName());
Reflections rf = new Reflections(
new ConfigurationBuilder().setUrls(ClasspathHelper.forClassLoader(plugin.getClass().getClassLoader()))
.addClassLoader(plugin.getClass().getClassLoader()).addScanners(new SubTypesScanner())
.filterInputsBy((String pkg) -> pkg.contains(acmdclass.getPackage().getName())));
Set<Class<? extends TBMCCommandBase>> cmds = rf.getSubTypesOf(TBMCCommandBase.class);
for (Class<? extends TBMCCommandBase> cmd : cmds) {
try {
if (Modifier.isAbstract(cmd.getModifiers()))
continue;
TBMCCommandBase c = cmd.newInstance();
c.plugin = plugin;
commands.put(c.GetCommandPath(), c);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
/**
* <p>
* Add player information for {@link PlayerInfoCommand}. Only mods can see the given information.
* </p>
*
* @param player
* @param infoline
*/
public void AddPlayerInfoForMods(TBMCPlayer player, String infoline) {
// TODO
}
/**
* <p>
* Add player information for hover text at {@link ChatProcessing}. Every online player can see the given information.
* </p>
*
* @param player
* @param infoline
*/
public void AddPlayerInfoForHover(TBMCPlayer player, String infoline) {
// TODO
}
}

View file

@ -0,0 +1,26 @@
package buttondevteam.lib.chat;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
public abstract class TBMCCommandBase {
public TBMCCommandBase() {
}
public abstract String[] GetHelpText(String alias);
public abstract boolean OnCommand(CommandSender sender, String alias, String[] args);
public abstract String GetCommandPath();
public abstract boolean GetPlayerOnly();
public abstract boolean GetModOnly();
Plugin plugin; // Used By TBMCChatAPI
public Plugin getPlugin() { // Used by CommandCaller (ButtonChat)
return plugin;
}
}

View file

@ -0,0 +1,4 @@
name: ButtonPluginBucket
main: buttondevteam.bucket.MainPlugin
version: 1.0
author: TBMCPlugins