Import Parabot "API" & Rename Directory Names

This commit is contained in:
Dark98
2021-10-06 16:28:08 +01:00
parent ffc3bdd5a8
commit 82646880da
32 changed files with 2027 additions and 5 deletions
-5
View File
@@ -70,11 +70,6 @@
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.parabot</groupId>
<artifactId>internal-api</artifactId>
<version>1.53.1</version>
</dependency>
</dependencies>
<build>
@@ -0,0 +1,14 @@
package org.parabot.api;
/**
* @author JKetelaar
*/
public class Configuration {
public static final String BOT_TITLE = "Parabot";
public static final String BOT_SLOGAN = "The best RuneScape private server bot";
public static final String V3_API_ENDPOINT = "http://v3.bdn.parabot.org/api/";
public static final String LIBRARIES_DOWNLOAD = V3_API_ENDPOINT + "bot/libraries/download";
}
@@ -0,0 +1,26 @@
package org.parabot.api.calculations;
/**
* A random class is used for generating random numbers
*
* @author Everel
*/
public class Random {
private final static java.util.Random RANDOM = new java.util.Random();
/**
* Randomizes a number between minimum and maximum
*
* @param min
* @param max
* @return randomized number
*/
public static int between(final int min, final int max) {
try {
return min + (max == min ? 0 : RANDOM.nextInt(max - min));
} catch (Exception e) {
return min + (max - min);
}
}
}
@@ -0,0 +1,277 @@
package org.parabot.api.io;
import org.parabot.api.misc.OperatingSystem;
import org.parabot.api.output.Verboser;
import javax.swing.*;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.*;
/**
* Holds and manages Parabot's used directories
*
* @author Everel
* @author JKetelaar
* @author Matt
*/
public class Directories {
private static Map<String, File> cached;
private static File temp = null;
static {
cached = new HashMap<>();
switch (OperatingSystem.getOS()) {
case WINDOWS:
cached.put("Root", new JFileChooser().getFileSystemView().getDefaultDirectory());
break;
default:
cached.put("Root", new File(System.getProperty("user.home")));
break;
}
Verboser.verbose("Caching directories...");
cached.put("Root", getDefaultDirectory());
cached.put("Workspace", new File(cached.get("Root"), "/2006Scape/"));
cached.put("Sources", new File(cached.get("Root"), "/2006Scape/scripts/sources/"));
cached.put("Compiled", new File(cached.get("Root"), "/2006Scape/scripts/compiled/"));
cached.put("Resources", new File(cached.get("Root"), "/2006Scape/scripts/resources/"));
cached.put("Settings", new File(cached.get("Root"), "/2006Scape/settings/"));
cached.put("Servers", new File(cached.get("Root"), "/2006Scape/servers/"));
cached.put("Cache", new File(cached.get("Root"), "/2006Scape/cache/"));
cached.put("Screenshots", new File(cached.get("Root"), "/2006Scape/screenshots/"));
Verboser.verbose("Directories cached.");
clearCache(259200);
}
/**
* Set script bin folder
*
* @param f
*/
public static void setScriptCompiledDirectory(File f) {
if (!f.isDirectory()) {
throw new IllegalArgumentException(f + "is not a directory.");
}
cached.put("Compiled", f);
}
/**
* Set server bin folder
*
* @param f
*/
public static void setServerCompiledDirectory(File f) {
if (!f.isDirectory()) {
throw new IllegalArgumentException(f + "is not a directory.");
}
cached.put("Servers", f);
}
/**
* Returns the root directory outside of the main Parabot folder.
*
* @return
*/
public static File getDefaultDirectory() {
return cached.get("Root");
}
/**
* Returns the Parabot folder.
*
* @return
*/
public static File getWorkspace() {
return cached.get("Workspace");
}
/**
* Returns the script sources folder.
*
* @return
*/
public static File getScriptSourcesPath() {
return cached.get("Sources");
}
/**
* Returns the compiled scripts folder.
*
* @return
*/
public static File getScriptCompiledPath() {
return cached.get("Compiled");
}
/**
* Returns the scripts resources folder.
*
* @return
*/
public static File getResourcesPath() {
return cached.get("Resources");
}
/**
* Returns the Parabot settings folder.
*
* @return
*/
public static File getSettingsPath() {
return cached.get("Settings");
}
/**
* Returns the Parabot servers folder.
*
* @return
*/
public static File getServerPath() {
return cached.get("Servers");
}
/**
* Returns the Parabot cache folder.
*
* @return
*/
public static File getCachePath() {
return cached.get("Cache");
}
/**
* Returns the redirected Home Directory
*
* @return
*/
public static File getHomeDir() {
return cached.get("Home");
}
/**
* Returns the screenshot folder.
*
* @return
*/
public static File getScreenshotDir() {
return cached.get("Screenshots");
}
/**
* Validates all directories and makes them if necessary
*/
public static void validate() {
final File defaultPath = getDefaultDirectory();
if (defaultPath == null || !defaultPath.exists()) {
throw new RuntimeException("Default path not found");
}
final Queue<File> files = new LinkedList<File>();
files.addAll(cached.values());
while (files.size() > 0) {
final File file = files.poll();
if (!file.exists()) {
Verboser.verbose("Generating directory: " + file.getAbsolutePath());
file.mkdirs();
if (!file.exists()) {
System.err.println("Failed to make directory: " + file.getAbsolutePath());
}
}
}
}
public static File getTempDirectory() {
if (temp != null) {
return temp;
}
int randomNum = new Random().nextInt(999999999);
temp = new File(getResourcesPath(), randomNum + "/");
temp.mkdirs();
temp.deleteOnExit();
return temp;
}
/**
* Clears the cache based on the latest modification
*
* @param remove A long that represents the amount of seconds that a file may have since the latest modification
* @param force Defines if the cache folder, within user.home, should also be removed
*/
public static void clearCache(int remove, boolean force) {
File[] cache = getCachePath().listFiles();
if (cache != null) {
for (File f : cache) {
if (f != null && System.currentTimeMillis() / 1000 - f.lastModified() / 1000 > remove) {
Verboser.verbose("Clearing " + (f.isDirectory() ? "directory " : "file ") + f.getName() + " from cache (" + (force ? "Force-cleared" : "Expired") + ")...");
try {
FileUtil.delete(f);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
private static void clearCache(int remove) {
clearCache(remove, false);
}
public static void clearCache() {
clearCache(0, true);
}
/**
* @param file Directory to be removed
*/
private static void removeDirectory(File file, boolean root) {
if (file.isDirectory()) {
if (file.list().length == 0) {
file.delete();
Verboser.verbose("Directory is deleted : "
+ file.getAbsolutePath());
} else {
String files[] = file.list();
for (String temp : files) {
File fileDelete = new File(file, temp);
removeDirectory(fileDelete, false);
}
if (file.list().length == 0) {
file.delete();
Verboser.verbose("Directory is deleted: "
+ file.getAbsolutePath());
}
}
if (root) {
file.delete();
}
} else {
file.delete();
Verboser.verbose("File is deleted : " + file.getAbsolutePath());
}
}
/**
* Returns an array of files with from a given directory and a given extension
*
* @param directory The directory where should be searched
* @param extension The extension to be searched for, including the dot (like .json)
* @return An array of of files that match the request
*/
public static File[] listFilesWithExtension(File directory, final String extension) {
return directory.listFiles(new FilenameFilter() {
public boolean accept(File dir, String filename) {
return filename.endsWith(extension);
}
});
}
public static File[] listJSONFiles(File directory) {
return listFilesWithExtension(directory, ".json");
}
}
@@ -0,0 +1,123 @@
package org.parabot.api.io;
import org.parabot.api.output.Verboser;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* @author JKetelaar
*/
public class FileUtil {
public static String getChecksum(File file) {
if (file.isFile()) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
if (file.exists()) {
FileInputStream fis = new FileInputStream(file);
byte[] dataBytes = new byte[1024];
int nread;
while ((nread = fis.read(dataBytes)) != -1) {
md.update(dataBytes, 0, nread);
}
byte[] mdbytes = md.digest();
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < mdbytes.length; i++) {
sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
}
} catch (NoSuchAlgorithmException | IOException e) {
e.printStackTrace();
}
}
return null;
}
public static byte[] getChecksumBytes(File file) {
if (file.isFile()) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
if (file.exists()) {
FileInputStream fis = new FileInputStream(file);
byte[] dataBytes = new byte[1024];
int nread;
while ((nread = fis.read(dataBytes)) != -1) {
md.update(dataBytes, 0, nread);
}
return md.digest();
}
} catch (NoSuchAlgorithmException | IOException e) {
e.printStackTrace();
}
}
return null;
}
public static void copyFile(File sourceFile, File destFile)
throws IOException {
if (!sourceFile.exists()) {
return;
}
if (!destFile.exists()) {
destFile.createNewFile();
}
FileChannel source = null;
FileChannel destination = null;
source = new FileInputStream(sourceFile).getChannel();
destination = new FileOutputStream(destFile).getChannel();
if (source != null) {
destination.transferFrom(source, 0, source.size());
}
if (source != null) {
source.close();
}
destination.close();
}
public static void delete(File file) throws IOException {
if (file.isDirectory()) {
if (file.list().length == 0) {
boolean success = file.delete();
Verboser.verbose(success ? "Deleted " + file.getAbsolutePath() + " OK" :
"FAILED to delete " + file.getAbsolutePath());
} else {
String files[] = file.list();
for (String temp : files) {
File fileDelete = new File(file, temp);
delete(fileDelete);
}
if (file.list().length == 0) {
boolean success = file.delete();
Verboser.verbose(success ? "Deleted " + file.getAbsolutePath() + " OK" :
"FAILED to delete " + file.getAbsolutePath());
}
}
} else {
boolean success = file.delete();
Verboser.verbose(success ? "Deleted " + file.getAbsolutePath() + " OK" :
"FAILED to delete " + file.getAbsolutePath());
}
}
}
@@ -0,0 +1,43 @@
package org.parabot.api.io;
import javax.imageio.ImageIO;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.net.URL;
/**
* @author Fryslan
*/
public class ImageUtil {
/**
* Gets an image from local device
*
* @param location Location of the image
* @return image from location.
*/
public Image getLocalImage(String location) {
try {
File sourceimage = new File(location);
return ImageIO.read(sourceimage);
} catch (IOException e) {
return null;
}
}
/**
* Gets an image from the given URL.
*
* @param url Url of th image.
* @return image from location.
*/
public Image getURLImage(String url) {
try {
URL sourceimage = new URL(url);
return ImageIO.read(sourceimage);
} catch (IOException e) {
return null;
}
}
}
@@ -0,0 +1,44 @@
package org.parabot.api.io;
/**
* Keeps track of a progress
*
* @author Everel
*/
public interface ProgressListener {
/**
* Called when progress increased
*
* @param value
*/
void onProgressUpdate(double value);
/**
* Updates upload speed
*
* @param mbPerSecond
*/
void updateDownloadSpeed(double mbPerSecond);
/**
* Sets the message displayed
* @param message The Text to show
*/
void updateMessage(String message);
/**
* Combination of the two
* @param message
* @param progress
*/
void updateMessageAndProgress(String message, double progress);
/**
* Usage would be
* <pre>double before = getCurrentProgress() <br> setCurrent(0) <br> for 0 .. 100: setCurrent(x) <br> done! <br> setCurrent(before)</pre>
* @return
*/
double getCurrentProgress();
}
@@ -0,0 +1,62 @@
package org.parabot.api.io;
import java.io.IOException;
import java.io.InputStream;
/**
* @author Everel
*/
public class SizeInputStream extends InputStream {
public int bytesRead;
private ProgressListener l;
private InputStream in;
private long startTime;
private double size;
public SizeInputStream(InputStream in, int size, ProgressListener l) {
this.in = in;
this.size = size;
this.l = l;
this.startTime = System.currentTimeMillis();
}
public int available() {
return ((int) size - bytesRead);
}
public int read() throws IOException {
int b = in.read();
if (b != -1) {
bytesRead++;
}
updateListener();
return b;
}
public int read(byte[] b) throws IOException {
int read = in.read(b);
bytesRead += read;
updateListener();
return read;
}
public int read(byte[] b, int off, int len) throws IOException {
int read = in.read(b, off, len);
bytesRead += read;
updateListener();
return read;
}
private void updateListener() {
if (l != null) {
double percent = (bytesRead / size) * 100.0D;
l.onProgressUpdate(percent);
long curTime = System.currentTimeMillis();
double timeSeconds = (curTime - startTime) / 1000.0D;
double speed = bytesRead / (1024.0D * 1024.0D) / timeSeconds;
l.updateDownloadSpeed(speed);
}
}
}
@@ -0,0 +1,330 @@
package org.parabot.api.io;
import org.json.simple.parser.JSONParser;
import org.parabot.api.output.Verboser;
import java.io.*;
import java.net.*;
/**
* A WebUtil class fetches data from an URL
*
* @author Everel
*/
public class WebUtil {
private static JSONParser jsonParser;
private static String agent = "Mozilla/5.0 (Wind0ws NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.112 Safari/535.1";
/**
* Gets useragent
*
* @return useragent
*/
public static String getUserAgent() {
return agent;
}
/**
* Agent to set at a URL connection
*
* @param userAgent
*/
public static void setUserAgent(final String userAgent) {
agent = userAgent;
}
/**
* Fetches content of a page
*
* @param location
* @return contents of page
* @throws MalformedURLException
*/
public static String getContents(final String location)
throws MalformedURLException {
return getContents(new URL(location));
}
public static String getContents(final String location, String parameters) throws MalformedURLException {
return getContents(new URL(location), parameters);
}
/**
* Get contents from URL
*
* @param url
* @return page contents
*/
public static String getContents(final URL url) {
return getContents(getConnection(url));
}
public static String getContents(final URL url, final String parameters) {
return getContents(getConnection(url), parameters);
}
/**
* Gets contents from URLConnection
*
* @param urlConnection
* @return page contents
*/
public static String getContents(URLConnection urlConnection) {
try {
final BufferedReader in = getReader(urlConnection);
final StringBuilder builder = new StringBuilder();
String line;
if (in != null) {
while ((line = in.readLine()) != null) {
builder.append(line);
}
in.close();
}
return builder.toString();
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
public static String getContents(URLConnection urlConnection, String parameters) {
try {
urlConnection.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(urlConnection.getOutputStream());
wr.write(parameters);
wr.flush();
wr.close();
final BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
final StringBuilder builder = new StringBuilder();
String line;
while ((line = in.readLine()) != null) {
builder.append(line);
}
return builder.toString();
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
/**
* Gets buffered reader from string url
*
* @param url
* @return bufferedreader
*/
public static BufferedReader getReader(final String url) {
try {
return getReader(new URL(url));
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
/**
* Gets BufferedReader from URL
*
* @param url
* @return BufferedReader from URL
*/
public static BufferedReader getReader(final URL url) {
return getReader(getConnection(url));
}
public static BufferedReader getReader(final URLConnection urlConnection) {
try {
return new BufferedReader(new InputStreamReader(
urlConnection.getInputStream()));
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
/**
* Gets inputstream from url
*
* @param url
* @return inputstream from url
*/
public static InputStream getInputStream(final URL url) {
final URLConnection con = getConnection(url);
try {
return con.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* Opens a connection
*
* @param url
* @return URLConnection to URL
*/
public static URLConnection getConnection(final URL url) {
try {
final URLConnection con = url.openConnection();
con.setRequestProperty("User-Agent", agent);
return con;
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
public static URLConnection getConnection(final URL url, String parameters) {
try {
final URLConnection con = getConnection(url);
con.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream());
wr.write(parameters);
wr.flush();
wr.close();
return con;
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
public static BufferedReader getReader(final URL url, String username, String password) {
try {
String data = URLEncoder.encode("username", "UTF-8") + "=" + username;
data += "&" + URLEncoder.encode("password", "UTF-8") + "=" + password;
URLConnection connection = url.openConnection();
connection.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream());
wr.write(data);
wr.flush();
wr.close();
return new BufferedReader(new InputStreamReader(connection.getInputStream()));
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
public static URLConnection getConnection(final URL url, String username, String password) {
try {
String data = URLEncoder.encode("username", "UTF-8") + "=" + username;
data += "&" + URLEncoder.encode("password", "UTF-8") + "=" + password;
URLConnection connection = url.openConnection();
connection.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream());
wr.write(data);
wr.flush();
wr.close();
return connection;
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
/**
* Downloads a file on the internet
*
* @param url
* @param destination
*/
public static void downloadFile(final URL url, final File destination) {
downloadFile(url, destination, null, null, null);
}
/**
* Downloads a file on the internet
*
* @param url
* @param destination
* @param listener
*/
public static void downloadFile(final URL url, final File destination,
final ProgressListener listener) {
downloadFile(url, destination, listener, null, null);
}
/**
* Downloads a file on the internet
*
* @param url
* @param destination
* @param listener
*/
public static void downloadFile(final URL url, final File destination,
final ProgressListener listener, String username, String password) {
try {
final URLConnection connection;
if (username == null || password == null) {
connection = getConnection(url);
} else {
connection = getConnection(url, username, password);
}
final int size = connection.getContentLength();
SizeInputStream sizeInputStream = new SizeInputStream(
connection.getInputStream(), size, listener);
BufferedInputStream in = new BufferedInputStream(sizeInputStream);
FileOutputStream fileOut = new FileOutputStream(destination);
final double before = listener == null ? 0d : listener.getCurrentProgress();
final long startTime = System.currentTimeMillis();
int totalRead = 0;
try {
byte data[] = new byte[1024];
int count;
while ((count = in.read(data, 0, 1024)) != -1) {
fileOut.write(data, 0, count);
totalRead += count;
if (listener != null) {
double progress = (((double)totalRead / (double)size) * 100d);
String rate = (totalRead / Math.max(1, ((System.currentTimeMillis()-startTime)/1000))) + "/s";
listener.updateMessageAndProgress(String.format("[%s] Downloading... %02f%% (%s of %s bytes) %s from %s to %s", WebUtil.class.getName(), progress, totalRead, size, rate, url.getPath(), destination.getAbsolutePath()),
progress);
}
}
} finally {
in.close();
fileOut.close();
}
if (listener != null) {
listener.onProgressUpdate(before);
}
Verboser.verbose("[WebUtil] Downloaded " + totalRead + " bytes from " + url + " -> " + destination.getAbsolutePath());
} catch (Throwable t) {
t.printStackTrace();
}
}
/**
* Converts file format to url format
*
* @param file
* @return url to file
*/
public static URL toURL(File file) {
try {
return file.toURI().toURL();
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
public static JSONParser getJsonParser() {
if (jsonParser == null) {
jsonParser = new JSONParser();
}
return jsonParser;
}
}
@@ -0,0 +1,19 @@
package org.parabot.api.io.build;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
public class BuildPath {
public static void add(final URL url) {
try {
Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
method.setAccessible(true);
method.invoke((URLClassLoader) ClassLoader.getSystemClassLoader(), url);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,30 @@
package org.parabot.api.io.images;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.util.HashMap;
/**
*
* Caches and loads images from resource
*
* @author Everel, JKetelaar
*
*/
public class Images {
private static final HashMap<String, BufferedImage> IMAGE_CACHE = new HashMap<>();
public static BufferedImage getResource(final String resource) {
if(IMAGE_CACHE.containsKey(resource)) {
return IMAGE_CACHE.get(resource);
}
try {
final BufferedImage img = ImageIO.read(Images.class.getResourceAsStream(resource));
IMAGE_CACHE.put(resource, img);
return img;
} catch (Throwable t) {
throw new RuntimeException("Failed to load image from resource. " + t.getMessage());
}
}
}
@@ -0,0 +1,23 @@
package org.parabot.api.io.libraries;
import org.parabot.api.io.WebUtil;
/**
* @author JKetelaar
*/
public class Environment {
/**
* Loads library into environment
*
* @param library
*/
public static void loadLibrary(Library library) {
if (library.requiresJar()) {
if (!library.hasJar()) {
WebUtil.downloadFile(library.getDownloadLink(), library.getJarFile());
}
library.init();
}
}
}
@@ -0,0 +1,67 @@
package org.parabot.api.io.libraries;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
/**
*
* @author Everel
*
*/
public abstract class Library {
/**
* Determines if this library jar has already been downloaded.
* @return <b>false</b> if library jar has not been downloaded, otherwise <b>true</b>
*/
public boolean hasJar() {
return getJarFile().exists();
}
/**
* Adds the library to the buildpath and validates if it has been added
*/
public abstract void init();
/**
* Determines if library has been added to the buildpath
* @return <b>true</b> if library has been added to the buildpath, otherwise <b>false</b>.
*/
public abstract boolean isAdded();
/**
* Gets the local file target/location of the jar file
* @return local file (target) to library
*/
public abstract File getJarFile();
/**
* Gets download url to the library
* @return url
*/
public abstract URL getDownloadLink();
/**
* Defines if the system requires a jar
* @return boolean
*/
public abstract boolean requiresJar();
/**
* Fetches URL from {@link Library#getJarFile()}
* @return URL to local library jar file
*/
public URL getJarFileURL() {
try {
return getJarFile().toURI().toURL();
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
public abstract String getLibraryName();
}
@@ -0,0 +1,67 @@
package org.parabot.api.io.libraries.jpushbullet;
import org.parabot.api.Configuration;
import org.parabot.api.io.Directories;
import org.parabot.api.io.build.BuildPath;
import org.parabot.api.io.libraries.Library;
import java.io.File;
import java.net.URL;
/**
* @author EmmaStone
*/
public class JPushBullet extends Library {
private static boolean valid;
@Override
public void init() {
if (!hasJar()) {
System.err.println("Failed to load jpushbullet... [jar missing]");
return;
}
BuildPath.add(getJarFileURL());
try {
Class.forName("com.github.sheigutn.pushbullet.Pushbullet");
valid = true;
} catch (ClassNotFoundException e) {
System.err
.println("Failed to add jpushbullet to build path, or incorrupt download");
}
}
@Override
public boolean isAdded() {
return valid;
}
@Override
public File getJarFile() {
return new File(Directories.getCachePath(), "jpushbullet.jar");
}
@Override
public URL getDownloadLink() {
try {
return new URL(Configuration.LIBRARIES_DOWNLOAD + "/JPushBullet");
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
@Override
public boolean requiresJar() {
return true;
}
@Override
public String getLibraryName() {
return "JPushBullet";
}
public static boolean isValid() {
return valid;
}
}
@@ -0,0 +1,15 @@
package org.parabot.api.misc;
/**
* @author JKetelaar
*/
public class JavaUtil {
public static double JAVA_VERSION = getVersion();
static double getVersion() {
String version = System.getProperty("java.version");
int pos = version.indexOf('.');
pos = version.indexOf('.', pos + 1);
return Double.parseDouble(version.substring(0, pos));
}
}
@@ -0,0 +1,26 @@
package org.parabot.api.misc;
/**
* This class is used for detecting the user's operating system
*
* @author Everel
*/
public enum OperatingSystem {
WINDOWS, LINUX, MAC, OTHER;
public static final OperatingSystem getOS() {
String str = System.getProperty("os.name").toLowerCase();
if (str.contains("win")) {
return OperatingSystem.WINDOWS;
}
if (str.contains("mac")) {
return OperatingSystem.MAC;
}
if (str.contains("nix") || str.contains("nux")) {
return OperatingSystem.LINUX;
}
return OperatingSystem.OTHER;
}
}
@@ -0,0 +1,44 @@
package org.parabot.api.misc;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* @author JKetelaar
*/
public class ProjectProperties {
private static ProjectProperties instance;
private Properties cached = new Properties();
private ProjectProperties() {
setProperties();
}
public static Version getProjectVersion() {
return new Version(getInstance().getCached().getProperty("application.version"));
}
public static ProjectProperties getInstance() {
return instance == null ? instance = new ProjectProperties() : instance;
}
private void setProperties() {
InputStream input;
try {
String propertiesFileName = "storage/internal.properties";
input = getClass().getClassLoader()
.getResourceAsStream(propertiesFileName);
cached.load(input);
} catch (IOException e) {
e.printStackTrace();
}
}
private Properties getCached() {
return cached;
}
}
@@ -0,0 +1,117 @@
package org.parabot.api.misc;
/**
* @author mkyong, JKetelaar
*/
public class StringUtil {
private static java.util.Random random = new java.util.Random();
private static char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".toCharArray();
public static String implode(String separator, String... data) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.length - 1; i++) {
//data.length - 1 => to not add separator at the end
if (!data[i].matches(" *")) {//empty string are ""; " "; " "; and so on
sb.append(data[i]);
sb.append(separator);
}
}
sb.append(data[data.length - 1].trim());
return sb.toString();
}
public static String convertHexToString(String hex) {
StringBuilder sb = new StringBuilder();
StringBuilder temp = new StringBuilder();
for (int i = 0; i < hex.length() - 1; i += 2) {
// grab the hex in pairs
String output = hex.substring(i, (i + 2));
// convert hex to decimal
int decimal = Integer.parseInt(output, 16);
// convert the decimal to character
sb.append((char) decimal);
temp.append(decimal);
}
return sb.toString();
}
public static String randomString(final int length) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 20; i++) {
char c = chars[random.nextInt(chars.length)];
sb.append(c);
}
return sb.toString();
}
public static long longForName(String name) {
long l = 0L;
for (int i = 0; i < name.length() && i < 12; i++) {
char c = name.charAt(i);
l *= 37L;
if (c >= 'A' && c <= 'Z') {
l += (1 + c) - 65;
} else if (c >= 'a' && c <= 'z') {
l += (1 + c) - 97;
} else if (c >= '0' && c <= '9') {
l += (27 + c) - 48;
}
}
while (l % 37L == 0L && l != 0L) {
l /= 37L;
}
return l;
}
public static String nameForLong(long name) {
try {
if (name <= 0L || name >= 0x5b5b57f8a98a5dd1L) {
return "invalid_name";
}
if (name % 37L == 0L) {
return "invalid_name";
}
int i = 0;
char ac[] = new char[12];
while (name != 0L) {
long l1 = name;
name /= 37L;
ac[11 - i++] = chars[(int) (l1 - name * 37L)];
}
return new String(ac, 12 - i, i);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String fixName(String name) {
if (name.length() > 0) {
char ac[] = name.toCharArray();
for (int j = 0; j < ac.length; j++)
if (ac[j] == '_') {
ac[j] = ' ';
if (j + 1 < ac.length && ac[j + 1] >= 'a' && ac[j + 1] <= 'z') {
ac[j + 1] = (char) ((ac[j + 1] + 65) - 97);
}
}
if (ac[0] >= 'a' && ac[0] <= 'z') {
ac[0] = (char) ((ac[0] + 65) - 97);
}
return new String(ac);
} else {
return name;
}
}
}
@@ -0,0 +1,55 @@
package org.parabot.api.misc;
public class Version implements Comparable<Version> {
private String version;
public Version(String version) {
if (version == null) {
throw new IllegalArgumentException("Version can not be null");
}
if (!version.matches("[0-9]+(\\.[0-9]+)*") && !version.matches("[0-9]+(\\.[0-9]+)*-RC-([0-9]+)")) {
throw new IllegalArgumentException("Invalid version format");
}
this.version = version;
}
public final String get() {
return this.version;
}
public boolean isNightly() {
return this.version.contains("RC");
}
@Override
public int compareTo(Version that) {
if (that == null) {
return 1;
}
String[] thisParts = this.get().split("\\.");
String[] thatParts = that.get().split("\\.");
int length = Math.max(thisParts.length, thatParts.length);
for (int i = 0; i < length; i++) {
int thisPart = i < thisParts.length ?
Integer.parseInt(thisParts[i]) : 0;
int thatPart = i < thatParts.length ?
Integer.parseInt(thatParts[i]) : 0;
if (thisPart < thatPart) {
return -1;
}
if (thisPart > thatPart) {
return 1;
}
}
return 0;
}
@Override
public boolean equals(Object that) {
return this == that || that != null && this.getClass() == that.getClass() && this.compareTo((Version) that) == 0;
}
}
@@ -0,0 +1,113 @@
package org.parabot.api.notifications;
import org.parabot.api.notifications.types.MacNotificationType;
import org.parabot.api.notifications.types.NotificationType;
import org.parabot.api.notifications.types.PushBulletNotificationType;
import java.util.ArrayList;
import java.util.Iterator;
/**
* @author JKetelaar
*/
public class NotificationManager {
private static NotificationManager context;
private ArrayList<NotificationType> notificationTypes;
private ArrayList<NotificationType> enabledTypes;
public NotificationManager() {
this.notificationTypes = new ArrayList<>();
this.enabledTypes = new ArrayList<>();
this.fillNotificationTypes();
}
public ArrayList<NotificationType> getNotificationTypes() {
return notificationTypes;
}
public void addNotificationType(NotificationType type) {
this.notificationTypes.add(type);
}
private void fillNotificationTypes() {
this.notificationTypes.add(new MacNotificationType());
this.notificationTypes.add(new PushBulletNotificationType());
}
public void enableNotificationType(NotificationType type) {
this.enabledTypes.add(type);
type.enable();
}
public void disableNotificationType(NotificationType type) {
Iterator iterator = this.enabledTypes.iterator();
while(iterator.hasNext()){
NotificationType t = (NotificationType) iterator.next();
if (t.getName().equalsIgnoreCase(type.getName())){
iterator.remove();
break;
}
}
}
public void sendNotification(String message) {
for (NotificationType notificationType : this.enabledTypes) {
notificationType.notify(message);
}
}
public void sendNotification(String header, String message) {
for (NotificationType notificationType : this.enabledTypes) {
notificationType.notify(header, message);
}
}
public void sendNotification(String title, String header, String message) {
for (NotificationType notificationType : this.enabledTypes) {
notificationType.notify(title, header, message);
}
}
public ArrayList<NotificationType> getEnabledTypes() {
return enabledTypes;
}
public ArrayList<NotificationType> getAvailableNotificationTypes() {
ArrayList<NotificationType> types = new ArrayList<>();
for (NotificationType notificationType : this.notificationTypes) {
boolean inAdded = false;
for (NotificationType enabledType : this.enabledTypes) {
if (enabledType.getName().equalsIgnoreCase(notificationType.getName())) {
inAdded = true;
}
}
if (!inAdded) {
types.add(notificationType);
}
}
return types;
}
public NotificationType getNotificationType(String name) {
for (NotificationType notificationType : this.notificationTypes) {
if (notificationType.getName().equalsIgnoreCase(name)) {
return notificationType;
}
}
return null;
}
public static NotificationManager getContext() {
if (context == null) {
context = new NotificationManager();
}
return context;
}
}
@@ -0,0 +1,43 @@
package org.parabot.api.notifications.types;
import org.parabot.api.misc.OperatingSystem;
import java.io.IOException;
/**
* @author JKetelaar
*/
public class MacNotificationType extends NotificationType {
public MacNotificationType() {
super("Mac");
}
@Override
public boolean isAvailable() {
return OperatingSystem.getOS().equals(OperatingSystem.MAC);
}
@Override
public void notify(String title, String header, String message) {
final StringBuilder src = new StringBuilder();
src.append("display notification")
.append(" \"").append(message).append("\"");
if (title != null && title.length() > 0) {
src.append(" with title ").append("\"").append(title).append("\"");
}
if (header != null && header.length() > 0) {
src.append(" subtitle ").append("\"").append(header).append("\"");
}
src.append(" sound name \"Ping\" ");
final Runtime rt = Runtime.getRuntime();
final String[] cmd = new String[]{"/usr/bin/osascript", "-e", src.toString()};
try {
rt.exec(cmd);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,33 @@
package org.parabot.api.notifications.types;
import org.parabot.api.Configuration;
/**
* @author JKetelaar
*/
public abstract class NotificationType {
private String name;
public NotificationType(String name) {
this.name = name;
}
public abstract boolean isAvailable();
public abstract void notify(String title, String header, String message);
public void notify(String header, String message){
notify(Configuration.BOT_TITLE, header, message);
}
public void notify(String message){
notify("Notification", message);
}
public String getName() {
return name;
}
public void enable(){}
}
@@ -0,0 +1,55 @@
package org.parabot.api.notifications.types;
import org.parabot.api.io.libraries.Environment;
import org.parabot.api.io.libraries.jpushbullet.JPushBullet;
import org.parabot.api.notifications.types.pushbullet.PushBulletController;
import javax.swing.*;
/**
* @author JKetelaar
*/
public class PushBulletNotificationType extends NotificationType {
private boolean enabled = false;
public PushBulletNotificationType() {
super("PushBullet");
}
@Override
public boolean isAvailable() {
double version = 1.0;
try {
version = Double.parseDouble(System.getProperty("java.specification.version"));
} catch (NumberFormatException ignored) {
}
return version >= 1.8;
}
@Override
public void enable() {
final String message = "Please insert your PushBullet API key, so we could send notifications.";
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
String s = JOptionPane.showInputDialog(null, message, "PushBullet API key", JOptionPane.QUESTION_MESSAGE);
if (s != null) {
Environment.loadLibrary(new JPushBullet());
enabled = PushBulletController.pushNote("Parabot", "PushBullets notifications have been enabled for Parabot", s);
}
}
});
}
@Override
public void notify(String title, String header, String message) {
if (this.enabled) {
PushBulletController.pushNote(title, message);
}
}
}
@@ -0,0 +1,52 @@
package org.parabot.api.notifications.types.pushbullet;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author JKetelaar
*/
public class PushBulletController {
private static Object pushBulletInstance;
public static void setPushBulletInstance(String key){
ClassLoader classLoader = PushBulletController.class.getClassLoader();
try {
PushBulletController.pushBulletInstance = classLoader.loadClass("com.github.sheigutn.pushbullet.Pushbullet").getConstructors()[0].newInstance(key);
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
e.printStackTrace();
}
}
public static Object getPushBulletInstance(String key){
PushBulletController.setPushBulletInstance(key);
return PushBulletController.pushBulletInstance;
}
public static boolean pushNote(String title, String message, String key){
PushBulletController.setPushBulletInstance(key);
return PushBulletController.pushNote(title, message);
}
public static boolean pushNote(String title, String message){
Class[] cArg = new Class[2];
cArg[0] = String.class;
cArg[1] = String.class;
if (PushBulletController.pushBulletInstance != null){
try {
Method method = PushBulletController.pushBulletInstance.getClass().getMethod("pushNote", cArg);
method.setAccessible(true);
method.invoke(PushBulletController.pushBulletInstance, title, message);
return true;
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
return false;
}
}
return false;
}
}
@@ -0,0 +1,94 @@
package org.parabot.api.output;
/**
* @author Fryslan
*/
public class Logger {
public enum LoggerColor {
RESET("\u001B[0m"),
BLACK("\u001B[30m"),
WHITE("\u001B[37m"),
RED("\u001B[31m"),
GREEN("\u001B[32m"),
YELLOW("\u001B[33m"),
BLUE("\u001B[34m"),
PURPLE("\u001B[35m"),
CYAN("\u001B[36m");
private final String ansi;
LoggerColor(String ansi) {
this.ansi = ansi;
}
public String getAnsi() {
return ansi;
}
}
/**
* Prints Error data in Red.
*
* @param tag Reference to the location , I.E Core, UserInterface.
* @param data Error data.
*/
public static void error(String tag, String data) {
System.out.println(LoggerColor.RED.getAnsi() + "[ERROR] : " + tag + " - " + data + LoggerColor.RESET.getAnsi());
}
/**
* Prints Error data in Red.
*
* @param tag Reference to the location , I.E Core, UserInterface.
* @param data Error data.
* @param throwable Error or Exception.
*/
public static void error(String tag, String data, Throwable throwable) {
System.out.println(LoggerColor.RED.getAnsi() + "[ERROR] : " + tag + " - " + data);
throwable.printStackTrace();
System.out.println(LoggerColor.RESET.getAnsi());
}
/**
* Prints Information data in Blue.
*
* @param tag Reference to the location , I.E Core, UserInterface.
* @param data Information data.
*/
public static void info(String tag, String data) {
System.out.println(LoggerColor.BLUE.getAnsi() + "[INFO] : " + tag + " - " + data + LoggerColor.RESET.getAnsi());
}
/**
* Prints Warning data in Yellow.
*
* @param tag Reference to the location , I.E Core, UserInterface.
* @param data Warning data.
*/
public static void warning(String tag, String data) {
System.out.println(LoggerColor.YELLOW.getAnsi() + "[WARNING] : " + tag + " - " + data + LoggerColor.RESET.getAnsi());
}
/**
* Prints Debug data in Green, if debugging is enabled.
*
* @param tag Reference to the location , I.E Core, UserInterface.
* @param data Debug data.
*/
public static void debug(String tag, String data) {
System.out.println(LoggerColor.GREEN.getAnsi() + "[DEBUG] : " + tag + " - " + data + LoggerColor.RESET.getAnsi());
}
/**
* @param tag Reference to the location , I.E Core, UserInterface.
* @param data Data to Print.
* @param color Color to print the the data in.
* @param header Reference to the reason this message is printed I.E Warning, Debug.
*/
public static void custom(String tag, String data, LoggerColor color, String header) {
System.out.println(color.getAnsi() + "[" + header.toUpperCase() + "] : " + tag + " - " + data + LoggerColor.RESET.getAnsi());
}
}
@@ -0,0 +1,10 @@
package org.parabot.api.output;
/**
* @author JKetelaar
*/
public class Verboser {
public static void verbose(String s) {
System.out.println(s);
}
}
@@ -0,0 +1,142 @@
package org.parabot.api.ui;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import org.parabot.api.io.ProgressListener;
import org.parabot.api.io.WebUtil;
import org.parabot.api.output.Verboser;
import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.io.File;
import java.io.IOException;
import java.net.URL;
/**
* If a JavaFX program runs as an "Application" it can only be launched once due to
* how the UI threadding works. To solve this, JavaFX should be used by embedded the FX content inside an FXPanel,
* which itself should just fill the content of a empty JFrame.
*
* @author Shadowrs
*/
public abstract class JavaFxUtil {
private JFrame frame;
private JFXPanel jfxp;
private JavaFxUtil instance;
private final URL end;
private final File target;
private final Class<?> controller;
private final ProgressListener listener;
/**
* Constructor to use when stylesheet.fxml is in the Parabot Jar
*
* @param fxmlSheet Location to .fxml such as "/storage/ui/notifications.fxml"
*/
public JavaFxUtil(final URL fxmlSheet, final Class<?> controller) {
this.end = fxmlSheet;
this.target = null;
this.listener = null;
this.controller = controller;
launchJFX();
}
/**
* Constructor to use when stylesheet.fxml requires downloading from a remote target.
*
* @param endpoint
* @param target
* @param listener
* @param controller
*/
public JavaFxUtil(URL endpoint, final File target, final ProgressListener listener, final Class<?> controller) {
this.end = endpoint;
this.target = target;
this.listener = listener;
this.controller = controller;
if (!target.exists() || !target.canRead()) {
WebUtil.downloadFile(end, target, listener);
}
Verboser.verbose("ui from " + end);
launchJFX();
}
/**
* Kick off the GUI by creating a JFrame on the Swing Thread, then load the JavaFX on the Platform Thread
*/
private void launchJFX() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createJFrame();
Platform.setImplicitExit(false);
Platform.runLater(new Runnable() {
@Override
public void run() {
addJavaFX();
}
});
}
});
}
/**
* Create the JFrame and attach the window listener
*/
private void createJFrame() {
Verboser.verbose("Creating JFrame for JavaFXPanel");
if (getFrame() != null) {
System.err.println("frame exists");
return;
}
frame = new JFrame();
jfxp = new JFXPanel();
getFrame().add(jfxp);
getFrame().setSize(230, 300);
getFrame().setLocationRelativeTo(null);
getFrame().setVisible(true);
getFrame().setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
getFrame().addWindowListener(getWindowAdapter());
Verboser.verbose("frame created: " + getFrame());
}
protected abstract WindowAdapter getWindowAdapter();
/**
* Add the JavaFX based on the controller and stylesheet to the Scene of the JavaFxPanel
*/
private void addJavaFX() {
Verboser.verbose("panel init");
instance = this;
try {
FXMLLoader loader = new FXMLLoader(end); // ui.fxml
if (loader.getController() == null) {
loader.setController(controller.newInstance());
}
Pane page = (Pane) loader.load();
Scene scene = new Scene(page);
jfxp.setScene(scene);
getFrame().pack();
onLaunched();
Verboser.verbose("UI showing");
} catch (IOException | InstantiationException | IllegalAccessException e) {
System.err.println("Error loading ui.fxml!");
e.printStackTrace();
}
}
protected abstract void onLaunched();
public JFrame getFrame() {
return frame;
}
}
@@ -0,0 +1,66 @@
package org.parabot.api.ui;
import org.parabot.api.io.images.Images;
import org.parabot.api.misc.JavaUtil;
import org.parabot.api.misc.OperatingSystem;
import javax.swing.*;
import java.awt.*;
import java.lang.reflect.Method;
/**
* Holds various swing util based methods
*
* @author Dane, JKetelaar
*/
public class SwingUtil {
/**
* Packs, centers, and shows the frame.
*
* @param f
*/
public static void finalize(JFrame f) {
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
/**
* Adds the dock icon to mac users
*
* @param f
*/
public static void setParabotIcons(JFrame f) {
setParabotIcon(f);
}
/**
* Adds the dock icon to mac users
*
* @param f
*/
public static boolean setParabotIcon(JFrame f) {
f.setIconImage(Images.getResource("/storage/images/icon.png"));
if (OperatingSystem.getOS() == OperatingSystem.MAC) {
Image image = Images.getResource("/storage/images/icon.png");
try {
if (JavaUtil.JAVA_VERSION >= 9) {
Class<?> taskbar = Class.forName("java.awt.Taskbar");
Object application = taskbar.getMethod("getTaskbar").invoke(null);
taskbar.getMethod("setIconImage", Image.class).invoke(application, image);
} else {
Class<?> util = Class.forName("com.apple.eawt.Application");
Object application = util.getMethod("getApplication").invoke(null);
Method setDockIconImage = util.getMethod("setDockIconImage", Image.class);
setDockIconImage.invoke(application, Images.getResource("/storage/images/icon.png"));
}
} catch (Throwable t) {
return false;
}
}
return true;
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

@@ -0,0 +1 @@
application.version=${project.version}${build.version}
+20
View File
@@ -0,0 +1,20 @@
package org.parabot;
import org.junit.Assert;
import org.junit.Test;
import org.parabot.api.misc.OperatingSystem;
import org.parabot.api.ui.SwingUtil;
import javax.swing.*;
public class MacOSTest {
@Test
public void testMacOS() {
if (OperatingSystem.getOS().equals(OperatingSystem.MAC)) {
JFrame frame = new JFrame();
frame.setSize(500, 500);
Assert.assertTrue(SwingUtil.setParabotIcon(frame));
}
}
}
@@ -0,0 +1,16 @@
package org.parabot;
import org.junit.Assert;
import org.junit.Test;
import org.parabot.api.notifications.NotificationManager;
/**
* @author JKetelaar
*/
public class NotificationTest {
@Test
public void testAmount(){
NotificationManager manager = new NotificationManager();
Assert.assertTrue(manager.getNotificationTypes().size() > 0);
}
}