Majority of API downloader and Script Loader completed. Other misc fixes and UI updates.

This commit is contained in:
Ethan
2019-12-16 04:35:13 -06:00
parent e0cb723396
commit f4f212705c
33 changed files with 1729 additions and 59 deletions
+38 -23
View File
@@ -1,5 +1,10 @@
package org.rebotted;
import org.rebotted.archive.ASMClassLoader;
import org.rebotted.archive.ClassArchive;
import org.rebotted.bot.data.APIData;
import org.rebotted.bot.data.RebottedAPI;
import org.rebotted.bot.loader.APILoader;
import org.rebotted.cache.FileArchive;
import org.rebotted.cache.FileStore;
import org.rebotted.cache.FileStore.Store;
@@ -547,6 +552,9 @@ public class Client extends GameApplet {
private int anInt1285;
private String selectedItemName;
private int publicChatMode;
private ClassArchive classArchive;
private RebottedAPI api;
private APIData apiData;
public Client() {
xpAddedPos = xpCounter = expAdded = 0;
fullscreenInterfaceID = -1;
@@ -883,29 +891,28 @@ public class Client extends GameApplet {
ObjectDefinition.lowMemory = true;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
JFrame.setDefaultLookAndFeelDecorated(true);
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
toolTipManager.setLightWeightPopupEnabled(false);
UIManager.setLookAndFeel(new SubstanceDark());
nodeID = 10;
portOffset = 0;
setHighMem();
isMembers = true;
SignLink.storeid = 32;
SignLink.startpriv(InetAddress.getLocalHost());
frameMode(ScreenMode.FIXED);
instance = new Client();
botFrame = new BotFrame(instance, false);
} catch (Exception e) {
e.printStackTrace();
}
});
public static void initFrame() {
try {
nodeID = 10;
portOffset = 0;
setHighMem();
isMembers = true;
SignLink.storeid = 32;
SignLink.startpriv(InetAddress.getLocalHost());
frameMode(Client.ScreenMode.FIXED);
instance = new Client();
System.out.println("Attempting to download latest bot API.");
final APILoader apiLoader = new APILoader(instance, "https://parabot-osrs.000webhostapp.com/RebottedAPI.jar");
if(apiLoader.getApiData() == null) {
System.err.println("There was a error downloading the API!");
System.exit(0);
}
instance.apiData = apiLoader.getApiData();
instance.api = apiLoader.getRebottedAPI();
botFrame = new BotFrame(instance, false);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void setTab(int id) {
@@ -13872,6 +13879,14 @@ public class Client extends GameApplet {
this.anInt1187 += (j << 1);
}
public RebottedAPI getApi() {
return api;
}
public APIData getApiData() {
return apiData;
}
public enum ScreenMode {
FIXED, RESIZABLE, FULLSCREEN
}
+28
View File
@@ -0,0 +1,28 @@
package org.rebotted;
import org.rebotted.bot.data.RebottedAPI;
import org.rebotted.bot.loader.APILoader;
import org.rebotted.directory.DirectoryManager;
import org.rebotted.ui.themes.SubstanceDark;
import javax.swing.*;
public class Core {
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
DirectoryManager.init();
SwingUtilities.invokeLater(() -> {
try {
System.setProperty("insubstantial.checkEDT", "false"); //turns off printing Substance throwables.
System.setProperty("insubstantial.logEDT", "false"); //turns off printing Substance exceptions.
JFrame.setDefaultLookAndFeelDecorated(true);
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
toolTipManager.setLightWeightPopupEnabled(false);
UIManager.setLookAndFeel(new SubstanceDark());
Client.initFrame();
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
@@ -0,0 +1,123 @@
package org.rebotted.archive;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.tree.ClassNode;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.util.HashMap;
import java.util.Map;
public class ASMClassLoader extends ClassLoader {
private final Map<String, Class<?>> classCache;
private final ClassArchive classArchive;
public ASMClassLoader(final ClassArchive classArchive) {
this.classCache = new HashMap<>();
this.classArchive = classArchive;
}
@Override
protected URL findResource(String name) {
if (getSystemResource(name) == null) {
if (classArchive.resources.containsKey(name)) {
try {
return classArchive.resources.get(name).toURI().toURL();
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
}
} else {
return null;
}
}
return getSystemResource(name);
}
public void inheritClassLoader(ASMClassLoader classLoader) {
if (classLoader == null)
return;
inheritClassCache(classLoader);
}
private void inheritClassCache(ASMClassLoader classLoader) {
for (Map.Entry<String, Class<?>> classNodes : classLoader.classCache.entrySet()) {
if (classCache.containsKey(classNodes.getKey())) {
classCache.remove(classNodes.getKey());
classCache.put(classNodes.getKey(), classNodes.getValue());
} else {
classCache.put(classNodes.getKey(), classNodes.getValue());
}
}
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
return findClass(name);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
return getSystemClassLoader().loadClass(name);
} catch (Exception ignored) {
}
final String key = name.replace('.', '/');
if (classCache.containsKey(key)) {
return classCache.get(key);
}
final ClassNode node = classArchive.classes.get(key);
if (node != null) {
final Class<?> c = nodeToClass(node);
classCache.put(key, c);
return c;
}
return getSystemClassLoader().loadClass(name);
}
private final Class<?> nodeToClass(ClassNode node) {
if (super.findLoadedClass(node.name) != null) {
return findLoadedClass(node.name);
}
final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
node.accept(cw);
final byte[] b = cw.toByteArray();
if (classArchive.classesBytes.containsKey(node.name + ".class")) {
classArchive.classesBytes.remove(node.name + ".class");
classArchive.classesBytes.put(node.name + ".class", b);
}
return defineClass(node.name.replace('/', '.'), b, 0, b.length,
getDomain());
}
private final ProtectionDomain getDomain() {
CodeSource code = null;
try {
code = new CodeSource(new URL("http://127.0.0.1"), (Certificate[]) null);
} catch (MalformedURLException e) {
e.printStackTrace();
}
return new ProtectionDomain(code, getPermissions());
}
private final Permissions getPermissions() {
final Permissions permissions = new Permissions();
permissions.add(new AllPermission());
return permissions;
}
public ClassArchive getClassArchive() {
return classArchive;
}
}
@@ -0,0 +1,188 @@
package org.rebotted.archive;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.tree.ClassNode;
import org.rebotted.directory.DirectoryManager;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class ClassArchive {
public final ArrayList<String> classNames;
public final Map<String, ClassNode> classes;
public final Map<String, byte[]> classesBytes;
public final Map<String, byte[]> resourcesBytes;
public final Map<String, File> resources;
public ClassArchive() {
this.classNames = new ArrayList<>();
this.classes = new HashMap<>();
this.resources = new HashMap<>();
this.classesBytes = new HashMap<>();
this.resourcesBytes = new HashMap<>();
}
public void inheritClassArchive(ClassArchive classArchive) {
if (classArchive == null)
return;
inheritClassNodeCache(classArchive);
inheritClassNames(classArchive);
inheritResourceCache(classArchive);
}
private void inheritClassNodeCache(ClassArchive classArchive) {
for (Map.Entry<String, ClassNode> classNodes : classArchive.classes.entrySet()) {
if (classes.containsKey(classNodes.getKey())) {
classes.remove(classNodes.getKey());
classes.put(classNodes.getKey(), classNodes.getValue());
} else {
classes.put(classNodes.getKey(), classNodes.getValue());
}
}
}
private void inheritResourceCache(ClassArchive classArchive) {
for (Map.Entry<String, File> resource : classArchive.resources.entrySet()) {
if (resources.containsKey(resource.getKey())) {
resources.remove(resource.getKey());
resources.put(resource.getKey(), resource.getValue());
} else {
resources.put(resource.getKey(), resource.getValue());
}
}
}
private void inheritClassNames(ClassArchive classArchive) {
for (String s : classArchive.classNames) {
if (!classNames.contains(s)) {
classNames.add(s);
}
}
}
public void loadClasses(Map<String, byte[]> classesBytes) {
for (Map.Entry<String, byte[]> entry : classesBytes.entrySet()) {
final ClassReader cr = new ClassReader(entry.getValue());
final ClassNode cn = new ClassNode();
cr.accept(cn, ClassReader.EXPAND_FRAMES);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cn.accept(cw);
final byte[] b = cw.toByteArray();
classesBytes.put(cn.name + ".class", b);
if (!classNames.contains(cn.name.replace('/', '.'))) {
classNames.add(cn.name.replace('/', '.'));
}
classes.remove(cn.name);
classes.put(cn.name, cn);
}
}
public void loadResources(Map<String, byte[]> resourcesBytes) {
for (Map.Entry<String, byte[]> entry : resourcesBytes.entrySet()) {
try {
String path;
path = DirectoryManager.TEMP_PATH + File.separator;
File f1 = new File(path);
final File f = File.createTempFile("bot", ".tmp", f1);
f.deleteOnExit();
try (FileOutputStream fileOuputStream = new FileOutputStream(f)) {
fileOuputStream.write(entry.getValue());
} catch (IOException e) {
e.printStackTrace();
}
resources.put(entry.getKey(), f);
resourcesBytes.put(entry.getKey(), entry.getValue());
} catch (Exception e) {
e.printStackTrace();
}
}
}
protected void loadClass(InputStream in) throws IOException {
final ClassReader cr = new ClassReader(in);
final ClassNode cn = new ClassNode();
cr.accept(cn, ClassReader.EXPAND_FRAMES);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cn.accept(cw);
final byte[] b = cw.toByteArray();
classesBytes.put(cn.name + ".class", b);
if (!classNames.contains(cn.name.replace('/', '.'))) {
classNames.add(cn.name.replace('/', '.'));
}
classes.remove(cn.name);
classes.put(cn.name, cn);
}
public void loadResource(final String name, final InputStream in) throws IOException {
String path;
path = DirectoryManager.TEMP_PATH + File.separator;
File f1 = new File(path);
final File f = File.createTempFile("bot", ".tmp", f1);
f.deleteOnExit();
final byte[] fileContent = Files.readAllBytes(f.toPath());
try (OutputStream out = new FileOutputStream(f)) {
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
} catch (IOException e) {
}
resources.put(name, f);
resourcesBytes.put(name, fileContent);
}
public void addJar(final File file) {
try {
addJar(file.toURI().toURL());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
private void addJar(final URL url) {
try {
addJar(url.openConnection());
} catch (IOException e) {
e.printStackTrace();
}
}
private void addJar(final URLConnection connection) {
try {
final ZipInputStream zin = new ZipInputStream(connection.getInputStream());
ZipEntry e;
while ((e = zin.getNextEntry()) != null) {
if (e.isDirectory())
continue;
if (e.getName().endsWith(".class")) {
loadClass(zin);
} else {
loadResource(e.getName(), zin);
}
}
zin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public Map<String, ClassNode> getClasses() {
return classes;
}
}
@@ -0,0 +1,46 @@
package org.rebotted.bot.data;
import org.rebotted.archive.ClassArchive;
import java.io.File;
public class APIData {
private final Class<?> clazz;
private final double version;
private final File apiPath;
private final ClassLoader classLoader;
private final ClassArchive classArchive;
public APIData(Class<?> clazz, double version, File apiPath, ClassArchive classArchive, ClassLoader classLoader) {
this.clazz = clazz;
this.version = version;
this.apiPath = apiPath;
this.classArchive = classArchive;
this.classLoader = classLoader;
}
public Class<?> getMainClass() {
return clazz;
}
public Class<?> getClazz() {
return clazz;
}
public double getVersion() {
return version;
}
public File getApiPath() {
return apiPath;
}
public ClassLoader getClassLoader() {
return classLoader;
}
public ClassArchive getClassArchive() {
return classArchive;
}
}
@@ -0,0 +1,10 @@
package org.rebotted.bot.data;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface APIManifest {
double version() default 1.0;
}
@@ -0,0 +1,7 @@
package org.rebotted.bot.data;
public abstract class RebottedAPI {
public abstract boolean onStartUp();
}
@@ -0,0 +1,109 @@
package org.rebotted.bot.loader;
import jdk.internal.org.objectweb.asm.tree.AnnotationNode;
import jdk.internal.org.objectweb.asm.tree.ClassNode;
import org.rebotted.Client;
import org.rebotted.archive.ASMClassLoader;
import org.rebotted.archive.ClassArchive;
import org.rebotted.bot.data.APIData;
import org.rebotted.bot.data.APIManifest;
import org.rebotted.bot.data.RebottedAPI;
import org.rebotted.directory.DirectoryManager;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarInputStream;
import java.util.zip.ZipEntry;
public class APILoader {
private final Client client;
private RebottedAPI rebottedAPI;
private APIData apiData;
public APILoader(Client client, String link) {
this.client = client;
this.apiData = downloadAPI(link);
}
/**
* Testing the loading of the API
* @param args
*/
public static void main(String[] args) {
DirectoryManager.init();
System.out.println(APIManifest.class.getCanonicalName());
new APILoader(null, "https://parabot-osrs.000webhostapp.com/RebottedAPI.jar");
}
private APIData downloadAPI(String link) {
try {
byte[] bytes = getByteArray(link);
final Map<String, byte[]> classMap = new HashMap<>();
final Map<String, byte[]> resourceMap = new HashMap<>();
final byte[] array = new byte[1024];
final JarInputStream jarInputStream = new JarInputStream(new ByteArrayInputStream(bytes));
ZipEntry nextEntry;
while ((nextEntry = jarInputStream.getNextEntry()) != null) {
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
JarInputStream jarInputStream2 = jarInputStream;
int read;
while ((read = jarInputStream2.read(array, 0, array.length)) != -1) {
jarInputStream2 = jarInputStream;
byteArrayOutputStream.write(array, 0, read);
}
if (nextEntry.getName().endsWith(".class")) {
classMap.put(nextEntry.getName(), byteArrayOutputStream.toByteArray());
} else {
resourceMap.put(nextEntry.getName(), byteArrayOutputStream.toByteArray());
}
}
final ClassArchive classArchive = new ClassArchive();
classArchive.loadResources(resourceMap);
classArchive.loadClasses(classMap);
final ASMClassLoader classLoader = new ASMClassLoader(classArchive);
for(ClassNode node : classArchive.classes.values()) {
for(AnnotationNode annotationNode : node.visibleAnnotations) {
if(annotationNode.desc.equals("L"+APIManifest.class.getCanonicalName().replaceAll("\\.", "/")+";")) {
final Class<?> clazz = classLoader.loadClass(node.name.replaceAll("/", "."));
final APIManifest manifest = clazz.getAnnotation(APIManifest.class);
rebottedAPI = (RebottedAPI) clazz.getConstructors()[0].newInstance(client);
System.out.println("Rebotted API version "+manifest.version()+" has been loaded...");
final APIData apiData = new APIData(clazz, manifest.version(), null, classArchive, classLoader);
return apiData;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private byte[] getByteArray(String link) {
try {
final URL url = new URL(link);
final DataInputStream dataInputStream = new DataInputStream(url.openStream());
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int read;
while ((read = dataInputStream.read()) != -1) {
byteArrayOutputStream.write(read);
}
dataInputStream.close();
return byteArrayOutputStream.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public RebottedAPI getRebottedAPI() {
return rebottedAPI;
}
public APIData getApiData() {
return apiData;
}
}
@@ -0,0 +1,140 @@
package org.rebotted.directory;
import org.rebotted.directory.exceptions.InvalidDirectoryNameException;
import org.rebotted.directory.exceptions.InvalidFileNameException;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.file.InvalidPathException;
import java.util.ArrayList;
import java.util.Arrays;
public class Directory {
private final File directory;
public Directory(String path) {
this.directory = new File(path);
if (directory.exists()) {
if (!directory.isDirectory()) {
throw new InvalidPathException(path, "The specified path is not a directory.");
}
}
}
public Directory(File file) {
this(file.getAbsolutePath());
}
public boolean create() throws IOException {
return directory.mkdirs();
}
public URI toURI() {
return directory.toURI();
}
public boolean exists() {
return directory.exists();
}
public String getPath() {
return directory.getAbsolutePath();
}
public String getName() {
return directory.getName();
}
public boolean isSubDirectoryOf(Directory directory) {
return directory.getPath().startsWith(getPath()) && !directory.getPath().equals(getPath());
}
public boolean isSubDirectoryOf(String path) {
final Directory subDirectory = new Directory(path);
return isSubDirectoryOf(subDirectory);
}
public boolean isParentDirectoryOf(Directory directory) {
return directory.getPath().startsWith(getPath()) && !directory.getPath().equals(getPath());
}
public boolean isParentDirectoryOf(String name) {
final Directory directory = new Directory(name);
return isParentDirectoryOf(directory);
}
public boolean createFile(String path) throws IOException {
final File file = new File(path);
return createFile(file);
}
public boolean createFile(File file) throws IOException {
if (file.exists()) {
return true;
}
return file.createNewFile();
}
public boolean createSubDirectory(String name) throws IOException {
final Directory directory = new Directory(getPath() + File.separator + name);
if (isParentDirectoryOf(directory)) {
return directory.create();
}
return false;
}
public File[] getAllFiles() {
final ArrayList<File> files = new ArrayList<File>();
for (File file : directory.listFiles()) {
if (file.isDirectory()) {
final Directory childDirectory = new Directory(file);
files.addAll(Arrays.asList(childDirectory.getAllFiles()));
continue;
}
files.add(file);
}
return files.toArray(new File[files.size()]);
}
public File[] getFiles() {
final ArrayList<File> files = new ArrayList<File>();
for (File file : directory.listFiles()) {
if (!file.isDirectory() && file.getParent().equals(getPath())) {
files.add(file);
}
}
return files.toArray(new File[files.size()]);
}
public File getFile(String name) throws InvalidFileNameException {
for (File file : getFiles()) {
if (file.getName().equals(name)) {
return file;
}
}
throw new InvalidFileNameException(name);
}
public Directory[] getSubDirectories() {
final ArrayList<Directory> directories = new ArrayList<Directory>();
for (File file : directory.listFiles()) {
if (file.isDirectory() && file.getParent().equals(getPath())) {
directories.add(new Directory(file.getPath()));
}
}
return directories.toArray(new Directory[directories.size()]);
}
public Directory getSubDirectory(String name) throws InvalidDirectoryNameException {
for (Directory directory : getSubDirectories()) {
if (directory.getName().equals(name)) {
return directory;
}
}
throw new InvalidDirectoryNameException(name);
}
}
@@ -0,0 +1,69 @@
package org.rebotted.directory;
import org.rebotted.directory.exceptions.InvalidDirectoryNameException;
import java.io.File;
import java.io.IOException;
public class DirectoryManager {
public final static String BOT_DIRECTORY_PATH = System.getProperty("user.home") + File.separator + ".2006rebotted_file_system";
public final static String CACHE = "Cache";
public final static String SCRIPTS = "Scripts";
public final static String TEMP = "Temp";
public final static String SCREENSHOTS = "Screenshots";
public static String CACHE_PATH;
public static String SCRIPTS_PATH;
public static String TEMP_PATH;
public static String SCREENSHOTS_PATH;
private static DirectoryManager instance;
private final Directory botDirectory;
private DirectoryManager() {
botDirectory = getRootDirectory();
try {
validateSubDirectories();
} catch (InvalidDirectoryNameException | IOException e) {
e.printStackTrace();
}
}
public static void init() {
if (instance == null) {
instance = new DirectoryManager();
}
}
public static DirectoryManager getInstance() {
return instance;
}
public Directory getRootDirectory() {
final Directory directory = new Directory(BOT_DIRECTORY_PATH);
if (!directory.exists()) {
try {
if (directory.create()) {
return directory;
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
return directory;
}
private void validateSubDirectories() throws IOException, InvalidDirectoryNameException {
botDirectory.createSubDirectory(CACHE);
CACHE_PATH = botDirectory.getSubDirectory(CACHE).getPath();
botDirectory.createSubDirectory(SCRIPTS);
SCRIPTS_PATH = botDirectory.getSubDirectory(SCRIPTS).getPath();
botDirectory.getSubDirectory(CACHE).createSubDirectory(TEMP);
TEMP_PATH = botDirectory.getSubDirectory(CACHE).getSubDirectory(TEMP).getPath();
botDirectory.getSubDirectory(CACHE).createSubDirectory(SCREENSHOTS);
SCREENSHOTS_PATH = botDirectory.getSubDirectory(CACHE).getSubDirectory(SCREENSHOTS).getPath();
System.out.println("Directories validated.");
}
}
@@ -0,0 +1,11 @@
package org.rebotted.directory.exceptions;
public class InvalidDirectoryNameException extends InvalidNameException {
private static final long serialVersionUID = 6214764160978219616L;
public InvalidDirectoryNameException(String name) {
super(name + " is not a valid directory name.");
}
}
@@ -0,0 +1,11 @@
package org.rebotted.directory.exceptions;
public class InvalidFileNameException extends InvalidNameException {
private static final long serialVersionUID = -3076779825506160714L;
public InvalidFileNameException(String name) {
super(name + " is not a valid file name.");
}
}
@@ -0,0 +1,11 @@
package org.rebotted.directory.exceptions;
public class InvalidNameException extends Exception {
private static final long serialVersionUID = 4139344206095457028L;
public InvalidNameException(String exception) {
super(exception);
}
}
@@ -0,0 +1,105 @@
package org.rebotted.script;
import org.rebotted.script.scriptdata.ScriptData;
import org.rebotted.script.types.Script;
import org.rebotted.util.Condition;
public class ScriptHandler implements Runnable {
private static ScriptHandler instance;
private Thread scriptThread;
private Script script;
private ScriptData scriptData;
private volatile State scriptState = State.STOPPED;
private long breakDuration;
public ScriptHandler() {
instance = this;
}
public static ScriptHandler getInstance() {
if(instance == null)
instance = new ScriptHandler();
return instance;
}
@Override
public void run() {
try {
while (!scriptState.equals(State.STOPPED)) {
if (script == null) {
stop();
} else if (scriptState.equals(State.PAUSE)) {
Condition.sleep(500);
} else if (scriptState.equals(State.BREAKING)) {
this.script.onBreak();
Condition.sleep(breakDuration);
} else {
int timeToSleep = script.operate();
Condition.sleep(timeToSleep);
}
}
} catch (Exception e) {
stop();
}
}
public void start(Script script, ScriptData scriptData) {
if (scriptState.equals(State.RUNNING)) {
System.out.println("Why would you try to start a script with one running?");
return;
}
if (script == null) {
System.out.println("Error starting script.");
return;
}
if (scriptState.equals(State.PAUSE)) {
System.out.println("Script resumed: " + scriptData.getName());
this.scriptState = State.RUNNING;
return;
}
System.out.println("Script Started: " + scriptData.getName());
this.scriptState = State.RUNNING;
this.scriptData = scriptData;
this.script = script;
this.scriptThread = new Thread(this);
if (this.script.onStart()) {
this.scriptThread.start();
}
}
public void takeBreak(long duration) {
System.out.println(scriptData.getName() + " Breaking for: " + duration);
this.breakDuration = duration;
this.scriptState = State.BREAKING;
}
public void stop() {
System.out.println("Script Stopped: " + scriptData.getName());
this.scriptState = State.STOPPED;
this.script.onStop();
this.scriptThread.interrupt();
}
public void pause() {
if (scriptState.equals(State.RUNNING)) {
System.out.println("Script Paused: " + scriptData.getName());
this.scriptState = State.PAUSE;
} else if (scriptState.equals(State.PAUSE)) {
System.out.println("Script resumed: " + scriptData.getName());
this.scriptState = State.RUNNING;
}
}
public State getScriptState() {
return scriptState;
}
public void setScriptState(State scriptState) {
this.scriptState = scriptState;
}
public enum State {
RUNNING, BREAKING, PAUSE, STOPPED
}
}
@@ -0,0 +1,58 @@
package org.rebotted.script.loader;
import org.rebotted.bot.data.APIData;
import org.rebotted.directory.DirectoryManager;
import org.rebotted.script.scriptdata.ScriptData;
import org.rebotted.script.scriptdata.ScriptManifest;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
public class ScriptLoader {
private APIData apiData;
public ScriptLoader(APIData apiData) {
this.apiData = apiData;
}
private final List<ScriptData> scripts = new ArrayList<>();
public List<ScriptData> getScripts() {
scripts.clear();
scripts.addAll(loadLocalScripts());
return scripts;
}
private final List<ScriptData> loadLocalScripts() {
final List<ScriptData> scripts = new ArrayList<>();
try {
for (File file : DirectoryManager.getInstance().getRootDirectory().getSubDirectory(DirectoryManager.SCRIPTS).getFiles()) {
if (file.getAbsolutePath().endsWith(".jar")) {
apiData.getClassArchive().addJar(file);
try (JarInputStream inputStream = new JarInputStream(new FileInputStream(file))) {
JarEntry jarEntry;
while ((jarEntry = inputStream.getNextJarEntry()) != null) {
if (jarEntry.getName().endsWith(".class") && !jarEntry.getName().contains("$")) {
final String classPackage = jarEntry.getName().replace(".class", "");
final Class<?> clazz = apiData.getClassLoader().loadClass(classPackage.replaceAll("/", "."));
if (clazz.isAnnotationPresent(ScriptManifest.class)) {
final ScriptManifest manifest = clazz.getAnnotation(ScriptManifest.class);
final ScriptData scriptData = new ScriptData(clazz, manifest.name(), manifest.description(), manifest.version(), manifest.author(), manifest.category(), file);
scripts.add(scriptData);
}
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return scripts;
}
}
@@ -0,0 +1,56 @@
package org.rebotted.script.scriptdata;
import java.io.File;
public class ScriptData {
private final Class<?> clazz;
private final String name, author, desc;
private final double version;
private final SkillCategory skillCategory;
private final int scriptId;
private final File scriptPath;
public ScriptData(Class<?> clazz, String name, String desc, double version, String author, SkillCategory category, File scriptPath) {
this.clazz = clazz;
this.name = name;
this.desc = desc;
this.version = version;
this.author = author;
this.skillCategory = category;
this.scriptId = -1;
this.scriptPath = scriptPath;
}
public Class<?> getMainClass() {
return clazz;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
public double getVersion() {
return version;
}
public String getAuthor() {
return author;
}
public SkillCategory getSkillCategory() {
return skillCategory;
}
public int getScriptId() {
return scriptId;
}
public File getScriptPath() {
return scriptPath;
}
}
@@ -0,0 +1,21 @@
package org.rebotted.script.scriptdata;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface ScriptManifest {
String name();
String author();
String description() default "";
double version() default 1.0;
SkillCategory category() default SkillCategory.MISC;
}
@@ -0,0 +1,78 @@
package org.rebotted.script.scriptdata;
public enum SkillCategory {
AGILITY("Agility", new String[]{"Agility"}, new int[]{1}),
COMBAT("Combat", new String[]{"Combat", "Fighter", "Killer", "Kill"}, new int[]{2}),
CONSTRUCTION("Construction", new String[]{"Construction"}, new int[]{3}),
COOKING("Cooking", new String[]{"Cooking"}, new int[]{4}),
CRAFTING("Crafting", new String[]{"Crafting"}, new int[]{5}),
FARMING("Farming", new String[]{"Farming"}, new int[]{6}),
FIREMAKING("Firemaking", new String[]{"Firemaking", "FM"}, new int[]{7}),
FISHING("Fishing", new String[]{"Fishing", "Fisher"}, new int[]{8}),
FLETCHING("Fletching", new String[]{"Fletching"}, new int[]{9}),
HERBLORE("Herblore", new String[]{"Herblore"}, new int[]{11}),
HUNTER("Hunter", new String[]{"Hunter"}, new int[]{12}),
MAGIC("Magic", new String[]{"Magic"}, new int[]{13}),
MINING("Mining", new String[]{"Mining", "Ore"}, new int[]{14}),
MINI_GAMES("Mini-games", new String[]{"Mini-games"}, new int[]{15}),
PRAYER("Prayer", new String[]{"Prayer"}, new int[]{17}),
RANGED("Ranged", new String[]{"Ranged", "Range"}, new int[]{18}),
RUNECRAFTING("Runecrafting", new String[]{"Runecrafting", "Runes"}, new int[]{19}),
SLAYER("Slayer", new String[]{"Slayer"}, new int[]{20}),
SMITHING("Smithing", new String[]{"Smithing"}, new int[]{21}),
THEIVING("Thieving", new String[]{"Thieving"}, new int[]{22}),
WOODCUTTING("Woodcutting", new String[]{"Woodcutting,woodcut,chop,chopper"}, new int[]{23}),
MONEY_MAKING("Money Making", new String[]{"Money Making", "Cash"}, new int[]{16}),
MISC("Misc", new String[]{"Misc"}, new int[]{0, 24});
private String skill;
private String[] filters;
private int[] ids;
SkillCategory(String skill, String[] filters, int[] ids) {
this.skill = skill;
this.filters = filters;
this.ids = ids;
}
public static SkillCategory getCategory(int id) {
for (SkillCategory skillCategory : SkillCategory.values()) {
for (int a : skillCategory.ids) {
if (a == id) {
return skillCategory;
}
}
}
return SkillCategory.MISC;
}
public static SkillCategory detect(final String name, final String desc) {
for (SkillCategory skillCategory : SkillCategory.values()) {
for (String filter : skillCategory.filters) {
if (name.toLowerCase().contains(filter.toLowerCase()) || desc.toLowerCase().contains(filter.toLowerCase())) {
return skillCategory;
}
}
}
return SkillCategory.MISC;
}
public String getName() {
return this.skill;
}
public String[] getFiltersWord() {
return this.filters;
}
public int[] getIds() {
return ids;
}
@Override
public String toString() {
return name().charAt(0) + name().substring(1).replaceAll("_", " ").toLowerCase();
}
}
@@ -0,0 +1,11 @@
package org.rebotted.script.types;
public abstract class LoopScript extends Script {
public abstract int loop();
@Override
public final int operate() {
return loop();
}
}
@@ -0,0 +1,18 @@
package org.rebotted.script.types;
public abstract class Script {
private final long startTime = System.currentTimeMillis();
public abstract boolean onStart();
public abstract void onStop();
public abstract void onBreak();
public abstract int operate();
public final long getRuntime() {
return System.currentTimeMillis() - startTime;
}
}
@@ -0,0 +1,23 @@
package org.rebotted.script.types;
public abstract class Task {
private final int priority;
public Task(int priority) {
this.priority = priority;
}
public Task() {
this.priority = 0;
}
public abstract boolean activate();
public abstract void execute();
public final int priority() {
return priority;
}
}
@@ -0,0 +1,54 @@
package org.rebotted.script.types;
import org.rebotted.script.ScriptHandler;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
public abstract class TaskScript extends Script implements Comparator<Task> {
private final List<Task> tasks = new LinkedList<>();
private synchronized Task get() {
try {
for (Task action : tasks) {
if (action != null && action.activate()) {
return action;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public final void provide(List<Task> tasks) {
if (tasks.size() > 0) {
for (Task task : tasks) {
this.tasks.add(task);
}
}
}
@Override
public final int operate() {
try {
final Task action = get();
if (action != null) {
action.execute();
return 200;
}
} catch (Exception e) {
ScriptHandler.getInstance().stop();
e.printStackTrace();
}
return 0;
}
@Override
public int compare(Task o1, Task o2) {
return o1.priority() - o2.priority();
}
}
+45 -7
View File
@@ -1,7 +1,10 @@
package org.rebotted.ui;
import org.rebotted.Client;
import org.rebotted.Configuration;
import org.rebotted.GameApplet;
import org.rebotted.script.ScriptHandler;
import org.rebotted.script.types.Script;
import javax.swing.*;
import java.awt.*;
@@ -12,16 +15,19 @@ public final class BotFrame extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
private final BotMenuBar botMenuBar;
public BotFrame(GameApplet applet, boolean resizable) {
private static BotMenuBar botMenuBar;
private final Client client;
private final ScriptUI scriptUI;
public BotFrame(Client client, boolean resizable) {
this.client = client;
final GameApplet applet = client;
setTitle(Configuration.CLIENT_NAME);
setResizable(resizable);
botMenuBar = new BotMenuBar(this);
BotFrame.botMenuBar = new BotMenuBar(this);
setJMenuBar(botMenuBar);
add(applet, BorderLayout.CENTER);
setMinimumSize(new Dimension(774, 559));
setSize(new Dimension(774, 559));
setMinimumSize(new Dimension(774, 567));
setSize(new Dimension(774, 567));
pack();
setLocationRelativeTo(getParent());
setLocationRelativeTo(getOwner());
@@ -29,14 +35,46 @@ public final class BotFrame extends JFrame implements ActionListener {
requestFocus();
toFront();
applet.initClientFrame(766, 536);
scriptUI = new ScriptUI(client.getApiData());
System.out.println("Client Launched.");
}
public static void setPaused() {
botMenuBar.setPausedButtons(false);
botMenuBar.setRunButtons(true);
botMenuBar.setStopButtons(true);
}
public static void setRunning() {
botMenuBar.setRunButtons(false);
botMenuBar.setPausedButtons(true);
botMenuBar.setStopButtons(true);
}
public static void setStopped() {
botMenuBar.setStopButtons(false);
botMenuBar.setPausedButtons(false);
botMenuBar.setRunButtons(true);
}
@Override
public void actionPerformed(ActionEvent e) {
switch (e.getActionCommand().toLowerCase()) {
case "run":
System.out.println("run was clicked..");
if(ScriptHandler.getInstance().getScriptState() == ScriptHandler.State.STOPPED) {
scriptUI.show();
} else if(ScriptHandler.getInstance().getScriptState() == ScriptHandler.State.PAUSE) {
ScriptHandler.getInstance().setScriptState(ScriptHandler.State.RUNNING);
setRunning();
}
break;
case "pause":
setPaused();
ScriptHandler.getInstance().pause();
break;
case "stop":
setStopped();
ScriptHandler.getInstance().stop();
break;
}
}
+22 -29
View File
@@ -8,7 +8,7 @@ import javax.swing.*;
public class BotMenuBar extends JMenuBar {
private BotFrame botUI;
private JButton startButton, pauseButton, stopButton;
private static JButton startButton, pauseButton, stopButton;
private JMenu file, scripts;
private JMenuItem run, pause, stop;
@@ -45,11 +45,11 @@ public class BotMenuBar extends JMenuBar {
file.add(exit);
/* startButton = createNewButton(new ImageIcon(Images.getResource("/storage/images/run_button.png")), "Run Script", "Run", true);
startButton = createNewButton(new ImageIcon(getClass().getResource("/images/run_button.png")), "Run Script", "Run", true);
pauseButton = createNewButton(new ImageIcon(Images.getResource("/storage/images/pause_button.png")), "Pause Script", "Pause", false);
pauseButton = createNewButton(new ImageIcon(getClass().getResource("/images/pause_button.png")), "Pause Script", "Pause", false);
stopButton = createNewButton(new ImageIcon(Images.getResource("/storage/images/stop_button.png")), "Stop Script", "Stop", false);*/
stopButton = createNewButton(new ImageIcon(getClass().getResource("/images/stop_button.png")), "Stop Script", "Stop", false);
}
@@ -77,41 +77,34 @@ public class BotMenuBar extends JMenuBar {
add(file);
add(scripts);
add(Box.createHorizontalGlue());
/*add(startButton);
add(startButton);
add(pauseButton);
add(stopButton);*/
add(stopButton);
}
public void setPausedButtons(boolean enabled) {
pause.setEnabled(enabled);
pauseButton.setEnabled(enabled);
}
public void setStopButtons(boolean enabled) {
stopButton.setEnabled(enabled);
stop.setEnabled(enabled);
}
public void setRunButtons(boolean enabled) {
run.setEnabled(enabled);
startButton.setEnabled(enabled);
}
public JMenu getFile() {
return file;
}
public JButton getStartButton() {
return startButton;
}
public JButton getPauseButton() {
return pauseButton;
}
public JButton getStopButton() {
return stopButton;
}
public JMenu getScripts() {
return scripts;
}
public JMenuItem getRun() {
return run;
}
public JMenuItem getPause() {
return pause;
}
public JMenuItem getStop() {
return stop;
}
}
@@ -0,0 +1,89 @@
package org.rebotted.ui;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import org.rebotted.script.ScriptHandler;
import org.rebotted.script.scriptdata.ScriptData;
import org.rebotted.script.scriptdata.SkillCategory;
import org.rebotted.script.types.Script;
import java.net.URL;
import java.util.ResourceBundle;
public class ScriptController implements Initializable {
@FXML
private Button startButton;
@FXML
private TableView<ScriptData> scriptTable;
@FXML
private TableColumn<ScriptData, SkillCategory> category;
@FXML
private TableColumn<ScriptData, String> scriptName;
@FXML
private TableColumn<ScriptData, String> author;
@FXML
private TableColumn<ScriptData, String> description;
@FXML
private TableColumn<ScriptData, Double> version;
public void startScript() {
if (ScriptHandler.getInstance().getScriptState() == ScriptHandler.State.PAUSE) {
ScriptHandler.getInstance().pause();
} else if (ScriptHandler.getInstance().getScriptState() == ScriptHandler.State.STOPPED) {
final ScriptData scriptData = scriptTable.getSelectionModel().getSelectedItem();
if(scriptData == null) {
System.err.println("Please select a script before pressing start!");
return;
}
startScript(scriptData);
ScriptUI.hide();
BotFrame.setRunning();
} else if (ScriptHandler.getInstance().getScriptState() == ScriptHandler.State.RUNNING) {
System.out.println("You already have a script running!");
}
}
public void searchScripts() {
}
public TableView<ScriptData> getScriptTable() {
return scriptTable;
}
@Override
public void initialize(URL location, ResourceBundle resources) {
category.setCellValueFactory(new PropertyValueFactory<>("skillCategory"));
scriptName.setCellValueFactory(new PropertyValueFactory<>("name"));
author.setCellValueFactory(new PropertyValueFactory<>("author"));
description.setCellValueFactory(new PropertyValueFactory<>("desc"));
version.setCellValueFactory(new PropertyValueFactory<>("version"));
}
private void startScript(ScriptData scriptData) {
Script script = null;
try {
script = (Script) scriptData.getMainClass().newInstance();
} catch (Exception e) {
e.printStackTrace();
}
ScriptHandler.getInstance().start(script, scriptData);
}
}
@@ -0,0 +1,74 @@
package org.rebotted.ui;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.embed.swing.JFXPanel;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import org.rebotted.bot.data.APIData;
import org.rebotted.script.loader.ScriptLoader;
import org.rebotted.script.scriptdata.ScriptData;
import javax.swing.*;
public class ScriptUI {
private static ScriptController controller;
private static JFrame frame;
private JFXPanel jfxPanel = new JFXPanel();
private ScriptLoader scriptLoader;
public ScriptUI(final APIData apiData) {
scriptLoader = new ScriptLoader(apiData);
loadUI();
}
public static ScriptController getController() {
return controller;
}
public void loadUI() {
Platform.runLater(() -> {
try {
frame = new JFrame("2006Rebotted - Script Selector");
jfxPanel = new JFXPanel();
final FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/ScriptUI.fxml"));
final Parent root = fxmlLoader.load();
final Scene scene = new Scene(root, 597, 353);
scene.getStylesheets().add(getClass().getResource("/dark.css").toExternalForm());
jfxPanel.setScene(scene);
controller = fxmlLoader.getController();
controller.getScriptTable().setItems(loadLocalScripts());
SwingUtilities.invokeLater(() -> {
frame.add(jfxPanel);
frame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
frame.pack();
frame.setResizable(false);
});
} catch (Exception e) {
}
});
}
public void show() {
controller.getScriptTable().setItems(loadLocalScripts());
frame.setVisible(true);
System.out.println("Script Selector Loaded.");
}
public static void hide() {
frame.setVisible(false);
}
private ObservableList<ScriptData> loadLocalScripts() {
final ObservableList<ScriptData> scripts = FXCollections.observableArrayList();
for (ScriptData scriptData : scriptLoader.getScripts()) {
scripts.add(scriptData);
}
return scripts;
}
}
@@ -0,0 +1,134 @@
package org.rebotted.util;
import java.nio.file.DirectoryStream.Filter;
import java.util.concurrent.Callable;
/**
* Condition An event-driven blocking utility. Frequencies are randomly adjusted
* to provide a basic antipattern.
*/
public class Condition {
/**
* The random adjustment variance, 0.85-1.50.
*/
public static final double[] VARIANCE = {.85d, 1.5d};
/**
* Blocks until the specified condition is satisfied (returns {@code true}).
* This uses a frequency of 600ms for up to 10 tries, i.e. attempting a
* maximum of 6 seconds.
*
* @param cond the condition
* @return {@code true} if the condition was satisfied, otherwise
* {@code false}
*/
public static boolean wait(final Callable<Boolean> cond) {
return wait(cond, 600, 10);
}
/**
* Blocks until the specified condition is satisfied (returns {@code true}).
* This uses the specified frequency interval and retries for up to 6
* seconds.
*
* @param cond the condition
* @param freq the polling frequency in milliseconds
* @return {@code true} if the condition was satisfied, otherwise
* {@code false}
*/
public static boolean wait(final Callable<Boolean> cond, final int freq) {
return wait(cond, freq, Math.max(2, 6000 / freq));
}
/**
* Blocks until the specified condition is satisfied (returns {@code true}).
*
* @param cond the condition
* @param freq the polling frequency in milliseconds
* @param tries the maximum number of attempts before this method returns
* {@code false}
* @return if the condition was satisfied, otherwise {@code false}
*/
public static boolean wait(final Callable<Boolean> cond, final int freq, int tries) {
tries = Math.max(1, tries + Random.nextInt(-1, 2));
for (int i = 0; i < tries; i++) {
try {
final double f = freq * Random.nextDouble(VARIANCE[0], VARIANCE[1]);
Thread.sleep(Math.max(5, (int) f));
} catch (final InterruptedException ignored) {
return false;
}
final boolean r;
try {
r = cond.call();
} catch (final Exception ignored) {
return false;
}
if (r) {
return true;
}
}
return false;
}
/**
* Sleeps the current thread.
*
* @param ms the length of time to sleep in milliseconds, which is adjusted
* by a random variance
* @return the actual amount of time slept in milliseconds, which is subject
* to system clock accuracy
*/
public static int sleep(final long ms) {
if (ms <= 0) {
Thread.yield();
return 0;
}
final long s = System.nanoTime();
try {
Thread.sleep((long) (ms * Random.nextDouble(VARIANCE[0], VARIANCE[1])));
} catch (final InterruptedException ignored) {
}
return (int) ((System.nanoTime() - s) / 1000000L);
}
/**
* Sleeps the current thread for a duration that is 10 times the value of
* {@link Random#getDelay()}.
*/
public static void sleep() {
sleep(Random.getDelay() * 10);
}
/**
* Check A simplified conditional checking task.
*/
public static abstract class Check implements Callable<Boolean>, Filter<Void> {
/**
* {@inheritDoc}
*/
@Override
public Boolean call() {
return poll();
}
/**
* {@inheritDoc}
*/
@Override
public boolean accept(final Void v) {
return poll();
}
/**
* Checks if a condition has been met.
*
* @return {@code true} if the condition has been met, otherwise
* {@code false} to try again later.
*/
public abstract boolean poll();
}
}
@@ -0,0 +1,69 @@
package org.rebotted.util;
import java.security.SecureRandom;
public class Random {
private static final double[] pd;
private static final ThreadLocal<java.util.Random> random = new ThreadLocal<java.util.Random>() {
@Override
protected java.util.Random initialValue() {
java.util.Random r;
try {
r = SecureRandom.getInstance("SHA1PRNG", "SUN");
} catch (Exception ignored) {
r = new java.util.Random();
}
r.setSeed(r.nextLong());
return r;
}
};
static {
pd = new double[2];
final double[] e = {3d, 45d + random.get().nextInt(11), 12d + random.get().nextGaussian()};
final double[] x = {Runtime.getRuntime().availableProcessors(), Runtime.getRuntime().maxMemory() >> 30};
pd[0] = 4d * Math.log(Math.sin(((Math.PI / x[0]) * Math.PI + 1d) / 4d)) / Math.PI
+ 2d * Math.PI * (Math.PI / x[0]) / 3d - 4d * Math.log(Math.sin(0.25d)) / Math.PI;
pd[0] = e[0] * Math.exp(Math.pow(pd[0], 0.75d)) + e[1];
pd[1] = e[2] * Math.exp(1d / Math.cosh(x[1]));
}
public static int getDelay() {
return (int) ((-1 + 2 * nextDouble()) * pd[1] + pd[0]);
}
public static int hicks(final int a) {
return 105 * (int) (Math.log(a * 2) / 0.6931471805599453d);
}
public static boolean nextBoolean() {
return random.get().nextBoolean();
}
public static int nextInt(final int min, final int max) {
final int a = min < max ? min : max, b = max > min ? max : min;
return a + (b == a ? 0 : random.get().nextInt(b - a));
}
public static double nextDouble(final double min, final double max) {
final double a = min < max ? min : max, b = max > min ? max : min;
return a + random.get().nextDouble() * (b - a);
}
public static double nextDouble() {
return random.get().nextDouble();
}
public static double nextGaussian() {
return random.get().nextGaussian();
}
public static int nextGaussian(final int min, final int max, final double sd) {
return nextGaussian(min, max, (max - min) / 2, sd);
}
public static int nextGaussian(final int min, final int max, final int mean, final double sd) {
return min + Math.abs(((int) (nextGaussian() * sd + mean)) % (max - min));
}
}
+25
View File
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane xmlns:fx="http://javafx.com/fxml/1" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" prefHeight="353.0" prefWidth="605.0" xmlns="http://javafx.com/javafx/11.0.1"
fx:controller="org.rebotted.ui.ScriptController">
<children>
<TableView fx:id="scriptTable" prefHeight="325.0" prefWidth="605.0">
<columns>
<TableColumn fx:id="category" prefWidth="84.0" text="Category"/>
<TableColumn fx:id="scriptName" prefWidth="107.0" text="Script"/>
<TableColumn fx:id="version" prefWidth="62.0" text="Version"/>
<TableColumn fx:id="description" prefWidth="250.0" text="Description"/>
<TableColumn fx:id="author" prefWidth="100.0" text="Author"/>
</columns>
</TableView>
<Button fx:id="startButton" layoutX="528.0" layoutY="327.0" mnemonicParsing="false" onAction="#startScript"
prefHeight="25.0" prefWidth="73.0" text="Start"/>
<ComboBox layoutX="5.0" layoutY="327.0" prefHeight="25.0" prefWidth="251.0" promptText="Accounts..."/>
<TextField layoutX="263.0" layoutY="327.0" onAction="#searchScripts" prefHeight="25.0" prefWidth="259.0"
promptText="Search scripts..."/>
</children>
</AnchorPane>
+56
View File
@@ -0,0 +1,56 @@
/*
* This is an adjustment of the original modena.css for a consistent dark theme.
* Original modena.css here: https://gist.github.com/maxd/63691840fc372f22f470.
*/
/* Redefine base colors */
.root {
-fx-base: rgb(50, 50, 50);
-fx-background: rgb(50, 50, 50);
/* make controls (buttons, thumb, etc.) slightly lighter */
-fx-color: derive(-fx-base, 10%);
/* text fields and table rows background */
-fx-control-inner-background: rgb(20, 20, 20);
/* version of -fx-control-inner-background for alternative rows */
-fx-control-inner-background-alt: derive(-fx-control-inner-background, 2.5%);
/* text colors depending on background's brightness */
-fx-light-text-color: rgb(220, 220, 220);
-fx-mid-text-color: rgb(100, 100, 100);
-fx-dark-text-color: rgb(20, 20, 20);
/* A bright blue for highlighting/accenting objects. For example: selected
* text; selected items in menus, lists, trees, and tables; progress bars */
-fx-accent: rgb(0, 80, 100);
/* color of non-focused yet selected elements */
-fx-selection-bar-non-focused: rgb(50, 50, 50);
}
/* Fix derived prompt color for text fields */
.text-input {
-fx-prompt-text-fill: derive(-fx-control-inner-background, +50%);
}
/* Keep prompt invisible when focused (above color fix overrides it) */
.text-input:focused {
-fx-prompt-text-fill: transparent;
}
/* Fix scroll bar buttons arrows colors */
.scroll-bar > .increment-button > .increment-arrow,
.scroll-bar > .decrement-button > .decrement-arrow {
-fx-background-color: -fx-mark-highlight-color, rgb(220, 220, 220);
}
.scroll-bar > .increment-button:hover > .increment-arrow,
.scroll-bar > .decrement-button:hover > .decrement-arrow {
-fx-background-color: -fx-mark-highlight-color, rgb(240, 240, 240);
}
.scroll-bar > .increment-button:pressed > .increment-arrow,
.scroll-bar > .decrement-button:pressed > .decrement-arrow {
-fx-background-color: -fx-mark-highlight-color, rgb(255, 255, 255);
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 543 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 681 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B