Add system for sending messages between servers

This commit is contained in:
KingRainbow44 2023-05-30 13:06:50 -04:00
parent a3c56dff7e
commit c780fb7934
No known key found for this signature in database
GPG Key ID: FC2CB64B00D257BE
5 changed files with 133 additions and 18 deletions

View File

@ -1,17 +1,22 @@
package emu.grasscutter.server.dispatch; package emu.grasscutter.server.dispatch;
import static emu.grasscutter.config.Configuration.DISPATCH_INFO;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.server.event.dispatch.ServerMessageEvent;
import emu.grasscutter.server.game.GameServer; import emu.grasscutter.server.game.GameServer;
import emu.grasscutter.server.http.handlers.GachaHandler; import emu.grasscutter.server.http.handlers.GachaHandler;
import emu.grasscutter.utils.Crypto; import emu.grasscutter.utils.Crypto;
import emu.grasscutter.utils.DispatchUtils; import emu.grasscutter.utils.DispatchUtils;
import emu.grasscutter.utils.JsonUtils; import emu.grasscutter.utils.JsonUtils;
import emu.grasscutter.utils.objects.HandbookBody; import emu.grasscutter.utils.objects.HandbookBody;
import lombok.Getter;
import org.java_websocket.WebSocket;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.slf4j.Logger;
import java.net.ConnectException; import java.net.ConnectException;
import java.net.URI; import java.net.URI;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -22,11 +27,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
import lombok.Getter;
import org.java_websocket.WebSocket; import static emu.grasscutter.config.Configuration.DISPATCH_INFO;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.slf4j.Logger;
public final class DispatchClient extends WebSocketClient implements IDispatcher { public final class DispatchClient extends WebSocketClient implements IDispatcher {
@Getter private final Logger logger = Grasscutter.getLogger(); @Getter private final Logger logger = Grasscutter.getLogger();
@ -44,6 +46,7 @@ public final class DispatchClient extends WebSocketClient implements IDispatcher
this.registerHandler(PacketIds.GmTalkReq, this::handleHandbookAction); this.registerHandler(PacketIds.GmTalkReq, this::handleHandbookAction);
this.registerHandler(PacketIds.GetPlayerFieldsReq, this::fetchPlayerFields); this.registerHandler(PacketIds.GetPlayerFieldsReq, this::fetchPlayerFields);
this.registerHandler(PacketIds.GetPlayerByAccountReq, this::fetchPlayerByAccount); this.registerHandler(PacketIds.GetPlayerByAccountReq, this::fetchPlayerByAccount);
this.registerHandler(PacketIds.ServerMessageNotify, ServerMessageEvent::invoke);
} }
/** /**

View File

@ -1,12 +1,17 @@
package emu.grasscutter.server.dispatch; package emu.grasscutter.server.dispatch;
import static emu.grasscutter.config.Configuration.DISPATCH_INFO;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.server.event.dispatch.ServerMessageEvent;
import emu.grasscutter.utils.Crypto; import emu.grasscutter.utils.Crypto;
import lombok.Getter;
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import org.slf4j.Logger;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -15,11 +20,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
import lombok.Getter;
import org.java_websocket.WebSocket; import static emu.grasscutter.config.Configuration.DISPATCH_INFO;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import org.slf4j.Logger;
/* Internal communications server. */ /* Internal communications server. */
public final class DispatchServer extends WebSocketServer implements IDispatcher { public final class DispatchServer extends WebSocketServer implements IDispatcher {
@ -40,6 +42,7 @@ public final class DispatchServer extends WebSocketServer implements IDispatcher
this.registerHandler(PacketIds.LoginNotify, this::handleLogin); this.registerHandler(PacketIds.LoginNotify, this::handleLogin);
this.registerHandler(PacketIds.TokenValidateReq, this::validateToken); this.registerHandler(PacketIds.TokenValidateReq, this::validateToken);
this.registerHandler(PacketIds.GetAccountReq, this::fetchAccount); this.registerHandler(PacketIds.GetAccountReq, this::fetchAccount);
this.registerHandler(PacketIds.ServerMessageNotify, ServerMessageEvent::invoke);
} }
/** /**

View File

@ -1,7 +1,5 @@
package emu.grasscutter.server.dispatch; package emu.grasscutter.server.dispatch;
import static emu.grasscutter.config.Configuration.DISPATCH_INFO;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
@ -9,7 +7,11 @@ import com.google.gson.JsonObject;
import emu.grasscutter.utils.Crypto; import emu.grasscutter.utils.Crypto;
import emu.grasscutter.utils.JsonAdapters.ByteArrayAdapter; import emu.grasscutter.utils.JsonAdapters.ByteArrayAdapter;
import emu.grasscutter.utils.objects.JObject; import emu.grasscutter.utils.objects.JObject;
import org.java_websocket.WebSocket;
import org.slf4j.Logger;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -18,8 +20,8 @@ import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import org.java_websocket.WebSocket;
import org.slf4j.Logger; import static emu.grasscutter.config.Configuration.DISPATCH_INFO;
public interface IDispatcher { public interface IDispatcher {
Gson JSON = Gson JSON =
@ -246,6 +248,51 @@ public interface IDispatcher {
this.getCallbacks().get(packetId).add(callback); this.getCallbacks().get(packetId).add(callback);
} }
/**
* Sends a server message to the client.
*
* @param data The data to send.
* @param binary Whether the data is binary.
*/
default void sendServerMessage(byte[] data, boolean binary) {
var message = new JObject()
.add("binary", binary)
.add("data", Base64.getEncoder().encodeToString(data))
.gson();
this.sendMessage(PacketIds.ServerMessageNotify, message);
}
/**
* Sends a server message to the client.
* The data is sent as a string.
*
* @param data The data to send.
*/
default void sendServerMessage(String data) {
this.sendServerMessage(data.getBytes(), false);
}
/**
* Sends a server message to the client.
* The data is sent as a byte array.
*
* @param data The data to send.
*/
default void sendServerMessage(byte[] data) {
this.sendServerMessage(data, true);
}
/**
* Sends a server message to the client.
* The data is sent as a JSON object.
*
* @param data The data to send.
*/
default void sendServerMessage(Object data) {
this.sendServerMessage(JSON.toJson(data));
}
/** /**
* @return The logger for the dispatcher. * @return The logger for the dispatcher.
*/ */

View File

@ -17,4 +17,5 @@ public interface PacketIds {
int GetPlayerFieldsRsp = 9; int GetPlayerFieldsRsp = 9;
int GetPlayerByAccountReq = 10; int GetPlayerByAccountReq = 10;
int GetPlayerByAccountRsp = 11; int GetPlayerByAccountRsp = 11;
int ServerMessageNotify = 12;
} }

View File

@ -0,0 +1,61 @@
package emu.grasscutter.server.event.dispatch;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import emu.grasscutter.server.dispatch.IDispatcher;
import emu.grasscutter.server.event.Event;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.java_websocket.WebSocket;
import java.util.Base64;
@Getter
@RequiredArgsConstructor
public final class ServerMessageEvent extends Event {
/**
* Invokes the event.
*
* @param client The client that sent the message.
* @param object The message.
*/
public static void invoke(WebSocket client, JsonElement object) {
var message = IDispatcher.decode(object);
var isBinary = message.get("binary").getAsBoolean();
var data = Base64.getDecoder().decode(
message.get("data").getAsString());
// Create the event and invoke it.
new ServerMessageEvent(client, isBinary, data).call();
}
private final WebSocket client;
private final boolean isBinary;
private final byte[] message;
/**
* @return The message as a string.
*/
public String asString() {
if (this.isBinary)
throw new UnsupportedOperationException("Cannot convert binary message to string.");
return new String(this.message);
}
/**
* @return The message as a JSON object.
*/
public JsonObject asJson() {
return IDispatcher.JSON.fromJson(
this.asString(), JsonObject.class);
}
/**
* @return The message as a JSON object.
* The type is specified.
*/
public <T> T asJson(Class<T> type) {
return IDispatcher.JSON.fromJson(
this.asString(), type);
}
}