mirror of
https://github.com/lax1dude/eaglercraft-motd-1.8.git
synced 2024-11-08 07:16:05 -08:00
more progress on bungee impl
This commit is contained in:
parent
ee06da5fb6
commit
66a67bd79a
|
@ -1,11 +1,24 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.plugin.eaglermotd;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
|
||||
|
@ -27,12 +40,225 @@ public class EaglerMOTDConfiguration {
|
|||
public final Map<String,List<MessagePoolEntry>> messages = new HashMap();
|
||||
public final Map<String,MessagePool> messagePools = new HashMap();
|
||||
public final Map<String,JsonObject> framesCache = new HashMap();
|
||||
public final Map<String,QueryType> queryTypes = new HashMap();
|
||||
public int close_socket_after = 1200;
|
||||
public int max_sockets_per_ip = 10;
|
||||
public int max_total_sockets = 256;
|
||||
|
||||
public void reload(File pluginDir) {
|
||||
public void reload(File pluginDir, EaglerMOTDLoggerAdapter logger, Collection<String> allowedListeners) throws IOException {
|
||||
messages.clear();
|
||||
messagePools.clear();
|
||||
framesCache.clear();
|
||||
queryTypes.clear();
|
||||
|
||||
BitmapFile.bitmapCache.clear();
|
||||
QueryCache.flush();
|
||||
|
||||
byte[] damn = new byte[4096];
|
||||
int i;
|
||||
|
||||
File msgs = new File(pluginDir, "messages.json");
|
||||
|
||||
if(!msgs.isFile()) {
|
||||
try(OutputStream fileNew = new FileOutputStream(msgs)) {
|
||||
try(InputStream fileDefault = EaglerMOTDConfiguration.class.getResourceAsStream("/net/lax1dude/eaglercraft/v1_8/plugin/eaglermotd/default_messages.json")) {
|
||||
while((i = fileDefault.read(damn)) != -1) {
|
||||
fileNew.write(damn, 0, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
File f2 = new File(pluginDir, "frames.json");
|
||||
if(!f2.isFile()) {
|
||||
try(OutputStream fileNew = new FileOutputStream(f2)) {
|
||||
try(InputStream fileDefault = EaglerMOTDConfiguration.class.getResourceAsStream("/net/lax1dude/eaglercraft/v1_8/plugin/eaglermotd/default_frames.json")) {
|
||||
while((i = fileDefault.read(damn)) != -1) {
|
||||
fileNew.write(damn, 0, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
f2 = new File(pluginDir, "queries.json");
|
||||
if(!f2.isFile()) {
|
||||
try(OutputStream fileNew = new FileOutputStream(f2)) {
|
||||
try(InputStream fileDefault = EaglerMOTDConfiguration.class.getResourceAsStream("/net/lax1dude/eaglercraft/v1_8/plugin/eaglermotd/default_queries.json")) {
|
||||
while((i = fileDefault.read(damn)) != -1) {
|
||||
fileNew.write(damn, 0, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
f2 = new File("server-animation.png");
|
||||
if(!f2.isFile()) {
|
||||
try(OutputStream fileNew = new FileOutputStream(f2)) {
|
||||
try(InputStream fileDefault = EaglerMOTDConfiguration.class.getResourceAsStream("/net/lax1dude/eaglercraft/v1_8/plugin/eaglermotd/server-icons-test.png")) {
|
||||
while((i = fileDefault.read(damn)) != -1) {
|
||||
fileNew.write(damn, 0, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!msgs.exists()) {
|
||||
throw new NullPointerException("messages.json is missing and could not be created");
|
||||
}
|
||||
|
||||
ByteArrayOutputStream bao;
|
||||
try(InputStream is = new FileInputStream(msgs)) {
|
||||
bao = new ByteArrayOutputStream(is.available());
|
||||
while((i = is.read(damn)) != -1) {
|
||||
bao.write(damn, 0, i);
|
||||
}
|
||||
}
|
||||
|
||||
JsonObject msgsObj = JsonParser.parseString(new String(bao.toByteArray(), StandardCharsets.UTF_8)).getAsJsonObject();
|
||||
framesCache.put("messages", msgsObj);
|
||||
close_socket_after = optInt(msgsObj.get("close_socket_after"), 1200);
|
||||
max_sockets_per_ip = optInt(msgsObj.get("max_sockets_per_ip"), 10);
|
||||
max_total_sockets = optInt(msgsObj.get("max_total_sockets"), 256);
|
||||
msgsObj = msgsObj.get("messages").getAsJsonObject();
|
||||
|
||||
for(String ss : msgsObj.keySet()) {
|
||||
try {
|
||||
List<MessagePoolEntry> poolEntries = new LinkedList();
|
||||
JsonArray arr = msgsObj.get(ss).getAsJsonArray();
|
||||
for(int j = 0, l = arr.size(); j < l; ++j) {
|
||||
JsonObject entry = arr.get(j).getAsJsonObject();
|
||||
List<JsonObject> frames = new LinkedList();
|
||||
JsonArray framesJSON = entry.get("frames").getAsJsonArray();
|
||||
for(int k = 0, l2 = framesJSON.size(); k < l2; ++k) {
|
||||
JsonObject frame = resolveFrame(framesJSON.get(k).getAsString(), pluginDir, logger);
|
||||
if(frame != null) {
|
||||
frames.add(frame);
|
||||
}
|
||||
}
|
||||
if(frames.size() > 0) {
|
||||
poolEntries.add(new MessagePoolEntry(optInt(entry.get("interval"), 0), optInt(entry.get("timeout"), 500),
|
||||
optBoolean(entry.get("random"), false), optBoolean(entry.get("shuffle"), false), optFloat(entry.get("weight"), 1.0f),
|
||||
optString(entry.get("next"), null), frames, optString(entry.get("name"), null)));
|
||||
}else {
|
||||
logger.error("Message '" + ss + "' has no frames!");
|
||||
}
|
||||
}
|
||||
if(poolEntries.size() > 0) {
|
||||
List<MessagePoolEntry> existingList = messages.get(ss);
|
||||
if(existingList == null) {
|
||||
existingList = poolEntries;
|
||||
messages.put(ss, existingList);
|
||||
}else {
|
||||
existingList.addAll(poolEntries);
|
||||
}
|
||||
}
|
||||
}catch(Throwable t) {
|
||||
logger.error("Could not parse messages for '" + ss + "' " + t.toString());
|
||||
}
|
||||
}
|
||||
|
||||
String flag = null;
|
||||
for(String s : messages.keySet()) {
|
||||
if(!s.equals("all")) {
|
||||
boolean flag2 = false;
|
||||
for(String l : allowedListeners) {
|
||||
if(s.equals(l)) {
|
||||
flag2 = true;
|
||||
}
|
||||
}
|
||||
if(!flag2) {
|
||||
flag = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(flag != null) {
|
||||
logger.error("Listener '" + flag + "' does not exist!");
|
||||
String hostsString = "";
|
||||
for(String l : allowedListeners) {
|
||||
if(hostsString.length() > 0) {
|
||||
hostsString += " ";
|
||||
}
|
||||
hostsString += l;
|
||||
}
|
||||
logger.error("Listeners configured: " + hostsString);
|
||||
}
|
||||
|
||||
for(String l : allowedListeners) {
|
||||
MessagePool m = new MessagePool(l);
|
||||
List<MessagePoolEntry> e = messages.get("all");
|
||||
if(e != null) {
|
||||
m.messagePool.addAll(e);
|
||||
}
|
||||
e = messages.get(l);
|
||||
if(e != null) {
|
||||
m.messagePool.addAll(e);
|
||||
}
|
||||
if(m.messagePool.size() > 0) {
|
||||
logger.info("Loaded " + m.messagePool.size() + " messages for " + l);
|
||||
messagePools.put(l, m);
|
||||
}
|
||||
}
|
||||
|
||||
msgs = new File(pluginDir, "queries.json");
|
||||
if(msgs.exists()) {
|
||||
try {
|
||||
try(InputStream is = new FileInputStream(msgs)) {
|
||||
bao = new ByteArrayOutputStream(is.available());
|
||||
while((i = is.read(damn)) != -1) {
|
||||
bao.write(damn, 0, i);
|
||||
}
|
||||
}
|
||||
JsonObject queriesObject = JsonParser.parseString(new String(bao.toByteArray(), StandardCharsets.UTF_8)).getAsJsonObject();
|
||||
JsonObject queriesQueriesObject = queriesObject.get("queries").getAsJsonObject();
|
||||
for(String s : queriesQueriesObject.keySet()) {
|
||||
queryTypes.put(s.toLowerCase(), new QueryType(s, queriesQueriesObject.get(s).getAsJsonObject()));
|
||||
}
|
||||
if(queryTypes.size() > 0) {
|
||||
logger.info("Loaded " + queryTypes.size() + " query types");
|
||||
}
|
||||
}catch(Throwable t) {
|
||||
logger.error("Queries were not loaded: " + t.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public JsonObject resolveFrame(String s, File pluginDir, EaglerMOTDLoggerAdapter logger) throws IOException {
|
||||
int i = s.indexOf('.');
|
||||
if(i == -1) {
|
||||
logger.error("Frame '" + s + "' cannot be found! (it does not specify a filename)");
|
||||
return null;
|
||||
}
|
||||
String f = s.substring(0, i);
|
||||
JsonObject fc = framesCache.get(f);
|
||||
if(fc == null) {
|
||||
File ff = new File(pluginDir, f + ".json");
|
||||
if(!ff.exists()) {
|
||||
logger.error("File '" + f + ".json' cannot be found!");
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
ByteArrayOutputStream bao;
|
||||
try(InputStream is = new FileInputStream(ff)) {
|
||||
bao = new ByteArrayOutputStream(is.available());
|
||||
byte[] damn = new byte[4096];
|
||||
int j;
|
||||
while((j = is.read(damn)) != -1) {
|
||||
bao.write(damn, 0, j);
|
||||
}
|
||||
}
|
||||
fc = JsonParser.parseString(new String(bao.toByteArray(), StandardCharsets.UTF_8)).getAsJsonObject();
|
||||
framesCache.put(f, fc);
|
||||
}catch(Throwable t) {
|
||||
logger.error("File '" + f + ".json' could not be loaded: " + t.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
f = s.substring(i + 1).trim();
|
||||
if(fc.has(f)) {
|
||||
return fc.get(f).getAsJsonObject();
|
||||
}else {
|
||||
logger.error("Frame '" + s + "' cannot be found!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static final char COLOR_CHAR = '\u00A7';
|
||||
|
@ -49,4 +275,39 @@ public class EaglerMOTDConfiguration {
|
|||
return new String(b);
|
||||
}
|
||||
|
||||
private static int optInt(JsonElement el, int def) {
|
||||
if(el != null && !el.isJsonPrimitive()) {
|
||||
JsonPrimitive prim = el.getAsJsonPrimitive();
|
||||
return prim.isNumber() ? prim.getAsInt() : def;
|
||||
}else {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean optBoolean(JsonElement el, boolean def) {
|
||||
if(el != null && !el.isJsonPrimitive()) {
|
||||
JsonPrimitive prim = el.getAsJsonPrimitive();
|
||||
return prim.isBoolean() ? prim.getAsBoolean() : def;
|
||||
}else {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
private static float optFloat(JsonElement el, float def) {
|
||||
if(el != null && !el.isJsonPrimitive()) {
|
||||
JsonPrimitive prim = el.getAsJsonPrimitive();
|
||||
return prim.isNumber() ? prim.getAsFloat() : def;
|
||||
}else {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
private static String optString(JsonElement el, String def) {
|
||||
if(el != null && !el.isJsonPrimitive()) {
|
||||
JsonPrimitive prim = el.getAsJsonPrimitive();
|
||||
return prim.isString() ? prim.getAsString() : def;
|
||||
}else {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.plugin.eaglermotd;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public interface EaglerMOTDQueryResponseAdapter {
|
||||
|
||||
void stringResponse(String type, String str);
|
||||
void jsonResponse(String type, JsonObject json);
|
||||
|
||||
void sendBinary(byte[] bin);
|
||||
|
||||
default void errorResponse(String str) {
|
||||
stringResponse("error", str);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.plugin.eaglermotd;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class QueryCache {
|
||||
|
||||
private static class CachedFile {
|
||||
protected final String name;
|
||||
protected final File file;
|
||||
protected long lastReload;
|
||||
protected long lastRescan;
|
||||
protected CachedFile(String name, File file) {
|
||||
this.name = name;
|
||||
this.file = file;
|
||||
this.lastReload = this.lastRescan = 0l;
|
||||
}
|
||||
protected boolean needsReload() {
|
||||
long l = System.currentTimeMillis();
|
||||
if(l - lastRescan > 5000l) {
|
||||
lastRescan = l;
|
||||
return file.exists() && lastReload < file.lastModified();
|
||||
}else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class CachedFileBinary extends CachedFile {
|
||||
protected byte[] bytes = null;
|
||||
protected CachedFileBinary(String name, File file) {
|
||||
super(name, file);
|
||||
}
|
||||
protected byte[] getOrReload() {
|
||||
synchronized(this) {
|
||||
if(needsReload()) {
|
||||
if(file.exists()) {
|
||||
try(FileInputStream fis = new FileInputStream(file)) {
|
||||
ByteArrayOutputStream read = new ByteArrayOutputStream(fis.available());
|
||||
byte[] d = new byte[8192];
|
||||
int i;
|
||||
while((i = fis.read(d)) != -1) {
|
||||
read.write(d, 0, i);
|
||||
}
|
||||
lastRescan = lastReload = System.currentTimeMillis();
|
||||
bytes = read.toByteArray();
|
||||
}catch(Throwable t) {
|
||||
bytes = null;
|
||||
System.err.println("[EaglerMOTD] Failed to load binary: " + name);
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class CachedFileString extends CachedFile {
|
||||
protected String chars = null;
|
||||
protected CachedFileString(String name, File file) {
|
||||
super(name, file);
|
||||
|
||||
}
|
||||
protected String getOrReload() {
|
||||
synchronized(this) {
|
||||
if(needsReload()) {
|
||||
if(file.exists()) {
|
||||
try(FileInputStream fis = new FileInputStream(file)) {
|
||||
ByteArrayOutputStream read = new ByteArrayOutputStream(fis.available());
|
||||
byte[] d = new byte[8192];
|
||||
int i;
|
||||
while((i = fis.read(d)) != -1) {
|
||||
read.write(d, 0, i);
|
||||
}
|
||||
lastRescan = lastReload = System.currentTimeMillis();
|
||||
chars = new String(read.toByteArray(), StandardCharsets.UTF_8);
|
||||
}catch(Throwable t) {
|
||||
chars = null;
|
||||
System.err.println("[EaglerMOTD] Failed to load text: " + name);
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return chars;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class CachedFileJSON extends CachedFile {
|
||||
protected JsonObject json = null;
|
||||
protected CachedFileJSON(String name, File file) {
|
||||
super(name, file);
|
||||
|
||||
}
|
||||
protected JsonObject getOrReload() {
|
||||
synchronized(this) {
|
||||
if(needsReload()) {
|
||||
if(file.exists()) {
|
||||
try(FileInputStream fis = new FileInputStream(file)) {
|
||||
ByteArrayOutputStream read = new ByteArrayOutputStream(fis.available());
|
||||
byte[] d = new byte[8192];
|
||||
int i;
|
||||
while((i = fis.read(d)) != -1) {
|
||||
read.write(d, 0, i);
|
||||
}
|
||||
lastRescan = lastReload = System.currentTimeMillis();
|
||||
json = JsonParser.parseString(new String(read.toByteArray(), StandardCharsets.UTF_8)).getAsJsonObject();
|
||||
}catch(Throwable t) {
|
||||
json = null;
|
||||
System.err.println("[EaglerMOTD] Failed to load json: " + name);
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return json;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final HashMap<String, CachedFileBinary> cachedBinary = new HashMap();
|
||||
private static final HashMap<String, CachedFileString> cachedString = new HashMap();
|
||||
private static final HashMap<String, CachedFileJSON> cachedJSON = new HashMap();
|
||||
|
||||
public static void flush() {
|
||||
cachedBinary.clear();
|
||||
cachedString.clear();
|
||||
cachedJSON.clear();
|
||||
}
|
||||
|
||||
public static byte[] getBinaryFile(String s) {
|
||||
CachedFileBinary fb;
|
||||
synchronized(cachedBinary) {
|
||||
fb = cachedBinary.get(s);
|
||||
if(fb == null) {
|
||||
fb = new CachedFileBinary(s, new File(s));
|
||||
cachedBinary.put(s, fb);
|
||||
}
|
||||
}
|
||||
return fb.getOrReload();
|
||||
}
|
||||
|
||||
public static String getStringFile(String s) {
|
||||
CachedFileString fb;
|
||||
synchronized(cachedString) {
|
||||
fb = cachedString.get(s);
|
||||
if(fb == null) {
|
||||
fb = new CachedFileString(s, new File(s));
|
||||
cachedString.put(s, fb);
|
||||
}
|
||||
}
|
||||
return fb.getOrReload();
|
||||
}
|
||||
|
||||
public static JsonObject getJSONFile(String s) {
|
||||
CachedFileJSON fb;
|
||||
synchronized(cachedJSON) {
|
||||
fb = cachedJSON.get(s);
|
||||
if(fb == null) {
|
||||
fb = new CachedFileJSON(s, new File(s));
|
||||
cachedJSON.put(s, fb);
|
||||
}
|
||||
}
|
||||
return fb.getOrReload();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.plugin.eaglermotd;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class QueryType {
|
||||
|
||||
public final String name;
|
||||
public final String type;
|
||||
|
||||
public final String dataString;
|
||||
public final String dataJSONFile;
|
||||
public final JsonObject dataJSONObject;
|
||||
public final String dataTextFile;
|
||||
public final String dataBinaryFile;
|
||||
|
||||
public QueryType(String name, JsonObject tag) {
|
||||
this.name = name;
|
||||
JsonElement el = tag.get("json");
|
||||
if(el == null || !el.isJsonObject()) {
|
||||
this.dataJSONObject = null;
|
||||
this.dataJSONFile = optString(tag.get("json"), null);
|
||||
if(this.dataJSONFile == null) {
|
||||
this.dataTextFile = optString(tag.get("txt"), null);
|
||||
if(this.dataTextFile == null) {
|
||||
this.dataString = optString(tag.get("string"), null);
|
||||
}else {
|
||||
this.dataString = null;
|
||||
}
|
||||
}else {
|
||||
this.dataTextFile = null;
|
||||
this.dataString = null;
|
||||
}
|
||||
}else {
|
||||
this.dataJSONObject = el.getAsJsonObject();
|
||||
this.dataJSONFile = null;
|
||||
this.dataTextFile = null;
|
||||
this.dataString = null;
|
||||
}
|
||||
this.dataBinaryFile = optString(tag.get("file"), null);
|
||||
String t = optString(tag.get("type"), null);
|
||||
if(t == null) {
|
||||
if(this.dataJSONObject != null || this.dataJSONFile != null) {
|
||||
t = "json";
|
||||
}else if(this.dataString != null || this.dataTextFile != null) {
|
||||
t = "text";
|
||||
}else {
|
||||
t = "binary";
|
||||
}
|
||||
}
|
||||
this.type = t;
|
||||
}
|
||||
|
||||
public void doQuery(EaglerMOTDQueryResponseAdapter query) {
|
||||
byte[] bin = null;
|
||||
if(dataBinaryFile != null) {
|
||||
bin = QueryCache.getBinaryFile(dataBinaryFile);
|
||||
if(bin == null) {
|
||||
query.errorResponse("Error: could not load binary file '" + dataBinaryFile + "' for query '" + type + "'");
|
||||
return;
|
||||
}
|
||||
}
|
||||
boolean flag = false;
|
||||
if(dataJSONObject != null) {
|
||||
query.jsonResponse(type, dataJSONObject);
|
||||
flag = true;
|
||||
}else if(dataJSONFile != null) {
|
||||
JsonObject obj = QueryCache.getJSONFile(dataJSONFile);
|
||||
if(obj == null) {
|
||||
query.errorResponse("Error: could not load or parse JSON file '" + dataJSONFile + "' for query '" + type + "'");
|
||||
return;
|
||||
}else {
|
||||
query.jsonResponse(type, obj);
|
||||
flag = true;
|
||||
}
|
||||
}else if(dataTextFile != null) {
|
||||
String txt = QueryCache.getStringFile(dataTextFile);
|
||||
if(txt == null) {
|
||||
query.errorResponse("Error: could not load text file '" + dataJSONFile + "' for query '" + type + "'");
|
||||
return;
|
||||
}else {
|
||||
query.stringResponse(type, txt);
|
||||
flag = true;
|
||||
}
|
||||
}else if(dataString != null) {
|
||||
query.stringResponse(type, dataString);
|
||||
flag = true;
|
||||
}
|
||||
if(!flag) {
|
||||
if(bin != null) {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("binary", true);
|
||||
json.addProperty("file", dataBinaryFile);
|
||||
json.addProperty("size", bin.length);
|
||||
query.jsonResponse(type, json);
|
||||
}else {
|
||||
query.stringResponse(type, "<No Content>");
|
||||
}
|
||||
}
|
||||
if(bin != null) {
|
||||
query.sendBinary(bin);
|
||||
}
|
||||
}
|
||||
|
||||
private static String optString(JsonElement el, String def) {
|
||||
if(el == null || !el.isJsonPrimitive()) {
|
||||
return def;
|
||||
}else {
|
||||
JsonPrimitive pr = el.getAsJsonPrimitive();
|
||||
return pr.isString() ? pr.getAsString() : def;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,20 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.plugin.eaglermotd.bungee;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.plugin.eaglermotd.EaglerMOTDConfiguration;
|
||||
import net.lax1dude.eaglercraft.v1_8.plugin.eaglermotd.EaglerMOTDConnectionUpdater;
|
||||
import net.lax1dude.eaglercraft.v1_8.plugin.eaglermotd.EaglerMOTDLoggerAdapter;
|
||||
import net.lax1dude.eaglercraft.v1_8.plugin.eaglermotd.bungee.command.CommandMOTDReloadBungee;
|
||||
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_bungeecord.api.query.EaglerQueryHandler;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
|
||||
/**
|
||||
|
@ -28,7 +37,98 @@ public class EaglerMOTDPluginBungee extends Plugin {
|
|||
private static EaglerMOTDPluginBungee instance = null;
|
||||
|
||||
public final EaglerMOTDConfiguration conf = new EaglerMOTDConfiguration();
|
||||
public final Timer tickTimer = new Timer("MOTD Tick Timer");
|
||||
public final List<EaglerMOTDConnectionUpdater> motdConnections = new LinkedList();
|
||||
public final EaglerMOTDLoggerAdapter loggerAdapter;
|
||||
private Timer tickTimer = null;
|
||||
private final List<String> installedQueries = new ArrayList();
|
||||
|
||||
public EaglerMOTDPluginBungee() {
|
||||
instance = this;
|
||||
loggerAdapter = new EaglerMOTDLoggerAdapter() {
|
||||
@Override
|
||||
public void info(String msg) {
|
||||
EaglerMOTDPluginBungee.this.getLogger().info(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg) {
|
||||
EaglerMOTDPluginBungee.this.getLogger().warning(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String msg) {
|
||||
EaglerMOTDPluginBungee.this.getLogger().severe(msg);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
File dataFolder = getDataFolder();
|
||||
if(!dataFolder.isDirectory() && !dataFolder.mkdirs()) {
|
||||
throw new RuntimeException("Could not create config folder!");
|
||||
}
|
||||
conf.reload(dataFolder, loggerAdapter);
|
||||
}
|
||||
|
||||
public void installQueryHandlers() {
|
||||
for(String str : conf.queryTypes.keySet()) {
|
||||
EaglerQueryHandler.registerQueryType(str, EaglerMOTDQueryHandlerBungee.class);
|
||||
installedQueries.add(str);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeQueryHandlers() {
|
||||
for(String str : installedQueries) {
|
||||
EaglerQueryHandler.unregisterQueryType(str);
|
||||
}
|
||||
installedQueries.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
getProxy().getPluginManager().registerCommand(this, new CommandMOTDReloadBungee(this));
|
||||
installQueryHandlers();
|
||||
if(tickTimer == null) {
|
||||
tickTimer = new Timer("MOTD Tick Timer");
|
||||
tickTimer.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized(motdConnections) {
|
||||
Iterator<EaglerMOTDConnectionUpdater> itr = motdConnections.iterator();
|
||||
while(itr.hasNext()) {
|
||||
EaglerMOTDConnectionUpdater c = itr.next();
|
||||
try {
|
||||
if(!c.tick()) {
|
||||
itr.remove();
|
||||
}
|
||||
}catch(Throwable t) {
|
||||
EaglerMOTDPluginBungee.this.getLogger().log(Level.SEVERE, "Error ticking MOTD '" + (c.currentMessage == null ? "null" : c.currentMessage.name) + "' on listener " + c.listenerName, t);
|
||||
c.close();
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}, 0, 50l);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
removeQueryHandlers();
|
||||
if(tickTimer != null) {
|
||||
tickTimer.cancel();
|
||||
tickTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static EaglerMOTDPluginBungee getPlugin() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static Logger logger() {
|
||||
return instance.getLogger();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.plugin.eaglermotd.bungee;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.plugin.eaglermotd.EaglerMOTDQueryResponseAdapter;
|
||||
import net.lax1dude.eaglercraft.v1_8.plugin.eaglermotd.QueryType;
|
||||
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_bungeecord.api.query.EaglerQuerySimpleHandler;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class EaglerMOTDQueryHandlerBungee extends EaglerQuerySimpleHandler implements EaglerMOTDQueryResponseAdapter {
|
||||
|
||||
@Override
|
||||
protected void begin(String queryType) {
|
||||
if(this.isClosed()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
QueryType queryHandler = EaglerMOTDPluginBungee.getPlugin().conf.queryTypes.get(queryType.toLowerCase());
|
||||
if(queryHandler != null) {
|
||||
queryHandler.doQuery(this);
|
||||
}
|
||||
}catch(Throwable t) {
|
||||
EaglerMOTDPluginBungee.logger().log(Level.SEVERE, "Failed to handle query type \"" + queryType + "\"!", t);
|
||||
}finally {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stringResponse(String type, String str) {
|
||||
this.sendStringResponse(type, str);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonResponse(String type, JsonObject json) {
|
||||
this.sendJsonResponse(type, json);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendBinary(byte[] bin) {
|
||||
this.sendBinaryResponse(bin);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.plugin.eaglermotd.bungee.command;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.plugin.eaglermotd.bungee.EaglerMOTDPluginBungee;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class CommandMOTDReloadBungee extends Command {
|
||||
|
||||
private final EaglerMOTDPluginBungee plugin;
|
||||
|
||||
public CommandMOTDReloadBungee(EaglerMOTDPluginBungee plugin) {
|
||||
super("motd-reload", "eaglermotd.command.reload");
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender arg0, String[] arg1) {
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user