Archived
0

Initial commit

This commit is contained in:
Pepich
2017-11-15 18:38:45 +01:00
parent 9e9b4df5b7
commit 51380d886e
54 changed files with 1900 additions and 0 deletions

11
.classpath Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="/Users/Pepich/Desktop/redstoner/spigot.jar"/>
<classpathentry kind="lib" path="/Users/Pepich/Desktop/redstoner/plugins/vault.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/ChatAPI"/>
<classpathentry combineaccessrules="false" kind="src" path="/ChestAPI"/>
<classpathentry combineaccessrules="false" kind="src" path="/CommandManager"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType">
<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/>
<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="true"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"/>
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.launching.macosx.MacOSXType/Java SE 8 [1.8.0_65]"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.ant.internal.launching.remote.InternalAntRunner"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="Faucet"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/Faucet/build.xml}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,"/>
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
<stringAttribute key="process_factory_id" value="org.eclipse.ant.ui.remoteAntProcessFactory"/>
</launchConfiguration>

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/bin/

27
.project Normal file
View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Faucet</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
<dictionary>
<key>LaunchConfigHandle</key>
<value>&lt;project&gt;/.externalToolBuilders/Faucet build.xml [Builder].launch</value>
</dictionary>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

3
manifest.mf Normal file
View File

@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Class-Path: ../lib/CommandManager.jar ../lib/ChatAPI.jar ../lib/ChestAPI.jar

5
plugin.yml Normal file
View File

@@ -0,0 +1,5 @@
name: Faucet
version: 1.0.0
authors: [pepich1851]
main: com.redstoner.Main
softdepend: [Vault]

View File

@@ -0,0 +1,14 @@
package com.redstoner.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/** The auto register annotation, to be put onto Classes that implement listener when you are too lazy to register the events yourself.
*
* @author Pepich */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoRegisterListener
{}

View File

@@ -0,0 +1,15 @@
package com.redstoner.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.redstoner.misc.CommandHolder;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Commands
{
CommandHolder value();
}

View File

@@ -0,0 +1,13 @@
package com.redstoner.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Depends
{
String[] value();
}

View File

@@ -0,0 +1,13 @@
package com.redstoner.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SoftDepends
{
String[] value();
}

View File

@@ -0,0 +1,33 @@
package com.redstoner.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/** The Version annotation, to be applied to all Classes that are part of the project.
*
* @author Pepich */
@Target(ElementType.TYPE)
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Version
{
/** The major indicator of the version. Will be used for compatibility detection.
*
* @return the major version as an int */
int major();
int minor();
int revision();
/** The compatibility part of the version number. Will be used for compatibility detection.</br>
* Set to -1 if it is supposed to be always compatible.</br>
* Defaults to 1.
*
* @return the smallest compatible version as an int. */
int compatible() default 1;
}

View File

@@ -0,0 +1,9 @@
package com.redstoner.exceptions;
public class NonSaveableConfigException extends Exception {
private static final long serialVersionUID = -7271481973389455510L;
public NonSaveableConfigException() {
super("This config does not support saving!");
}
}

View File

@@ -0,0 +1,70 @@
package com.redstoner.faucet;
import java.util.HashMap;
import org.bukkit.plugin.java.JavaPlugin;
import com.nemez.cmdmgr.Command;
import com.redstoner.annotations.Version;
import com.redstoner.misc.mysql.MysqlHandler;
import com.redstoner.modules.Module;
import net.nemez.chatapi.ChatAPI;
/** Main class. Duh.
*
* @author Pepich */
@Version(major = 4, minor = 0, revision = 0, compatible = -1)
public class Faucet extends JavaPlugin
{
public static JavaPlugin plugin;
public static HashMap<String, Module> modules = new HashMap<>();
public static HashMap<Module, Boolean> states = new HashMap<>();
private final ClassLoader parentLoader;
public Faucet()
{
parentLoader = Faucet.class.getClassLoader();
}
@Override
public void onEnable()
{
plugin = this;
ChatAPI.initialize(this);
// Configger.init();
MysqlHandler.init();
}
@Override
public void onDisable()
{}
@Command(hook = "load")
public static boolean loadModule()
{
return false;
}
@Command(hook = "tap")
public static boolean loadBarrel()
{
return false;
}
public static boolean isEnabled(Module module)
{
return states.get(module);
}
public static void disable(String name)
{
Faucet.disable(modules.get(name));
}
public static void disable(Module module)
{
}
}

View File

@@ -0,0 +1,11 @@
package com.redstoner.misc;
import org.bukkit.command.CommandSender;
/** Classes implementing this interface can be used to define a filter for the Utils.broadcast method for sending a message to more than one, but less than all users.
*
* @author Pepich */
public interface BroadcastFilter
{
public boolean sendTo(CommandSender recipient);
}

View File

@@ -0,0 +1,10 @@
package com.redstoner.misc;
/** @author Pepich */
public enum CommandHolder
{
Stream,
File,
String,
None
}

View File

@@ -0,0 +1,144 @@
package com.redstoner.misc;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
/** This class provides simple JSON handling, like storing and loading from and to files.
*
* @author Pepich */
public class JsonManager
{
private JsonManager()
{}
/** Loads a JSONObject from a file.
*
* @param source the file to load from.
* @return the JSONObject or null if the source does not contain a valid JSONObject. */
public static JSONObject getObject(File source)
{
if (!source.exists())
return null;
JSONParser parser = new JSONParser();
try
{
FileReader reader = new FileReader(source);
Object rawObject = parser.parse(reader);
reader.close();
JSONObject jsonObject = (JSONObject) rawObject;
return jsonObject;
}
catch (IOException | ParseException e)
{}
return null;
}
/** Saves a JSONObject to a file. Will create the necessary FileStructure like folders and the file itself.</br>
* Note that this operation will be run on a different thread and you do not need to take care of that yourself.
*
* @param object the JSONObject to save.
* @param destination the file to write to. */
public static void save(JSONObject object, File destination)
{
Thread t = new Thread(new Runnable()
{
@Override
public void run()
{
saveSync(object, destination);
}
});
t.start();
}
/** Saves a JSONObject to a file. Will create the necessary FileStructure like folders and the file itself.</br>
* Note that this operation will be run on the same thread that you are calling it from!
*
* @param object the JSONObject to save.
* @param destination the file to write to. */
public static void saveSync(JSONObject object, File destination)
{
if (destination.exists())
destination.delete();
else if (!destination.getParentFile().exists())
destination.getParentFile().mkdirs();
try
{
destination.createNewFile();
FileWriter writer = new FileWriter(destination);
object.writeJSONString(writer);
writer.flush();
writer.close();
}
catch (IOException e)
{}
}
/** Loads a JSONArray from a file.
*
* @param source the file to load from.
* @return the JSONArray or null if the source does not contain a valid JSONArray. */
public static JSONArray getArray(File source)
{
if (!source.exists())
return null;
JSONParser parser = new JSONParser();
try
{
Object rawObject = parser.parse(new FileReader(source));
JSONArray jsonArray = (JSONArray) rawObject;
return jsonArray;
}
catch (IOException | ParseException e)
{}
return null;
}
/** Saves a JSONArray to a file. Will create the necessary FileStructure like folders and the file itself.</br>
* Note that this operation will be run on a different thread and you do not need to take care of that yourself.
*
* @param object the JSONArray to save.
* @param destination the file to write to. */
public static void save(JSONArray array, File destination)
{
Thread t = new Thread(new Runnable()
{
@Override
public void run()
{
saveSync(array, destination);
}
});
t.start();
}
/** Saves a JSONArray to a file. Will create the necessary FileStructure like folders and the file itself.</br>
* Note that this operation will be run on the same thread that you are calling it from!
*
* @param object the JSONArray to save.
* @param destination the file to write to. */
public static void saveSync(JSONArray array, File destination)
{
if (destination.exists())
destination.delete();
else if (!destination.getParentFile().exists())
destination.getParentFile().mkdirs();
try
{
destination.createNewFile();
FileWriter writer = new FileWriter(destination);
array.writeJSONString(writer);
writer.flush();
writer.close();
}
catch (IOException e)
{}
}
}

View File

@@ -0,0 +1,129 @@
package com.redstoner.misc;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
/** The utils class containing utility functions. Those include but are not limited to sending formatted messages, broadcasts and more.
*
* @author Pepich */
public final class Utils
{
/** The @SimpleDateFormat used for getting the current date. */
public static SimpleDateFormat dateFormat = new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss]");
/** Hidden constructor. Do not instantiate UTILS classes! :) */
private Utils()
{}
/** This method broadcasts a message to all players and console that are allowed by the filter. Set the filter to NULL to broadcast to everyone.</br>
* If you want to, you can set a message that will be logged to console. Set to null to not log anything.</br>
* You can still allow console in the filter to log the original message.
*
* @param prefix The prefix for the message. Set to NULL to let it auto generate.
* @param message the message to be sent around
* @param filter the BroadcastFilter to be applied.</br>
* Write a class implementing the interface and pass it to this method, the "sendTo()" method will be called for each recipient.
* @param logmessage the log message to appear in console. Set to null to not log this (you can still log the original message by returning true in the filter).
* @return the amount of people that received the message. */
public static int broadcast(String prefix, String message, BroadcastFilter filter)
{
if (prefix == null)
prefix = "§8[§2" + getCaller() + "§8]: ";
if (filter == null)
{
for (Player p : Bukkit.getOnlinePlayers())
p.sendMessage(prefix + message);
Bukkit.getConsoleSender().sendMessage(prefix + message);
return Bukkit.getOnlinePlayers().size() + 1;
}
else
{
int count = 0;
for (Player p : Bukkit.getOnlinePlayers())
if (filter.sendTo(p))
{
p.sendMessage(prefix + message);
count++;
}
if (filter.sendTo(Bukkit.getConsoleSender()))
{
Bukkit.getConsoleSender().sendMessage(prefix + message);
count++;
}
return count;
}
}
/** This method will find the next parent caller and return their class name, omitting package names.
*
* @return the Name of the calling class. */
private static final String getCaller()
{
StackTraceElement[] stackTrace = (new Exception()).getStackTrace();
String classname = "Utils";
for (int i = 0; classname.equals("Utils"); i++)
{
classname = stackTrace[i].getClassName().replaceAll(".*\\.", "");
}
return classname;
}
/** This method will find the next parent caller and return their class name, omitting package names.
*
* @param directCaller used to prevent this method from returning the caller itself. Null if supposed to be ignored.
* @return the name of the calling class. */
public static final String getCaller(String... directCaller)
{
if (directCaller == null || directCaller.length == 0)
return getCaller();
StackTraceElement[] stackTrace = (new Exception()).getStackTrace();
String classname = "Utils";
List<String> callers = Arrays.asList(directCaller);
for (int i = 0; callers.contains(classname) || classname.equals("Utils"); i++)
{
classname = stackTrace[i].getClassName().replaceAll(".*\\.", "");
}
return classname;
}
/** Provides a uniform way of getting the date for all modules.
*
* @return The current date in the format "[dd-mm-yyyy hh:mm:ss]" */
public static String getDate()
{
Date date = new Date(System.currentTimeMillis());
return dateFormat.format(date);
}
/** Provides a uniform way of getting the (display)name of a @CommandSender.
*
* @param sender The @CommandSender to get the name of.
* @return The DisplayName of the @CommandSender or if not a @Player, the name in blue. */
public static String getName(CommandSender sender)
{
if (sender instanceof Player)
return ((Player) sender).getDisplayName();
else
return "§9" + sender.getName();
}
/** Provides a uniform way of getting the UUID of a @CommandSender.
*
* @param sender The @CommandSender to get the UUID of.
* @return The UUID of the @CommandSender or if not a player, "CONSOLE" in blue. */
public static String getID(CommandSender sender)
{
String id;
if (sender instanceof Player)
id = ((Player) sender).getUniqueId().toString();
else
id = "CONSOLE";
return id;
}
}

View File

@@ -0,0 +1,278 @@
package com.redstoner.misc.mysql;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import com.redstoner.exceptions.NonSaveableConfigException;
import com.redstoner.faucet.Faucet;
public class Config
{
private File file;
private JSONObject config;
private JSONParser parser;
public Config()
{
file = null;
parser = new JSONParser();
config = new JSONObject();
}
public Config(JSONObject config)
{
this.file = null;
this.parser = new JSONParser();
this.config = config;
}
private Config(File file) throws IOException, ParseException
{
this.file = file;
parser = new JSONParser();
if (file.exists())
{
config = loadConfig(file);
}
else
{
config = new JSONObject();
}
}
public static final Config getConfig(String fileName) throws IOException, ParseException
{
return new Config(new File(Faucet.plugin.getDataFolder(), fileName));
}
public static final Config getConfig(File file) throws IOException, ParseException
{
return new Config(file);
}
private JSONObject loadConfig(File file) throws IOException, ParseException
{
FileReader reader = new FileReader(file);
return (JSONObject) parser.parse(reader);
}
@Override
public String toString()
{
return config.toJSONString();
}
public JSONObject asObject()
{
return config;
}
public void save() throws IOException, NonSaveableConfigException
{
if (file == null)
{
throw new NonSaveableConfigException();
}
PrintWriter writer = new PrintWriter(file);
writer.write(config.toJSONString());
writer.close();
}
public void refresh() throws IOException, ParseException, NonSaveableConfigException
{
if (file == null)
{
throw new NonSaveableConfigException();
}
loadConfig(file);
}
public void setFile(String fileName)
{
file = new File(Faucet.plugin.getDataFolder(), fileName);
}
public void setFile(File file)
{
this.file = file;
}
@SuppressWarnings("unchecked")
public void put(String key, String value)
{
config.put(key, value);
}
@SuppressWarnings("unchecked")
public void put(String key, List<String> value)
{
JSONArray array = new JSONArray();
for (String entry : value)
{
array.add(entry);
}
config.put(key, array);
}
@SuppressWarnings("unchecked")
public void putArray(String key, JSONArray value)
{
config.put(key, value);
}
@SuppressWarnings("unchecked")
public void put(String key, Map<String, String> value)
{
JSONObject object = new JSONObject();
for (String valKey : value.keySet())
{
String valVal = value.get(valKey);
object.put(valKey, valVal);
}
config.put(key, object);
}
@SuppressWarnings("unchecked")
public void put(String key, JSONObject value)
{
config.put(key, value);
}
@SuppressWarnings("unchecked")
public void putAll(Map<String, String> entry)
{
for (String key : entry.keySet())
{
String value = entry.get(key);
config.put(key, value);
}
}
public boolean containsKey(String key)
{
return config.containsKey(key);
}
public String get(String key)
{
if (containsKey(key))
{
Object value = config.get(key);
if (value instanceof String)
{
return (String) value;
}
}
return null;
}
public String getOrDefault(String key, String defaultValue)
{
if (containsKey(key))
{
Object value = config.get(key);
if (value instanceof String)
{
return (String) value;
}
return null;
}
else
{
return defaultValue;
}
}
@SuppressWarnings("unchecked")
public List<String> getList(String key)
{
if (containsKey(key))
{
Object value = config.get(key);
if (value instanceof JSONArray)
{
JSONArray array = (JSONArray) value;
List<String> output = new ArrayList<>();
for (String entry : (String[]) array.toArray(new String[0]))
{
output.add(entry);
}
return output;
}
}
return null;
}
public JSONArray getArray(String key)
{
if (containsKey(key))
{
Object value = config.get(key);
if (value instanceof JSONArray)
{
JSONArray array = (JSONArray) value;
return array;
}
}
return null;
}
public Map<String, String> getMap(String key)
{
if (containsKey(key))
{
Object value = config.get(key);
if (value instanceof JSONObject)
{
JSONObject object = (JSONObject) value;
@SuppressWarnings("unchecked")
Set<Map.Entry<String, String>> entrySet = object.entrySet();
Map<String, String> output = new HashMap<>();
for (Map.Entry<String, String> entry : entrySet)
{
output.put(entry.getKey(), entry.getValue());
}
return output;
}
}
return null;
}
public JSONObject getObject(String key)
{
if (containsKey(key))
{
Object value = config.get(key);
if (value instanceof JSONObject)
{
JSONObject object = (JSONObject) value;
return object;
}
}
return null;
}
public void remove(String key)
{
config.remove(key);
}
@SuppressWarnings("unchecked")
public Set<Entry<String, String>> getAll()
{
return config.entrySet();
}
}

View File

@@ -0,0 +1,107 @@
package com.redstoner.misc.mysql;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import com.redstoner.faucet.Faucet;
public class JSONManager
{
public static Map<Serializable, Serializable> getConfiguration(String fileName)
{
File file = new File(Faucet.plugin.getDataFolder(), fileName);
if (!file.exists())
{
try
{
PrintWriter writer = new PrintWriter(file.getAbsolutePath(), "UTF-8");
writer.println("{}");
writer.close();
}
catch (FileNotFoundException | UnsupportedEncodingException e)
{
e.printStackTrace();
}
}
try
{
return loadMap(file);
}
catch (IOException | ParseException e)
{
e.printStackTrace();
return null;
}
}
public static void saveConfiguration(Map<Serializable, Serializable> config, String fileName)
{
try
{
saveMap(new File(Faucet.plugin.getDataFolder(), fileName), config);
}
catch (IOException e)
{
e.printStackTrace();
}
}
@SuppressWarnings("unchecked")
public static void saveList(File file, List<Serializable> entries) throws IOException
{
JSONArray array = new JSONArray();
array.addAll(entries);
FileWriter writer = new FileWriter(file);
writer.write(array.toJSONString());
writer.close();
}
public static List<Serializable> loadList(File file) throws IOException, ParseException
{
FileReader read = new FileReader(file);
List<Serializable> entries = new ArrayList<>();
JSONArray array = (JSONArray) new JSONParser().parse(read);
for (Object o : array)
{
entries.add((Serializable) o);
}
return entries;
}
@SuppressWarnings("unchecked")
public static void saveMap(File file, Map<Serializable, Serializable> entries) throws IOException
{
JSONObject map = new JSONObject();
map.putAll(entries);
FileWriter writer = new FileWriter(file);
writer.write(map.toJSONString());
writer.close();
}
public static Map<Serializable, Serializable> loadMap(File file) throws IOException, ParseException
{
FileReader reader = new FileReader(file);
JSONObject map = (JSONObject) new JSONParser().parse(reader);
Map<Serializable, Serializable> entries = new HashMap<>();
for (Object o : map.keySet())
{
entries.put((Serializable) o, (Serializable) map.get(o));
}
return entries;
}
}

View File

@@ -0,0 +1,115 @@
package com.redstoner.misc.mysql;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.json.simple.parser.ParseException;
import com.redstoner.faucet.Faucet;
import com.redstoner.misc.mysql.elements.MysqlDatabase;
public class MysqlHandler
{
public static MysqlHandler INSTANCE;
private String url, username, password;
public MysqlHandler(String hostname, int port, String username, String password)
{
this.url = "jdbc:mysql://" + hostname + ":" + port + "/";
this.username = username;
this.password = password;
}
public static void init()
{
Map<Serializable, Serializable> mysqlCredentials = new HashMap<>();
File mysqlCredentialsFile = new File(Faucet.plugin.getDataFolder(), "mysqlCredentials.json");
if (mysqlCredentialsFile.exists())
{
try
{
mysqlCredentials = JSONManager.loadMap(mysqlCredentialsFile);
}
catch (IOException | ParseException e)
{
e.printStackTrace();
}
}
else
{
Bukkit.getConsoleSender().sendMessage(
ChatColor.RED + "MySQL config does not exist, creating an example one, things might (will) break!");
mysqlCredentials.put("hostname", "localhost");
mysqlCredentials.put("port", "3306");
mysqlCredentials.put("username", "your username here");
mysqlCredentials.put("password", "your password here");
try
{
JSONManager.saveMap(mysqlCredentialsFile, mysqlCredentials);
}
catch (IOException e)
{
e.printStackTrace();
}
}
String hostname = (String) mysqlCredentials.get("hostname");
int port = Integer.valueOf((String) mysqlCredentials.get("port"));
String username = (String) mysqlCredentials.get("username");
String password = (String) mysqlCredentials.get("password");
INSTANCE = new MysqlHandler(hostname, port, username, password);
}
private Connection getConnection(String databaseName) throws IllegalStateException
{
Connection connection = null;
try
{
connection = DriverManager.getConnection(url + databaseName, username, password);
}
catch (SQLException e)
{
throw new IllegalStateException("Cannot connect to the database!", e);
}
return connection;
}
public MysqlDatabase getDatabase(String databaseName)
{
return new MysqlDatabase(getConnection(databaseName));
}
public List<MysqlDatabase> getDatabases()
{
try
{
List<MysqlDatabase> databases = new ArrayList<>();
Connection connection = DriverManager.getConnection(url.substring(0, url.length()), username, password);
DatabaseMetaData metadata = connection.getMetaData();
ResultSet queryResults = metadata.getCatalogs();
while (queryResults.next())
{
String databaseName = queryResults.getString("TABLE_CAT");
databases.add(new MysqlDatabase(getConnection(databaseName)));
}
connection.close();
return databases;
}
catch (SQLException e)
{
e.printStackTrace();
return null;
}
}
}

View File

@@ -0,0 +1,33 @@
package com.redstoner.misc.mysql;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class MysqlQueryHandler {
public static ResultSet queryResult(Connection connection, String query) {
try {
Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery(query);
return results;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
public static boolean queryNoResult(Connection connection, String query) {
try {
CallableStatement statement = connection.prepareCall(query);
statement.execute();
return true;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
}

View File

@@ -0,0 +1,24 @@
package com.redstoner.misc.mysql.elements;
public enum ConstraintOperator {
LESS_THAN, GREATER_THAN, EQUAL, NOT_EQUAL, LESS_THAN_OR_EQUAL, GREATER_THAN_OR_EQUAL;
public String toString() {
switch (this) {
case LESS_THAN:
return "<";
case GREATER_THAN:
return ">";
case EQUAL:
return "=";
case NOT_EQUAL:
return "!=";
case LESS_THAN_OR_EQUAL:
return "<=";
case GREATER_THAN_OR_EQUAL:
return ">=";
default:
return "=";
}
}
}

View File

@@ -0,0 +1,24 @@
package com.redstoner.misc.mysql.elements;
public class MysqlConstraint {
private String fieldName, value;
private ConstraintOperator operator;
public MysqlConstraint(String fieldName, ConstraintOperator operator, String value) {
this.fieldName = fieldName;
this.operator = operator;
this.value = value;
}
public String getFieldName() {
return fieldName;
}
public String getValue() {
return value;
}
public ConstraintOperator getOperator() {
return operator;
}
}

View File

@@ -0,0 +1,90 @@
package com.redstoner.misc.mysql.elements;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.redstoner.misc.mysql.MysqlQueryHandler;
public class MysqlDatabase {
private Connection connection;
public MysqlDatabase(Connection connection) {
this.connection = connection;
}
public String getName() {
try {
return connection.getCatalog();
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
public MysqlTable getTable(String name) {
return new MysqlTable(this, name);
}
public boolean createTable(String name, MysqlField... description) {
return MysqlQueryHandler.queryNoResult(connection, "CREATE TABLE `" + name + "` " + getDescription(description) + ";");
}
public boolean createTableIfNotExists(String name, MysqlField... description) {
return MysqlQueryHandler.queryNoResult(connection, "CREATE TABLE IF NOT EXISTS `" + name + "` " + getDescription(description) + ";");
}
public boolean dropTable(String name) {
return MysqlQueryHandler.queryNoResult(connection, "DROP TABLE `" + name + "`;");
}
public boolean drop() {
return MysqlQueryHandler.queryNoResult(connection, "DROP DATABASE `" + getName() + "`;");
}
public List<MysqlTable> getTables() {
try {
List<MysqlTable> tables = new ArrayList<>();
DatabaseMetaData metadata = connection.getMetaData();
ResultSet queryResults = metadata.getTables(null, null, "%", null);
while (queryResults.next()) {
tables.add(new MysqlTable(this, queryResults.getString(3)));
}
return tables;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
protected Connection getConnection() {
return connection;
}
private String getDescription(MysqlField... description) {
String desc = "(";
for (int i = 0; i < description.length; i++) {
String nil = "";
if (description[i].canBeNull()) {
nil = " NOT NULL";
}
desc += "`" + description[i].getName() + "` " + description[i].getType().getName() + nil;
if (i < description.length - 1) {
desc += ",";
}
}
desc += ")";
return desc;
}
}

View File

@@ -0,0 +1,33 @@
package com.redstoner.misc.mysql.elements;
import com.redstoner.misc.mysql.types.MysqlType;
public class MysqlField {
private String name;
private MysqlType type;
private boolean canBeNull;
public MysqlField(String name, MysqlType type, boolean canBeNull) {
this.name = name;
this.type = type;
this.canBeNull = canBeNull;
}
public MysqlField(String name, String type, boolean canBeNull) {
this.name = name;
this.type = MysqlType.getTypeFromString(type);
this.canBeNull = canBeNull;
}
public String getName() {
return name;
}
public MysqlType getType() {
return type;
}
public boolean canBeNull() {
return canBeNull;
}
}

View File

@@ -0,0 +1,16 @@
package com.redstoner.misc.mysql.elements;
import java.sql.ResultSet;
import java.sql.SQLException;
public class MysqlResult {
private ResultSet results;
public MysqlResult(ResultSet results) {
this.results = results;
}
public Object getObject(int columnIndex, Class<?> type) throws SQLException {
return results.getObject(columnIndex, type);
}
}

View File

@@ -0,0 +1,133 @@
package com.redstoner.misc.mysql.elements;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.redstoner.misc.mysql.MysqlQueryHandler;
public class MysqlTable
{
private MysqlDatabase database;
private String name;
public MysqlTable(MysqlDatabase database, String name)
{
this.database = database;
this.name = name;
}
public String getName()
{
return this.name;
}
public MysqlField[] describe()
{
try
{
List<MysqlField> description = new ArrayList<>();
DatabaseMetaData metadata = database.getConnection().getMetaData();
ResultSet queryResults = metadata.getColumns(null, null, name, null);
while (queryResults.next())
{
description.add(new MysqlField(queryResults.getString(4),
queryResults.getString(6).split(" ")[0] + "(" + queryResults.getString(7) + ")",
queryResults.getBoolean(11)));
}
return description.toArray(new MysqlField[0]);
}
catch (SQLException e)
{
e.printStackTrace();
return null;
}
}
public boolean insert(String... values)
{
MysqlField[] description = describe();
if (values.length > 0 && values.length == description.length)
{
String val = "(\"" + String.join("\",\"", values) + "\")";
return MysqlQueryHandler.queryNoResult(database.getConnection(),
"INSERT INTO `" + name + "` VALUES " + val + ";");
}
else
{
return false;
}
}
public Object[] get(String fieldName, MysqlConstraint... constraints)
{
ResultSet results = MysqlQueryHandler.queryResult(database.getConnection(),
"SELECT " + fieldName + " FROM `" + name + "`" + getConstraints(constraints) + ";");
List<Object> resObj = new ArrayList<>();
try
{
while (results.next())
{
resObj.add(results.getObject(1));
}
}
catch (SQLException e)
{
e.printStackTrace();
return new Object[0];
}
return resObj.toArray(new Object[0]);
}
public Object[] get(String statement)
{
ResultSet results = MysqlQueryHandler.queryResult(database.getConnection(), statement);
List<Object> resObj = new ArrayList<>();
try
{
while (results.next())
{
resObj.add(results.getObject(1));
}
}
catch (SQLException e)
{
e.printStackTrace();
return new Object[0];
}
return resObj.toArray(new Object[0]);
}
public boolean delete(MysqlConstraint... constraints)
{
return MysqlQueryHandler.queryNoResult(database.getConnection(),
"DELETE FROM `" + name + "`" + getConstraints(constraints) + ";");
}
public boolean drop()
{
return MysqlQueryHandler.queryNoResult(database.getConnection(), "DROP TABLE `" + name + "`;");
}
private String getConstraints(MysqlConstraint... constraints)
{
String cons = "";
if (constraints.length > 0)
{
cons += " WHERE ";
for (int i = 0; i < constraints.length; i++)
{
MysqlConstraint constraint = constraints[i];
cons += constraint.getFieldName() + constraint.getOperator().toString() + "\"" + constraint.getValue()
+ "\"";
if (i < constraints.length - 1)
{
cons += " AND ";
}
}
}
return cons;
}
}

View File

@@ -0,0 +1,96 @@
package com.redstoner.misc.mysql.types;
import com.redstoner.misc.mysql.types.date.Date;
import com.redstoner.misc.mysql.types.date.DateTime;
import com.redstoner.misc.mysql.types.date.Time;
import com.redstoner.misc.mysql.types.date.TimeStamp;
import com.redstoner.misc.mysql.types.date.Year;
import com.redstoner.misc.mysql.types.number.BigInt;
import com.redstoner.misc.mysql.types.number.Decimal;
import com.redstoner.misc.mysql.types.number.Double;
import com.redstoner.misc.mysql.types.number.Float;
import com.redstoner.misc.mysql.types.number.Int;
import com.redstoner.misc.mysql.types.number.MediumInt;
import com.redstoner.misc.mysql.types.number.SmallInt;
import com.redstoner.misc.mysql.types.number.TinyInt;
import com.redstoner.misc.mysql.types.text.Blob;
import com.redstoner.misc.mysql.types.text.Char;
import com.redstoner.misc.mysql.types.text.Enum;
import com.redstoner.misc.mysql.types.text.LongBlob;
import com.redstoner.misc.mysql.types.text.LongText;
import com.redstoner.misc.mysql.types.text.MediumBlob;
import com.redstoner.misc.mysql.types.text.MediumText;
import com.redstoner.misc.mysql.types.text.Set;
import com.redstoner.misc.mysql.types.text.Text;
import com.redstoner.misc.mysql.types.text.TinyText;
import com.redstoner.misc.mysql.types.text.VarChar;
public abstract class MysqlType
{
public abstract String getName();
public static MysqlType getTypeFromString(String type)
{
String[] splitType = type.split("\\(");
String toSwitch = splitType[0].toUpperCase();
String value = "";
if (type.contains("(") && type.endsWith(")"))
{
value = splitType[1].substring(0, splitType[1].length() - 1);
}
switch (toSwitch)
{
case "CHAR":
return new Char(Integer.valueOf(value));
case "ENUM":
return new Enum(value.replaceAll("'", "").split(","));
case "VARCHAR":
return new VarChar(Integer.valueOf(value));
case "SET":
return new Set(value.replaceAll("'", "").split(","));
case "BLOB":
return new Blob();
case "TEXT":
return new Text();
case "MEDIUMBLOB":
return new MediumBlob();
case "LONGBLOB":
return new LongBlob();
case "TINYTEXT":
return new TinyText();
case "MEDIUMTEXT":
return new MediumText();
case "LONGTEXT":
return new LongText();
case "INT":
return new Int(Integer.valueOf(value));
case "TINYINT":
return new TinyInt(Integer.valueOf(value));
case "SMALLINT":
return new SmallInt(Integer.valueOf(value));
case "MEDIUMINT":
return new MediumInt(Integer.valueOf(value));
case "BIGINT":
return new BigInt(Integer.valueOf(value));
case "BIT":
return new TinyInt(1);
case "FLOAT":
return new Float();
case "DOUBLE":
return new Double();
case "DECIMAL":
return new Decimal();
case "DATE":
return new Date();
case "DATETIME":
return new DateTime();
case "TIME":
return new Time();
case "TIMESTAMP":
return new TimeStamp();
case "YEAR":
return new Year();
}
return null;
}
}

View File

@@ -0,0 +1,10 @@
package com.redstoner.misc.mysql.types.date;
import com.redstoner.misc.mysql.types.MysqlType;
public class Date extends MysqlType {
@Override
public String getName() {
return "DATE";
}
}

View File

@@ -0,0 +1,10 @@
package com.redstoner.misc.mysql.types.date;
import com.redstoner.misc.mysql.types.MysqlType;
public class DateTime extends MysqlType {
@Override
public String getName() {
return "DATETIME";
}
}

View File

@@ -0,0 +1,10 @@
package com.redstoner.misc.mysql.types.date;
import com.redstoner.misc.mysql.types.MysqlType;
public class Time extends MysqlType {
@Override
public String getName() {
return "TIME";
}
}

View File

@@ -0,0 +1,10 @@
package com.redstoner.misc.mysql.types.date;
import com.redstoner.misc.mysql.types.MysqlType;
public class TimeStamp extends MysqlType {
@Override
public String getName() {
return "TIMESTAMP";
}
}

View File

@@ -0,0 +1,10 @@
package com.redstoner.misc.mysql.types.date;
import com.redstoner.misc.mysql.types.MysqlType;
public class Year extends MysqlType {
@Override
public String getName() {
return "YEAR";
}
}

View File

@@ -0,0 +1,12 @@
package com.redstoner.misc.mysql.types.number;
public class BigInt extends Int {
public BigInt(int maxSize) {
super(maxSize);
}
@Override
public String getName() {
return "BIG" + super.getName();
}
}

View File

@@ -0,0 +1,10 @@
package com.redstoner.misc.mysql.types.number;
import com.redstoner.misc.mysql.types.MysqlType;
public class Decimal extends MysqlType {
@Override
public String getName() {
return "DECIMAL";
}
}

View File

@@ -0,0 +1,10 @@
package com.redstoner.misc.mysql.types.number;
import com.redstoner.misc.mysql.types.MysqlType;
public class Double extends MysqlType {
@Override
public String getName() {
return "DOUBLE";
}
}

View File

@@ -0,0 +1,10 @@
package com.redstoner.misc.mysql.types.number;
import com.redstoner.misc.mysql.types.MysqlType;
public class Float extends MysqlType {
@Override
public String getName() {
return "FLOAT";
}
}

View File

@@ -0,0 +1,16 @@
package com.redstoner.misc.mysql.types.number;
import com.redstoner.misc.mysql.types.MysqlType;
public class Int extends MysqlType {
private int maxSize;
public Int(int maxSize) {
this.maxSize = maxSize;
}
@Override
public String getName() {
return "INT(" + maxSize + ")";
}
}

View File

@@ -0,0 +1,12 @@
package com.redstoner.misc.mysql.types.number;
public class MediumInt extends Int {
public MediumInt(int maxSize) {
super(maxSize);
}
@Override
public String getName() {
return "MEDIUM" + super.getName();
}
}

View File

@@ -0,0 +1,12 @@
package com.redstoner.misc.mysql.types.number;
public class SmallInt extends Int {
public SmallInt(int maxSize) {
super(maxSize);
}
@Override
public String getName() {
return "SMALL" + super.getName();
}
}

View File

@@ -0,0 +1,12 @@
package com.redstoner.misc.mysql.types.number;
public class TinyInt extends Int {
public TinyInt(int maxSize) {
super(maxSize);
}
@Override
public String getName() {
return "TINY" + super.getName();
}
}

View File

@@ -0,0 +1,10 @@
package com.redstoner.misc.mysql.types.text;
import com.redstoner.misc.mysql.types.MysqlType;
public class Blob extends MysqlType {
@Override
public String getName() {
return "BLOB";
}
}

View File

@@ -0,0 +1,16 @@
package com.redstoner.misc.mysql.types.text;
import com.redstoner.misc.mysql.types.MysqlType;
public class Char extends MysqlType {
private int size;
public Char(int size) {
this.size = size;
}
@Override
public String getName() {
return "CHAR(" + size + ")";
}
}

View File

@@ -0,0 +1,27 @@
package com.redstoner.misc.mysql.types.text;
import com.redstoner.misc.mysql.types.MysqlType;
public class Enum extends MysqlType {
private String[] possibleValues;
public Enum(String... possibleValues) {
this.possibleValues = possibleValues;
}
@Override
public String getName() {
String name = "ENUM(";
for (int i = 0; i < possibleValues.length; i++) {
name += "'" + possibleValues[i] + "'";
if (i != possibleValues.length - 1) {
name += ",";
}
}
return name + ")";
}
}

View File

@@ -0,0 +1,8 @@
package com.redstoner.misc.mysql.types.text;
public class LongBlob extends Blob {
@Override
public String getName() {
return "LONG" + super.getName();
}
}

View File

@@ -0,0 +1,8 @@
package com.redstoner.misc.mysql.types.text;
public class LongText extends Text {
@Override
public String getName() {
return "LONG" + super.getName();
}
}

View File

@@ -0,0 +1,8 @@
package com.redstoner.misc.mysql.types.text;
public class MediumBlob extends Blob {
@Override
public String getName() {
return "MEDIUM" + super.getName();
}
}

View File

@@ -0,0 +1,8 @@
package com.redstoner.misc.mysql.types.text;
public class MediumText extends Text {
@Override
public String getName() {
return "MEDIUM" + super.getName();
}
}

View File

@@ -0,0 +1,27 @@
package com.redstoner.misc.mysql.types.text;
import com.redstoner.misc.mysql.types.MysqlType;
public class Set extends MysqlType {
private String[] possibleValues;
public Set(String... possibleValues) {
this.possibleValues = possibleValues;
}
@Override
public String getName() {
String name = "SET(";
for (int i = 0; i < possibleValues.length; i++) {
name += "'" + possibleValues[i] + "'";
if (i != possibleValues.length - 1) {
name += ",";
}
}
return name + ")";
}
}

View File

@@ -0,0 +1,10 @@
package com.redstoner.misc.mysql.types.text;
import com.redstoner.misc.mysql.types.MysqlType;
public class Text extends MysqlType {
@Override
public String getName() {
return "TEXT";
}
}

View File

@@ -0,0 +1,8 @@
package com.redstoner.misc.mysql.types.text;
public class TinyText extends Text {
@Override
public String getName() {
return "TINY" + super.getName();
}
}

View File

@@ -0,0 +1,16 @@
package com.redstoner.misc.mysql.types.text;
import com.redstoner.misc.mysql.types.MysqlType;
public class VarChar extends MysqlType {
private int maxSize;
public VarChar(int maxSize) {
this.maxSize = maxSize;
}
@Override
public String getName() {
return "VARCHAR(" + maxSize + ")";
}
}

View File

@@ -0,0 +1,62 @@
package com.redstoner.modules;
import com.redstoner.annotations.Version;
import com.redstoner.faucet.Faucet;
/** Interface for the Module class. Modules must always have an empty constructor to be invoked by the ModuleLoader.
*
* @author Pepich */
public interface Module
{
/** This method gets called to enable your module.
* It is guaranteed that all hard dependencies were loaded and enabled successfully.<br/>
* If is not guaranteed that all soft dependencies were loaded and enabled successfully, but it is guaranteed that there was an attempt to do so.<br/>
* If a hard dependency is missing or could not be enabled, then this method will not be called at all.<br/>
* If a soft dependency is missing or could not be enabled, then this method will be run regardless.<br/>
*
* @return true, if and only if your module successfully enabled. Return false to tell the loader that something went wrong. */
public default boolean onEnable()
{
return true;
}
/** This method gets called after ALL modules were enabled.<br/>
* You can use this method to do initialization based on which other modules are loaded and enabled. */
public default void postEnable()
{}
/** This method will be called when the loader disables the module. You can use this method to do cleanup.<br/>
* Please note that this method is run ASYNC and with a 10ms timeout.<br/>
* If the timeout gets exceeded the execution will be aborted. If you need to perform a task that will be longer than the given timeout,
* you can use setTimeout(int timeout) to change it as you desire. If you need your execution to be done sync, annotate this method with @SYNCHRONISED. */
public default void onDisable()
{}
/** Gets called on registration of the module, when this option is selected for command registration
*
* @return The String used for the CommandManager to register the commands. */
public default String getCommandString()
{
return null;
}
/** This method gets run the very first time a module gets loaded. You can use this to set up file structures or background data. */
public default void firstLoad()
{}
/** This method gets run every time a module gets loaded and its version has changed.
*
* @param old The version of the previous module. */
public default void migrate(Version old)
{}
public default boolean enabled()
{
return Faucet.isEnabled(this);
}
public default void disable()
{
Faucet.disable(this);
}
}

View File

@@ -0,0 +1,73 @@
package com.redstoner.modules;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import net.nemez.chatapi.ChatAPI;
import net.nemez.chatapi.click.Message;
public class ModuleLogger
{
public static final String PREFIX_WARN = "§8[§eWARN§8]:§7 ";
public static final String PREFIX_ERROR = "§8[§cERROR§8]:§7 ";
private String name;
public ModuleLogger(final String name)
{
this.name = name;
}
public void info(final String message)
{
Bukkit.getConsoleSender().sendMessage(getPrefix() + ChatAPI.colorify(null, message));
}
public void warn(final String message)
{
Bukkit.getConsoleSender().sendMessage(PREFIX_WARN + getPrefix() + ChatAPI.colorify(null, message));
}
public void error(final String message)
{
Bukkit.getConsoleSender().sendMessage(PREFIX_ERROR + getPrefix() + ChatAPI.colorify(null, message));
}
public void message(final CommandSender recipient, final String... message)
{
message(recipient, false, message);
}
public void message(final CommandSender recipient, final boolean error, final String... message)
{
Message m = new Message(recipient, null);
if (message.length == 1)
m.appendText(getPrefix(error) + message[0]);
else
{
m.appendText(getHeader());
m.appendText("&7" + String.join("\n&7", message));
}
m.send();
}
public String getPrefix()
{
return getPrefix(false);
}
public String getPrefix(final boolean error)
{
return "§8[§" + (error ? 'c' : '2') + name + "§8]§7 ";
}
public String getHeader()
{
return "§2--=[ " + name + " ]=--\n";
}
protected final void setName(final String name)
{
this.name = name;
}
}