Skip to content

Commit

Permalink
Implement Wrapped Messages and Responses
Browse files Browse the repository at this point in the history
  • Loading branch information
bundabrg committed Jun 22, 2020
1 parent e1f2486 commit 5fa5750
Show file tree
Hide file tree
Showing 26 changed files with 293 additions and 75 deletions.
83 changes: 68 additions & 15 deletions common/src/main/java/au/com/grieve/geyserlink/GeyserLink.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,22 @@

import au.com.grieve.geyserlink.config.Configuration;
import au.com.grieve.geyserlink.config.Dynamic;
import au.com.grieve.geyserlink.messages.GeyserLinkMessage;
import au.com.grieve.geyserlink.messages.GeyserLinkResponse;
import au.com.grieve.geyserlink.messages.GeyserLinkSignedMessage;
import au.com.grieve.geyserlink.message.messages.GeyserLinkMessage;
import au.com.grieve.geyserlink.message.messages.PingMessage;
import au.com.grieve.geyserlink.message.messages.WrappedMessage;
import au.com.grieve.geyserlink.message.responses.GeyserLinkResponse;
import au.com.grieve.geyserlink.message.responses.PingResponse;
import au.com.grieve.geyserlink.message.responses.WrappedResponse;
import au.com.grieve.geyserlink.message.wrappers.GeyserLinkSignedMessage;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.security.KeyPair;
import java.security.PublicKey;
import java.util.Base64;
Expand Down Expand Up @@ -144,7 +150,7 @@ protected void generateConfig() {
}

/**
* Send GeyserLink Signed Message
* Send Raw GeyserLink Signed Message
*/
public MessageResult sendMessage(Object recipient, String channel, String subChannel, byte[] data) {
GeyserLinkMessage message = new GeyserLinkMessage(
Expand All @@ -154,12 +160,19 @@ public MessageResult sendMessage(Object recipient, String channel, String subCha
subChannel,
Base64.getEncoder().encodeToString(data)
);
GeyserLinkSignedMessage<GeyserLinkMessage> signedMessage = GeyserLinkSignedMessage.createSignedMessage(message, keyPair.getPrivate(), GeyserLinkMessage.class);

GeyserLinkSignedMessage<GeyserLinkMessage> signedMessage = GeyserLinkSignedMessage.createSignedMessage(message, keyPair.getPrivate(), GeyserLinkMessage.class);
platform.sendPluginMessage(recipient, "geyserlink:message", signedMessage);
return new MessageResult(this, recipient, message);
}

/**
* Send a Wrapped Message Object
*/
public MessageResult sendMessage(Object recipient, WrappedMessage message) {
return sendMessage(recipient, message.getChannel(), message.getSubChannel(), message.getBytes());
}

/**
* Send GeyserLink Response Message
*/
Expand All @@ -174,18 +187,26 @@ public void sendResponse(Object recipient, GeyserLinkMessage message, byte[] dat
platform.sendPluginMessage(recipient, "geyserlink:response", signedMessage);
}

public void sendResponse(Object recipient, GeyserLinkMessage message, WrappedResponse response) {
sendResponse(recipient, message, response.getBytes());
}

/**
* Built in Messages
*/
@SuppressWarnings("SwitchStatementWithTooFewBranches")
public void handleMainMessage(Object sender, GeyserLinkSignedMessage<GeyserLinkMessage> message) {
switch (message.getWrappedMessage().getSubChannel()) {
switch (message.getMessage().getSubChannel()) {
case "ping":
sendResponse(
sender,
message.getWrappedMessage(),
message.getWrappedMessage().getPayload().getBytes()
);
try {
PingMessage pingMessage = new PingMessage(PingMessage.from(Base64.getDecoder().decode(message.getMessage().getPayload())));
sendResponse(
sender,
message.getMessage(),
new PingResponse(pingMessage.getData()));
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
Expand All @@ -194,11 +215,11 @@ public void handleMainMessage(Object sender, GeyserLinkSignedMessage<GeyserLinkM
* Handle Responses
*/
public void handleResponse(Object sender, GeyserLinkSignedMessage<GeyserLinkResponse> message) {
if (!message.getWrappedMessage().getRecipient().equals(myUUID)) {
if (!message.getMessage().getRecipient().equals(myUUID)) {
return;
}

MessageResult.ResponseRunnable runnable = responseMap.get(message.getWrappedMessage().getId());
MessageResult.ResponseRunnable runnable = responseMap.get(message.getMessage().getId());
if (runnable != null) {
runnable.run(message);
}
Expand All @@ -216,15 +237,15 @@ public MessageResult onResponse(Runnable runnable, long timeout, long expiry) {
// Clean up after a timeout
IScheduledTask timeoutTask = geyserLink.getPlatform().schedule(() -> geyserLink.getResponseMap().remove(message.getId()), timeout);

geyserLink.getResponseMap().put(message.getId(), (response) -> {
geyserLink.getResponseMap().put(message.getId(), response -> {
// Cancel cleanup
timeoutTask.cancel();

// Set expiry
geyserLink.getPlatform().schedule(() -> geyserLink.getResponseMap().remove(message.getId()), expiry);

// Execute
runnable.run(this, response);
runnable.run(MessageResult.this, response);
});

return this;
Expand All @@ -234,6 +255,38 @@ public MessageResult onResponse(Runnable runnable) {
return onResponse(runnable, 300, 30);
}

public <T extends WrappedResponse> MessageResult onResponse(Class<T> responseClass, WrappedRunnable<T> runnable, long timeout, long expiry) {
// Clean up after a timeout
IScheduledTask timeoutTask = geyserLink.getPlatform().schedule(() -> geyserLink.getResponseMap().remove(message.getId()), timeout);

geyserLink.getResponseMap().put(message.getId(), response -> {
// Cancel cleanup
timeoutTask.cancel();

// Set expiry
geyserLink.getPlatform().schedule(() -> geyserLink.getResponseMap().remove(message.getId()), expiry);

// Execute
try {
runnable.run(MessageResult.this, response, responseClass.getConstructor(JsonNode.class).newInstance(WrappedResponse.from(Base64.getDecoder().decode(response.getMessage().getPayload()))));
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | IOException e) {
e.printStackTrace();
}
});

return this;
}

// Wrapped Response
public <T extends WrappedResponse> MessageResult onResponse(Class<T> responseClass, WrappedRunnable<T> runnable) {
return onResponse(responseClass, runnable, 300, 30);
}


public interface WrappedRunnable<T extends WrappedResponse> {
void run(MessageResult result, GeyserLinkSignedMessage<GeyserLinkResponse> response, T wrapped);
}

public interface Runnable {
void run(MessageResult result, GeyserLinkSignedMessage<GeyserLinkResponse> response);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

package au.com.grieve.geyserlink;

import au.com.grieve.geyserlink.messages.GeyserLinkSignedMessage;
import au.com.grieve.geyserlink.message.wrappers.GeyserLinkSignedMessage;

import java.io.File;
import java.io.InputStream;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package au.com.grieve.geyserlink.messages;
package au.com.grieve.geyserlink.message;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package au.com.grieve.geyserlink.messages;
package au.com.grieve.geyserlink.message.messages;

import au.com.grieve.geyserlink.message.wrappers.EnvelopeMessage;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.Getter;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* GeyserLink - The Missing Link
* Copyright (C) 2020 GeyserLink Developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package au.com.grieve.geyserlink.message.messages;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.Getter;
import lombok.ToString;


@Getter
@ToString(callSuper = true)
public class PingMessage extends WrappedMessage {
private final String channel = "geyserlink:main";
private final String subChannel = "ping";

private final String data;

public PingMessage(String data) {
super();
this.data = data;
}

public PingMessage(JsonNode node) {
super(node);
this.data = node.get("data").asText();
}

@Override
protected ObjectNode serialize() {
return super.serialize()
.put("data", data);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* GeyserLink - The Missing Link
* Copyright (C) 2020 GeyserLink Developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package au.com.grieve.geyserlink.message.messages;

import au.com.grieve.geyserlink.message.BaseMessage;
import com.fasterxml.jackson.databind.JsonNode;

public abstract class WrappedMessage extends BaseMessage {
public WrappedMessage() {
super();
}

public WrappedMessage(JsonNode node) {
super(node);
}

public abstract String getChannel();

public abstract String getSubChannel();
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package au.com.grieve.geyserlink.messages;
package au.com.grieve.geyserlink.message.responses;

import au.com.grieve.geyserlink.message.wrappers.EnvelopeMessage;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.Getter;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* GeyserLink - The Missing Link
* Copyright (C) 2020 GeyserLink Developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package au.com.grieve.geyserlink.message.responses;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.Getter;
import lombok.ToString;


@Getter
@ToString(callSuper = true)
public class PingResponse extends WrappedResponse {
private final String data;

public PingResponse(String data) {
super();

this.data = data;
}

public PingResponse(JsonNode node) {
super(node);
this.data = node.get("data").asText();
}

@Override
protected ObjectNode serialize() {
return super.serialize()
.put("data", data);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* GeyserLink - The Missing Link
* Copyright (C) 2020 GeyserLink Developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package au.com.grieve.geyserlink.message.responses;

import au.com.grieve.geyserlink.message.BaseMessage;
import com.fasterxml.jackson.databind.JsonNode;

public abstract class WrappedResponse extends BaseMessage {

public WrappedResponse() {
super();
}

public WrappedResponse(JsonNode node) {
super(node);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package au.com.grieve.geyserlink.messages;
package au.com.grieve.geyserlink.message.wrappers;

import au.com.grieve.geyserlink.message.BaseMessage;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.Getter;
Expand Down
Loading

0 comments on commit 5fa5750

Please sign in to comment.