HarbleAPI and UIlogger bugfix in structures

This commit is contained in:
sirjonasxx 2018-11-17 03:12:15 +01:00
parent ce71cf114a
commit 2486d5a902
8 changed files with 354 additions and 13 deletions

View File

@ -368,7 +368,7 @@ public abstract class Extension {
}
protected interface OnConnectionListener {
public interface OnConnectionListener {
void act(String host, int port, String hotelversion);
}
private List<OnConnectionListener> onConnectionListeners = new ArrayList<>();

View File

@ -1,7 +0,0 @@
package gearth.extensions.extra;
/**
* Created by Jonas on 22/09/18.
*/
public class Inspector {
}

View File

@ -0,0 +1,127 @@
package gearth.extensions.extra.hashing;
import gearth.extensions.Extension;
import gearth.misc.harble_api.HarbleAPI;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by Jonas on 10/11/2018.
*/
public class HashSupport {
private final Object lock = new Object();
private HarbleAPI harbleAPI = new HarbleAPI(""); //empty
private Map<String, List<Extension.MessageListener>> incomingMessageListeners = new HashMap<>();
private Map<String, List<Extension.MessageListener>> outgoingMessageListeners = new HashMap<>();
private PacketSender toClientSender;
private PacketSender toServerSender;
public interface OnConnectRegistration {
void onConnect(Extension.OnConnectionListener listener);
}
public interface InterceptRegistration {
void intercept(HMessage.Side side, Extension.MessageListener messageListener);
}
public interface PacketSender {
boolean send(HPacket packet);
}
public HashSupport(OnConnectRegistration onConnectRegistration, InterceptRegistration interceptRegistration, PacketSender sendToClient, PacketSender sendToServer) {
toClientSender = sendToClient;
toServerSender = sendToServer;
onConnectRegistration.onConnect((host, port, hotelversion) -> {
// synchronized (lock) {
harbleAPI = new HarbleAPI(hotelversion);
// }
});
interceptRegistration.intercept(HMessage.Side.TOSERVER, message -> {
// synchronized (lock) {
HarbleAPI.HarbleMessage haMessage = harbleAPI.getHarbleMessageFromHeaderId(HMessage.Side.TOSERVER, message.getPacket().headerId());
if (haMessage != null) {
String hash = haMessage.getHash();
List<Extension.MessageListener> listeners = outgoingMessageListeners.get(hash);
if (listeners != null) {
for (Extension.MessageListener listener : listeners) {
listener.act(message);
message.getPacket().resetReadIndex();
}
}
}
// }
});
interceptRegistration.intercept(HMessage.Side.TOCLIENT, message -> {
// synchronized (lock) {
HarbleAPI.HarbleMessage haMessage = harbleAPI.getHarbleMessageFromHeaderId(HMessage.Side.TOCLIENT, message.getPacket().headerId());
if (haMessage != null) {
String hash = haMessage.getHash();
List<Extension.MessageListener> listeners = incomingMessageListeners.get(hash);
if (listeners != null) {
for (Extension.MessageListener listener : listeners) {
listener.act(message);
message.getPacket().resetReadIndex();
}
}
}
// }
});
}
public void intercept(HMessage.Side side, String hash, Extension.MessageListener messageListener) {
Map<String, List<Extension.MessageListener>> messageListeners =
(side == HMessage.Side.TOSERVER
? outgoingMessageListeners
: incomingMessageListeners);
messageListeners.computeIfAbsent(hash, k -> new ArrayList<>());
messageListeners.get(hash).add(messageListener);
}
/**
*
* @return if no errors occurred (invalid hash/invalid parameters/connection error)
*/
public boolean sendToClient(String hash, Object... objects) {
List<HarbleAPI.HarbleMessage> possibilities = harbleAPI.getHarbleMessagesFromHash(HMessage.Side.TOCLIENT, hash);
if (possibilities.size() == 0) return false;
int headerId = possibilities.get(0).getHeaderId();
try {
HPacket packetToSend = new HPacket(headerId, objects);
return toClientSender.send(packetToSend);
}
catch (InvalidParameterException e) {
return false;
}
}
/**
*
* @return if no errors occurred (invalid hash/invalid parameters/connection error)
*/
public boolean sendToServer(String hash, Object... objects) {
List<HarbleAPI.HarbleMessage> possibilities = harbleAPI.getHarbleMessagesFromHash(HMessage.Side.TOSERVER, hash);
if (possibilities.size() == 0) return false;
int headerId = possibilities.get(0).getHeaderId();
try {
HPacket packetToSend = new HPacket(headerId, objects);
return toServerSender.send(packetToSend);
}
catch (InvalidParameterException e) {
return false;
}
}
}

View File

@ -30,7 +30,7 @@ public class Cacher {
private static boolean cacheFileExists(String cache_filename) {
public static boolean cacheFileExists(String cache_filename) {
File f = new File(getCacheDir(), cache_filename);
return (f.exists() && !f.isDirectory());
}
@ -83,7 +83,7 @@ public class Cacher {
}
private static boolean cacheFileExists() {
public static boolean cacheFileExists() {
return cacheFileExists(DEFAULT_CACHE_FILENAME);
}

View File

@ -1,10 +1,142 @@
package gearth.misc.harble_api;
import gearth.misc.Cacher;
import gearth.protocol.HMessage;
import org.json.JSONObject;
import sun.misc.Cache;
import javax.print.attribute.standard.Destination;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by Jonas on 10/11/2018.
*/
public class HarbleAPI {
public class HarbleMessage {
private HMessage.Side destination;
private int headerId;
private String hash;
private String name;
//name can be NULL
public HarbleMessage(HMessage.Side destination, int headerId, String hash, String name) {
this.destination = destination;
this.headerId = headerId;
this.hash = hash;
this.name = name;
}
public String getName() {
return name;
}
public int getHeaderId() {
return headerId;
}
public HMessage.Side getDestination() {
return destination;
}
public String getHash() {
return hash;
}
}
private Map<Integer, HarbleMessage> headerIdToMessage_incoming = new HashMap<>();
private Map<Integer, HarbleMessage> headerIdToMessage_outgoing = new HashMap<>();
private Map<String, List<HarbleMessage>> hashToMessage_incoming = new HashMap<>();
private Map<String, List<HarbleMessage>> hashToMessage_outgoing = new HashMap<>();
private Map<String, HarbleMessage> nameToMessage_incoming = new HashMap<>();
private Map<String, HarbleMessage> nameToMessage_outgoing = new HashMap<>();
/**
* cache file must be generated first within G-Earth, inb4 20 extensions requesting it at the same time
* @param hotelversion
*/
public HarbleAPI (String hotelversion) {
if (Cacher.cacheFileExists(HarbleAPIFetcher.CACHE_PREFIX + hotelversion)) {
JSONObject object = Cacher.getCacheContents(HarbleAPIFetcher.CACHE_PREFIX + hotelversion);
parse(object);
}
}
private void addMessage(HarbleMessage message) {
Map<Integer, HarbleMessage> headerIdToMessage =
message.getDestination() == HMessage.Side.TOCLIENT
? headerIdToMessage_incoming :
headerIdToMessage_outgoing;
Map<String, List<HarbleMessage>> hashToMessage =
message.getDestination() == HMessage.Side.TOCLIENT
? hashToMessage_incoming
: hashToMessage_outgoing;
Map<String, HarbleMessage> nameToMessag =
message.getDestination() == HMessage.Side.TOCLIENT
? nameToMessage_incoming
: nameToMessage_outgoing;
headerIdToMessage.put(message.getHeaderId(), message);
hashToMessage.computeIfAbsent(message.getHash(), k -> new ArrayList<>());
hashToMessage.get(message.getHash()).add(message);
if (message.getName() != null && !message.getName().equals("null")) {
nameToMessag.put(message.getName(), message);
}
}
private void parse(JSONObject object) {
JSONObject incoming = object.getJSONObject("IncomingMessages");
JSONObject outgoing = object.getJSONObject("OutgoingMessages");
if (incoming != null && outgoing != null) {
for (String key : incoming.keySet()) {
JSONObject inMsg = incoming.getJSONObject(key);
String name = inMsg.getString("Name");
String hash = inMsg.getString("Hash");
Integer headerId = Integer.parseInt(key);
HarbleMessage message = new HarbleMessage(HMessage.Side.TOCLIENT, headerId, hash, name);
addMessage(message);
}
for (String key : outgoing.keySet()) {
JSONObject outMsg = incoming.getJSONObject(key);
String name = outMsg.getString("Name");
String hash = outMsg.getString("Hash");
Integer headerId = Integer.parseInt(key);
HarbleMessage message = new HarbleMessage(HMessage.Side.TOSERVER, headerId, hash, name);
addMessage(message);
}
}
}
public HarbleMessage getHarbleMessageFromHeaderId(HMessage.Side side, int headerId) {
Map<Integer, HarbleMessage> headerIdToMessage =
(side == HMessage.Side.TOSERVER
? headerIdToMessage_outgoing
: headerIdToMessage_incoming);
return headerIdToMessage.get(headerId);
}
public List<HarbleMessage> getHarbleMessagesFromHash(HMessage.Side side, String hash) {
Map<String, List<HarbleMessage>> hashToMessage =
(side == HMessage.Side.TOSERVER
? hashToMessage_outgoing
: hashToMessage_incoming);
List<HarbleMessage> result = hashToMessage.get(hash);
return result == null ? new ArrayList<>() : result;
}
public HarbleMessage getHarbleMessageFromName(HMessage.Side side, String name) {
Map<String, HarbleMessage> nameToMessage =
(side == HMessage.Side.TOSERVER
? nameToMessage_outgoing
: nameToMessage_incoming);
return nameToMessage.get(name);
}
}

View File

@ -1,8 +1,51 @@
package gearth.misc.harble_api;
import gearth.misc.Cacher;
import org.json.JSONObject;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;
/**
* Created by Jeunez on 10/11/2018.
* Created by Jonas on 10/11/2018.
*/
public class HarbleAPIFetcher {
}
public static final String CACHE_PREFIX = "HARBLE_API-";
public static final String HARBLE_API_URL = "https://api.harble.net/revisions/$hotelversion$.json";
public static HarbleAPI fetch(String hotelversion) {
String cacheName = CACHE_PREFIX + hotelversion;
if (Cacher.cacheFileExists(cacheName)) {
return new HarbleAPI(hotelversion);
}
else {
Connection connection = Jsoup.connect(HARBLE_API_URL.replace("$hotelversion$", hotelversion)).ignoreContentType(true);
try {
Document doc = connection.get();
Connection.Response response = connection.response();
if (response.statusCode() == 200) {
String s = doc.body().toString();
s = s.substring(6, s.length() - 7);
JSONObject object = new JSONObject(s);
Cacher.updateCache(object, cacheName);
return new HarbleAPI(hotelversion);
}
else {
return null;
}
} catch (IOException e) {
return null;
}
}
}
public static void main(String[] args) {
HarbleAPI api = fetch("PRODUCTION-201810171204-70166177");
}
}

View File

@ -1,10 +1,12 @@
package gearth.protocol;
import com.sun.org.apache.xpath.internal.operations.Bool;
import gearth.misc.StringifyAble;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Arrays;
@ -35,6 +37,35 @@ public class HPacket implements StringifyAble {
isEdited = false;
}
/**
*
* @param header headerId
* @param objects can be a byte, integer, boolean, string, no short values allowed (use 2 bytes instead)
*/
public HPacket(int header, Object... objects) throws InvalidParameterException {
this(header);
for (int i = 0; i < objects.length; i++) {
Object o = objects[i];
if (o instanceof Byte) {
appendByte((Byte)o);
}
else if (o instanceof Integer) {
appendInt((Integer)o);
}
else if (o instanceof String) {
appendString((String)o);
}
else if (o instanceof Boolean) {
appendBoolean((Boolean) o);
}
else {
throw new InvalidParameterException();
}
}
isEdited = false;
}
public String toString() {
String teststring = "";
for (byte x : packetInBytes) {

View File

@ -60,6 +60,20 @@ public class UiLoggerController implements Initializable {
}
private static String cleanTextContent(String text)
{
// // strips off all non-ASCII characters
// text = text.replaceAll("[^\\x00-\\x7F]", "");
//
// // erases all the ASCII control characters
text = text.replaceAll("[\\p{Cntrl}&&[^\n\t]]", "");
// removes non-printable characters from Unicode
// text = text.replaceAll("\\p{C}", "");
return text.trim();
}
public void appendMessage(HPacket packet, int types) {
boolean isBlocked = (types & PacketLogger.MESSAGE_TYPE.BLOCKED.getValue()) != 0;
boolean isReplaced = (types & PacketLogger.MESSAGE_TYPE.REPLACED.getValue()) != 0;
@ -103,7 +117,7 @@ public class UiLoggerController implements Initializable {
}
}
if (!expr.equals("") && displayStructure && (!skiphugepackets || packet.length() <= 8000))
elements.add(new Element("\n" + expr, "structure"));
elements.add(new Element("\n" + cleanTextContent(expr), "structure"));
elements.add(new Element("\n--------------------\n", ""));
@ -125,6 +139,7 @@ public class UiLoggerController implements Initializable {
for (Element element : elements) {
sb.append(element.text);
styleSpansBuilder.add(Collections.singleton(element.className), element.text.length());
}