mirror of
https://github.com/sirjonasxx/G-Earth.git
synced 2025-01-18 16:26:26 +01:00
extension suppoer & abstract Extension class implemented, not tested yet.
This commit is contained in:
parent
2b9c553c9c
commit
fd781afb18
@ -38,8 +38,10 @@ public class Main extends Application {
|
||||
|
||||
}
|
||||
|
||||
public static String[] args;
|
||||
|
||||
public static void main(String[] args) {
|
||||
Main.args = args;
|
||||
launch(args);
|
||||
}
|
||||
}
|
||||
|
210
src/main/extensions/Extension.java
Normal file
210
src/main/extensions/Extension.java
Normal file
@ -0,0 +1,210 @@
|
||||
package main.extensions;
|
||||
|
||||
import main.protocol.HMessage;
|
||||
import main.protocol.HPacket;
|
||||
import main.protocol.packethandler.PayloadBuffer;
|
||||
import main.ui.extensions.Extensions;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by Jonas on 23/06/18.
|
||||
*/
|
||||
public abstract class Extension {
|
||||
|
||||
public interface MessageListener {
|
||||
void act(HMessage message);
|
||||
}
|
||||
public interface FlagsCheckListener {
|
||||
void act(String[] args);
|
||||
}
|
||||
|
||||
|
||||
private static final String[] PORT_FLAG = {"--port", "-p"};
|
||||
|
||||
private OutputStream out = null;
|
||||
private Map<Integer, List<MessageListener>> incomingMessageListeners = new HashMap<>();
|
||||
private Map<Integer, List<MessageListener>> outgoingMessageListeners = new HashMap<>();
|
||||
private FlagsCheckListener flagRequestCallback = null;
|
||||
|
||||
|
||||
|
||||
public Extension(String[] args) {
|
||||
//obtain port
|
||||
int port = 0;
|
||||
|
||||
outerloop:
|
||||
for (int i = 0; i < args.length - 1; i++) {
|
||||
for (String str : PORT_FLAG) {
|
||||
if (args[i].equals(str)) {
|
||||
port = Integer.parseInt(args[i+1]);
|
||||
break outerloop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
Socket GEarthExtensionServer = new Socket("localhost", port);
|
||||
|
||||
InputStream in = GEarthExtensionServer.getInputStream();
|
||||
out = GEarthExtensionServer.getOutputStream();
|
||||
|
||||
PayloadBuffer buffer = new PayloadBuffer();
|
||||
while (!GEarthExtensionServer.isClosed()) {
|
||||
if (in.available() > 0) {
|
||||
byte[] data = new byte[in.available()];
|
||||
in.read(data);
|
||||
buffer.push(data);
|
||||
|
||||
HPacket[] packets = buffer.receive();
|
||||
for (HPacket packet : packets) {
|
||||
if (packet.headerId() == Extensions.OUTGOING_MESSAGES_IDS.INFOREQUEST) {
|
||||
HPacket response = new HPacket(Extensions.INCOMING_MESSAGES_IDS.EXTENSIONINFO);
|
||||
response.appendString(getTitle())
|
||||
.appendString(getAuthor())
|
||||
.appendString(getVersion())
|
||||
.appendString(getDescription());
|
||||
writeToStream(response.toBytes());
|
||||
}
|
||||
else if (packet.headerId() == Extensions.OUTGOING_MESSAGES_IDS.CONNECTIONSTART) {
|
||||
onStartConnection();
|
||||
}
|
||||
else if (packet.headerId() == Extensions.OUTGOING_MESSAGES_IDS.CONNECTIONEND) {
|
||||
onEndConnection();
|
||||
}
|
||||
else if (packet.headerId() == Extensions.OUTGOING_MESSAGES_IDS.FLAGSCHECK) {
|
||||
// body = an array of G-Earths main flags
|
||||
if (flagRequestCallback != null) {
|
||||
int arraysize = packet.readInteger();
|
||||
String[] gEarthArgs = new String[arraysize];
|
||||
for (int i = 0; i < gEarthArgs.length; i++) {
|
||||
gEarthArgs[i] = packet.readString();
|
||||
}
|
||||
flagRequestCallback.act(gEarthArgs);
|
||||
}
|
||||
flagRequestCallback = null;
|
||||
}
|
||||
else if (packet.headerId() == Extensions.OUTGOING_MESSAGES_IDS.INIT) {
|
||||
init();
|
||||
}
|
||||
else if (packet.headerId() == Extensions.OUTGOING_MESSAGES_IDS.FREEFLOW) {
|
||||
// nothing to be done yet
|
||||
}
|
||||
else if (packet.headerId() == Extensions.OUTGOING_MESSAGES_IDS.ONDOUBLECLICK) {
|
||||
onDoubleClick();
|
||||
}
|
||||
else if (packet.headerId() == Extensions.OUTGOING_MESSAGES_IDS.PACKETINTERCEPT) {
|
||||
HMessage habboMessage = new HMessage(packet.readString());
|
||||
HPacket habboPacket = habboMessage.getPacket();
|
||||
|
||||
Map<Integer, List<MessageListener>> listeners =
|
||||
habboMessage.getDestination() == HMessage.Side.TOCLIENT ?
|
||||
incomingMessageListeners :
|
||||
outgoingMessageListeners;
|
||||
|
||||
if (listeners.containsKey(-1)) { // registered on all packets
|
||||
for (int i = listeners.get(-1).size() - 1; i >= 0; i--) {
|
||||
listeners.get(-1).get(i).act(habboMessage);
|
||||
}
|
||||
}
|
||||
if (listeners.containsKey(habboPacket.headerId())) {
|
||||
for (int i = listeners.get(habboPacket.headerId()).size() - 1; i >= 0; i--) {
|
||||
listeners.get(habboPacket.headerId()).get(i).act(habboMessage);
|
||||
}
|
||||
}
|
||||
|
||||
HPacket response = new HPacket(Extensions.INCOMING_MESSAGES_IDS.MANIPULATEDPACKET);
|
||||
response.appendString(habboMessage.stringify());
|
||||
|
||||
writeToStream(response.toBytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
Thread.sleep(1);
|
||||
}
|
||||
|
||||
|
||||
} catch (IOException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeToStream(byte[] bytes) throws IOException {
|
||||
synchronized (out) {
|
||||
out.write(bytes);
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
|
||||
//methods returns if succeed
|
||||
protected boolean sendToClient(HPacket packet) {
|
||||
return send(packet, HMessage.Side.TOCLIENT);
|
||||
}
|
||||
protected boolean sendToServer(HPacket packet) {
|
||||
return send(packet, HMessage.Side.TOSERVER);
|
||||
}
|
||||
private boolean send(HPacket packet, HMessage.Side side) {
|
||||
HPacket packet1 = new HPacket(Extensions.INCOMING_MESSAGES_IDS.SENDMESSAGE);
|
||||
packet1.appendByte(side == HMessage.Side.TOCLIENT ? (byte)0 : (byte)1);
|
||||
packet1.appendInt(packet.getBytesLength());
|
||||
packet1.appendBytes(packet.toBytes());
|
||||
try {
|
||||
writeToStream(packet1.toBytes());
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected void intercept(HMessage.Side side, int headerId, MessageListener messageListener) {
|
||||
Map<Integer, List<MessageListener>> listeners =
|
||||
side == HMessage.Side.TOCLIENT ?
|
||||
incomingMessageListeners :
|
||||
outgoingMessageListeners;
|
||||
|
||||
if (!listeners.containsKey(headerId)) {
|
||||
listeners.put(headerId, new ArrayList<>());
|
||||
}
|
||||
|
||||
listeners.get(headerId).add(messageListener);
|
||||
}
|
||||
protected void intercept(HMessage.Side side, MessageListener messageListener) {
|
||||
intercept(side, -1, messageListener);
|
||||
}
|
||||
|
||||
//returns "false" if another flag requester was busy
|
||||
protected boolean requestFlags(FlagsCheckListener flagRequestCallback) {
|
||||
if (this.flagRequestCallback != null) return false;
|
||||
this.flagRequestCallback = flagRequestCallback;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void writeToConsole(String s) {
|
||||
HPacket packet = new HPacket(Extensions.INCOMING_MESSAGES_IDS.EXTENSIONCONSOLELOG);
|
||||
packet.appendString(s);
|
||||
try {
|
||||
writeToStream(packet.toBytes());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// All methods under here block the stream, use threads if needed.
|
||||
protected abstract void init();
|
||||
protected abstract void onDoubleClick();
|
||||
protected abstract void onStartConnection();
|
||||
protected abstract void onEndConnection();
|
||||
|
||||
protected abstract String getTitle();
|
||||
protected abstract String getDescription();
|
||||
protected abstract String getVersion();
|
||||
protected abstract String getAuthor();
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
package main.protocol;
|
||||
|
||||
public class HMessage {
|
||||
import main.misc.StringifyAble;
|
||||
|
||||
public class HMessage implements StringifyAble {
|
||||
|
||||
public enum Side {
|
||||
TOSERVER,
|
||||
@ -13,6 +15,9 @@ public class HMessage {
|
||||
|
||||
private boolean isBlocked;
|
||||
|
||||
public HMessage(String fromString) {
|
||||
constructFromString(fromString);
|
||||
}
|
||||
|
||||
public HMessage(HPacket packet, Side side, int index) {
|
||||
this.side = side;
|
||||
@ -42,4 +47,47 @@ public class HMessage {
|
||||
public boolean isCorrupted() {
|
||||
return hPacket.isCorrupted();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String stringify() {
|
||||
String s = (isBlocked ? "1" : "0") + "\t" + index + "\t" + side.name() + "\t" + hPacket.stringify();
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void constructFromString(String str) {
|
||||
String[] parts = str.split("\t");
|
||||
this.isBlocked = parts[0].equals("1");
|
||||
this.index = Integer.parseInt(parts[1]);
|
||||
this.side = parts[2].equals("TOCLIENT") ? Side.TOCLIENT : Side.TOSERVER;
|
||||
HPacket p = new HPacket(new byte[0]);
|
||||
p.constructFromString(parts[3]);
|
||||
this.hPacket = p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof HMessage)) return false;
|
||||
|
||||
HMessage message = (HMessage) obj;
|
||||
|
||||
return message.hPacket.equals(hPacket) && (side == message.side) && (index == message.index);
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// HPacket packet3 = new HPacket(81, new byte[]{0,0,0,1,0,0});
|
||||
//
|
||||
// HPacket packet = new HPacket(82, new byte[]{0,0,0,1,0,0});
|
||||
// HMessage message = new HMessage(packet, Side.TOSERVER, 5);
|
||||
//
|
||||
// String stringed = message.stringify();
|
||||
//
|
||||
// HMessage message2 = new HMessage(stringed);
|
||||
// HPacket packet1 = message2.getPacket();
|
||||
//
|
||||
// System.out.println(message.equals(message2));
|
||||
// System.out.println(packet.equals(packet1));
|
||||
// System.out.println(packet.equals(packet3));
|
||||
// }
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package main.protocol;
|
||||
|
||||
import main.misc.StringifyAble;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -8,7 +10,7 @@ import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class HPacket {
|
||||
public class HPacket implements StringifyAble {
|
||||
// te komen: toExpressions (+impl. expressies)
|
||||
private boolean isEdited = false;
|
||||
private byte[] packetInBytes;
|
||||
@ -403,7 +405,6 @@ public class HPacket {
|
||||
}
|
||||
public HPacket replaceAllString(String oldS, String newS) {
|
||||
while (replaceFirstString(oldS, newS)) {}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -737,7 +738,7 @@ public class HPacket {
|
||||
resultTest[j] = "{b:"+(packetInBytes[j] == 1 ? "true" : "false")+"}";
|
||||
}
|
||||
else {
|
||||
resultTest[j] = "{b:"+packetInBytes[j]+"}";
|
||||
resultTest[j] = "{b:"+((((int)packetInBytes[j])+256)%256)+"}";
|
||||
}
|
||||
}
|
||||
opeenvolging = 0;
|
||||
@ -761,4 +762,23 @@ public class HPacket {
|
||||
return expression.toString().replace("{i:0}{b:false}{b:true}", "{s:}{i:1}");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringify() {
|
||||
String st = (isEdited ? "1" : "0") + this.toString();
|
||||
return st;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void constructFromString(String str) {
|
||||
this.isEdited = str.charAt(0) == '1';
|
||||
packetInBytes = fromStringToBytes(str.substring(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (!(object instanceof HPacket)) return false;
|
||||
|
||||
HPacket packet2 = (HPacket) object;
|
||||
return Arrays.equals(packetInBytes, packet2.packetInBytes) && (isEdited == packet2.isEdited);
|
||||
}
|
||||
}
|
@ -1,7 +1,13 @@
|
||||
package main.ui.extensions;
|
||||
|
||||
import main.Main;
|
||||
import main.protocol.*;
|
||||
import main.ui.SubForm;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by Jonas on 06/04/18.
|
||||
*/
|
||||
@ -47,7 +53,7 @@ import main.ui.SubForm;
|
||||
* | | | exact implementation is found in the Java abstract Extension class |
|
||||
* -----------------------------------------------------------------------------------------------------
|
||||
* | 3 | PACKET-INTERCEPT* | Includes the whole HMessage as body, needs response with the |
|
||||
* | | | manipulated HMessage (OUTGOING id: 2) (blank body = no manipulation) |
|
||||
* | | | manipulated HMessage (OUTGOING id: 2) |
|
||||
* -----------------------------------------------------------------------------------------------------
|
||||
* | 4 | FLAGS-CHECK** | Body: String with G-Earth's boot flags (args from static main method) |
|
||||
* -----------------------------------------------------------------------------------------------------
|
||||
@ -55,6 +61,10 @@ import main.ui.SubForm;
|
||||
* | | | you could check this yourself as well (listen to out:4000 packet) |
|
||||
* -----------------------------------------------------------------------------------------------------
|
||||
* | 6 | CONNECTION END | Empty body, just a note that a connection has ended |
|
||||
* -----------------------------------------------------------------------------------------------------
|
||||
* | 7 | INIT | Empty body, a connection with G-Earth has been set up |
|
||||
* -----------------------------------------------------------------------------------------------------
|
||||
* | 99 | FREE FLOW | extension-specific body |
|
||||
* -----------------------------------------------------------------------------------------------------
|
||||
*
|
||||
* OUTGOING MESSAGES: (marked with * if that is a response to one of the msgs above)
|
||||
@ -70,17 +80,168 @@ import main.ui.SubForm;
|
||||
* | 4 | SEND-MESSAGE | Body: HMessage object. Sends the HPacket wrapped in the HMessage |
|
||||
* | | | to the client/server |
|
||||
* -----------------------------------------------------------------------------------------------------
|
||||
* | 99 | FREE FLOW | extension-specific body |
|
||||
* -----------------------------------------------------------------------------------------------------
|
||||
*
|
||||
* 4. Your extension will only appear in the extension list once the EXTENSION-INFO has been received by G-Earth
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
public class Extensions extends SubForm {
|
||||
|
||||
public static class OUTGOING_MESSAGES_IDS {
|
||||
public static final int ONDOUBLECLICK = 1;
|
||||
public static final int INFOREQUEST = 2; // backend: implemented
|
||||
public static final int PACKETINTERCEPT = 3; // backend: implemented
|
||||
public static final int FLAGSCHECK = 4; // backend: implemented
|
||||
public static final int CONNECTIONSTART = 5; // backend: implemented
|
||||
public static final int CONNECTIONEND = 6; // backend: implemented
|
||||
public static final int INIT = 7; // backend: implemented
|
||||
public static final int FREEFLOW = 99; // no implementation needed yet
|
||||
}
|
||||
|
||||
|
||||
public static class INCOMING_MESSAGES_IDS {
|
||||
public static final int EXTENSIONINFO = 1; // backend: implemented
|
||||
public static final int MANIPULATEDPACKET = 2; // backend: implemented
|
||||
public static final int REQUESTFLAGS = 3; // backend: implemented
|
||||
public static final int SENDMESSAGE = 4; // backend: implemented
|
||||
public static final int EXTENSIONCONSOLELOG = 98;
|
||||
public static final int FREEFLOW = 99; // no implementation needed yet
|
||||
}
|
||||
|
||||
|
||||
|
||||
private List<GEarthExtension> gEarthExtensions = new ArrayList<>();
|
||||
|
||||
public void initialize() {
|
||||
|
||||
}
|
||||
|
||||
protected void onParentSet() {
|
||||
getHConnection().addStateChangeListener((oldState, newState) -> {
|
||||
if (newState == HConnection.State.CONNECTED) {
|
||||
for (GEarthExtension extension : gEarthExtensions) {
|
||||
extension.sendMessage(new HPacket(OUTGOING_MESSAGES_IDS.CONNECTIONSTART));
|
||||
}
|
||||
}
|
||||
if (oldState == HConnection.State.CONNECTED) {
|
||||
for (GEarthExtension extension : gEarthExtensions) {
|
||||
extension.sendMessage(new HPacket(OUTGOING_MESSAGES_IDS.CONNECTIONEND));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
getHConnection().addTrafficListener(1, message -> {
|
||||
Set<GEarthExtension> collection = new HashSet<>(gEarthExtensions);
|
||||
|
||||
String stringified = message.stringify();
|
||||
HPacket manipulatePacketRequest = new HPacket(OUTGOING_MESSAGES_IDS.PACKETINTERCEPT);
|
||||
manipulatePacketRequest.appendString(stringified);
|
||||
|
||||
boolean[] isblock = new boolean[1];
|
||||
|
||||
for (GEarthExtension extension : gEarthExtensions) {
|
||||
GEarthExtension.ReceiveMessageListener respondCallback = new GEarthExtension.ReceiveMessageListener() {
|
||||
@Override
|
||||
public void act(HPacket packet) {
|
||||
if (packet.headerId() == INCOMING_MESSAGES_IDS.MANIPULATEDPACKET) {
|
||||
String stringifiedresponse = packet.readString();
|
||||
HMessage responseMessage = new HMessage(stringifiedresponse);
|
||||
if (responseMessage.getDestination() == message.getDestination() && responseMessage.getIndex() == message.getIndex()) {
|
||||
if (!message.equals(responseMessage)) {
|
||||
message.constructFromString(stringifiedresponse);
|
||||
if (responseMessage.isBlocked()) {
|
||||
isblock[0] = true;
|
||||
}
|
||||
}
|
||||
collection.remove(extension);
|
||||
extension.removeOnReceiveMessageListener(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
extension.addOnReceiveMessageListener(respondCallback);
|
||||
|
||||
extension.sendMessage(manipulatePacketRequest);
|
||||
}
|
||||
|
||||
//block untill all extensions have responded
|
||||
List<GEarthExtension> willdelete = new ArrayList<>();
|
||||
while (!collection.isEmpty()) {
|
||||
for (GEarthExtension extension : collection) {
|
||||
if (!gEarthExtensions.contains(extension)) willdelete.add(extension);
|
||||
}
|
||||
for (int i = willdelete.size() - 1; i >= 0; i--) {
|
||||
collection.remove(willdelete.get(i));
|
||||
willdelete.remove(i);
|
||||
}
|
||||
|
||||
try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}
|
||||
}
|
||||
|
||||
if (isblock[0]) {
|
||||
message.setBlocked(true);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
GEarthExtensionsRegistrer extensionsRegistrer = null;
|
||||
HashMap<GEarthExtension, GEarthExtension.ReceiveMessageListener> messageListeners = new HashMap<>();
|
||||
try {
|
||||
extensionsRegistrer = new GEarthExtensionsRegistrer(new GEarthExtensionsRegistrer.ExtensionRegisterObserver() {
|
||||
@Override
|
||||
public void onConnect(GEarthExtension extension) {
|
||||
gEarthExtensions.add(extension);
|
||||
GEarthExtension.ReceiveMessageListener receiveMessageListener = message -> {
|
||||
if (message.headerId() == INCOMING_MESSAGES_IDS.REQUESTFLAGS) { // no body
|
||||
HPacket packet = new HPacket(OUTGOING_MESSAGES_IDS.FLAGSCHECK);
|
||||
packet.appendInt(Main.args.length);
|
||||
for (String arg : Main.args) {
|
||||
packet.appendString(arg);
|
||||
}
|
||||
extension.sendMessage(packet);
|
||||
}
|
||||
else if (message.headerId() == INCOMING_MESSAGES_IDS.SENDMESSAGE) {
|
||||
Byte side = message.readByte();
|
||||
int byteLength = message.readInteger();
|
||||
byte[] packetAsByteArray = message.readBytes(byteLength);
|
||||
|
||||
HPacket packet = new HPacket(packetAsByteArray);
|
||||
if (!packet.isCorrupted()) {
|
||||
if (side == 0) { // toclient
|
||||
getHConnection().sendToClientAsync(packet);
|
||||
}
|
||||
else if (side == 1) { // toserver
|
||||
getHConnection().sendToServerAsync(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
messageListeners.put(extension, receiveMessageListener);
|
||||
extension.addOnReceiveMessageListener(receiveMessageListener);
|
||||
|
||||
extension.sendMessage(new HPacket(OUTGOING_MESSAGES_IDS.INIT));
|
||||
if (getHConnection().getState() == HConnection.State.CONNECTED) {
|
||||
extension.sendMessage(new HPacket(OUTGOING_MESSAGES_IDS.CONNECTIONSTART));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnect(GEarthExtension extension) {
|
||||
gEarthExtensions.remove(extension);
|
||||
|
||||
extension.removeOnReceiveMessageListener(messageListeners.get(extension));
|
||||
messageListeners.remove(extension);
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("Extension server registered on port: " + extensionsRegistrer.getPort());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
169
src/main/ui/extensions/GEarthExtension.java
Normal file
169
src/main/ui/extensions/GEarthExtension.java
Normal file
@ -0,0 +1,169 @@
|
||||
package main.ui.extensions;
|
||||
|
||||
import main.protocol.HMessage;
|
||||
import main.protocol.HPacket;
|
||||
import main.protocol.packethandler.PayloadBuffer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.Socket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Jonas on 21/06/18.
|
||||
*/
|
||||
public class GEarthExtension {
|
||||
|
||||
private String title;
|
||||
private String author;
|
||||
private String version;
|
||||
private String description;
|
||||
|
||||
private Socket connection;
|
||||
|
||||
//calls callback when the extension is creatd
|
||||
static void create(Socket connection, OnCreatedCallback callback, OnDisconnectedCallback onDisconnectedCallback) {
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
connection.getOutputStream().write((new HPacket(Extensions.OUTGOING_MESSAGES_IDS.INFOREQUEST)).toBytes());
|
||||
connection.getOutputStream().flush();
|
||||
|
||||
PayloadBuffer payloadBuffer = new PayloadBuffer();
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
|
||||
outerloop:
|
||||
while (!connection.isClosed()) {
|
||||
if (inputStream.available() > 0) {
|
||||
byte[] incoming = new byte[inputStream.available()];
|
||||
inputStream.read(incoming);
|
||||
payloadBuffer.push(incoming);
|
||||
}
|
||||
|
||||
HPacket[] hPackets = payloadBuffer.receive();
|
||||
for (HPacket packet : hPackets) { // it should be only one packet
|
||||
if (packet.headerId() == Extensions.INCOMING_MESSAGES_IDS.EXTENSIONINFO) {
|
||||
|
||||
GEarthExtension gEarthExtension = new GEarthExtension(
|
||||
packet.readString(),
|
||||
packet.readString(),
|
||||
packet.readString(),
|
||||
packet.readString(),
|
||||
connection,
|
||||
onDisconnectedCallback
|
||||
);
|
||||
callback.act(gEarthExtension);
|
||||
|
||||
break outerloop;
|
||||
}
|
||||
}
|
||||
|
||||
Thread.sleep(1);
|
||||
}
|
||||
|
||||
} catch (IOException | InterruptedException ignored) {}
|
||||
}).start();
|
||||
|
||||
}
|
||||
|
||||
private GEarthExtension(String title, String author, String version, String description, Socket connection, OnDisconnectedCallback onDisconnectedCallback) {
|
||||
this.title = title;
|
||||
this.author = author;
|
||||
this.version = version;
|
||||
this.description = description;
|
||||
this.connection = connection;
|
||||
|
||||
GEarthExtension selff = this;
|
||||
new Thread(() -> {
|
||||
try {
|
||||
PayloadBuffer payloadBuffer = new PayloadBuffer();
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
|
||||
while (!connection.isClosed()) {
|
||||
if (inputStream.available() > 0) {
|
||||
byte[] incoming = new byte[inputStream.available()];
|
||||
inputStream.read(incoming);
|
||||
payloadBuffer.push(incoming);
|
||||
}
|
||||
|
||||
HPacket[] hPackets = payloadBuffer.receive();
|
||||
for (HPacket packet : hPackets) {
|
||||
for (int i = receiveMessageListeners.size() - 1; i >= 0; i--) {
|
||||
receiveMessageListeners.get(i).act(packet);
|
||||
}
|
||||
}
|
||||
|
||||
Thread.sleep(1);
|
||||
}
|
||||
onDisconnectedCallback.act(selff);
|
||||
|
||||
} catch (IOException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public Socket getConnection() {
|
||||
return connection;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean closeConnection() {
|
||||
try {
|
||||
connection.close();
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean sendMessage(HPacket message) {
|
||||
try {
|
||||
connection.getOutputStream().write(message.toBytes());
|
||||
connection.getOutputStream().flush();
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private List<ReceiveMessageListener> receiveMessageListeners = new ArrayList<>();
|
||||
public void addOnReceiveMessageListener(ReceiveMessageListener receiveMessageListener) {
|
||||
receiveMessageListeners.add(receiveMessageListener);
|
||||
}
|
||||
public void removeOnReceiveMessageListener(ReceiveMessageListener receiveMessageListener) {
|
||||
receiveMessageListeners.remove(receiveMessageListener);
|
||||
}
|
||||
|
||||
public interface ReceiveMessageListener {
|
||||
void act(HPacket message);
|
||||
}
|
||||
public interface OnCreatedCallback {
|
||||
void act(GEarthExtension extension); // returns itself
|
||||
}
|
||||
public interface OnDisconnectedCallback {
|
||||
void act(GEarthExtension extension); // returns itself
|
||||
}
|
||||
|
||||
}
|
35
src/main/ui/extensions/GEarthExtensionsRegistrer.java
Normal file
35
src/main/ui/extensions/GEarthExtensionsRegistrer.java
Normal file
@ -0,0 +1,35 @@
|
||||
package main.ui.extensions;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
|
||||
/**
|
||||
* Created by Jonas on 21/06/18.
|
||||
*/
|
||||
public class GEarthExtensionsRegistrer {
|
||||
|
||||
final ServerSocket serverSocket;
|
||||
|
||||
GEarthExtensionsRegistrer(ExtensionRegisterObserver observer) throws IOException {
|
||||
|
||||
serverSocket = new ServerSocket(0);
|
||||
new Thread(() -> {
|
||||
try {
|
||||
while (!serverSocket.isClosed()) {
|
||||
Socket extensionSocket = serverSocket.accept();
|
||||
GEarthExtension.create(extensionSocket, observer::onConnect, observer::onDisconnect);
|
||||
}
|
||||
} catch (IOException e) {e.printStackTrace();}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return serverSocket.getLocalPort();
|
||||
}
|
||||
|
||||
public interface ExtensionRegisterObserver {
|
||||
void onConnect(GEarthExtension extension);
|
||||
void onDisconnect(GEarthExtension extension);
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package main.ui.extensions.extensionfilemanager;
|
||||
|
||||
import main.ui.extensions.extensionfilemanager.extensionfile.ExtensionFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Jonas on 21/06/18.
|
||||
*/
|
||||
public interface ExtensionFilesManager {
|
||||
|
||||
List<ExtensionFile> getAllExtensions();
|
||||
|
||||
ExtensionFile addExtension(File file); //returns g-earth extension file, returns null if failure
|
||||
|
||||
boolean removeExtension(ExtensionFile file); //returns false if not done
|
||||
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package main.ui.extensions.extensionfilemanager;
|
||||
|
||||
/**
|
||||
* Created by Jonas on 21/06/18.
|
||||
*/
|
||||
public class ExtensionFilesManagerFactory {
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package main.ui.extensions.extensionfilemanager;
|
||||
|
||||
import main.ui.extensions.extensionfilemanager.extensionfile.ExtensionFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Jonas on 21/06/18.
|
||||
*/
|
||||
public class LinuxExtensionFilesManager implements ExtensionFilesManager {
|
||||
|
||||
@Override
|
||||
public List<ExtensionFile> getAllExtensions() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtensionFile addExtension(File file) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeExtension(ExtensionFile file) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package main.ui.extensions.extensionfilemanager.extensionfile;
|
||||
|
||||
/**
|
||||
* Created by Jonas on 21/06/18.
|
||||
*/
|
||||
public class ExtensionFile {
|
||||
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user