From 07469599bc5b247c367b4ba77e88df37e168af48 Mon Sep 17 00:00:00 2001 From: Luck Date: Sun, 15 Jul 2018 22:42:37 -0700 Subject: [PATCH] Rewrite MessagingService message encoding, conform to new plugin message channel requirements * This change isn't backwards compatible with previous builds, this version (& onwards) won't be able to "communicate" with old versions, and vice versa. * MC 1.13 requires plugin message channel names to be namespaced, so 'lpuc' has been changed to 'luckperms:update' * The channel names for Redis/Lily types have also changed, I've been wanting to change the encoded format to something a bit saner for a while, and this seemed like a good time. Changing the channel names a) keeps things consistent and b) means I don't have to worry about old versions interpreting the new format. --- .../bukkit/messaging/BungeeMessenger.java | 2 +- .../bukkit/messaging/LilyPadMessenger.java | 2 +- .../bungee/messaging/BungeeMessenger.java | 2 +- .../messaging/RedisBungeeMessenger.java | 2 +- .../actionlog/LogEntryJsonSerializer.java | 72 ++++++++ .../messaging/LuckPermsMessagingService.java | 171 ++++++++++++------ .../messaging/message/LogMessageImpl.java | 90 ++------- .../messaging/message/UpdateMessageImpl.java | 38 +--- .../message/UserUpdateMessageImpl.java | 52 +++--- .../messaging/redis/RedisMessenger.java | 2 +- .../storage/dao/file/FileActionLogger.java | 38 +--- .../sponge/messaging/BungeeMessenger.java | 2 +- 12 files changed, 238 insertions(+), 235 deletions(-) create mode 100644 common/src/main/java/me/lucko/luckperms/common/actionlog/LogEntryJsonSerializer.java diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/messaging/BungeeMessenger.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/messaging/BungeeMessenger.java index 414b1c4f4..690487742 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/messaging/BungeeMessenger.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/messaging/BungeeMessenger.java @@ -47,7 +47,7 @@ import javax.annotation.Nonnull; * An implementation of {@link Messenger} using the plugin messaging channels. */ public class BungeeMessenger implements Messenger, PluginMessageListener { - private static final String CHANNEL = "lpuc"; + private static final String CHANNEL = "luckperms:update"; private final LPBukkitPlugin plugin; private final IncomingMessageConsumer consumer; diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/messaging/LilyPadMessenger.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/messaging/LilyPadMessenger.java index 9b10ea47d..45571f6cb 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/messaging/LilyPadMessenger.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/messaging/LilyPadMessenger.java @@ -45,7 +45,7 @@ import javax.annotation.Nonnull; * An implementation of {@link Messenger} using LilyPad. */ public class LilyPadMessenger implements Messenger { - private static final String CHANNEL = "lpuc"; + private static final String CHANNEL = "luckperms:update"; private final LPBukkitPlugin plugin; private final IncomingMessageConsumer consumer; diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/messaging/BungeeMessenger.java b/bungee/src/main/java/me/lucko/luckperms/bungee/messaging/BungeeMessenger.java index 2ee59941c..2bd0f720f 100644 --- a/bungee/src/main/java/me/lucko/luckperms/bungee/messaging/BungeeMessenger.java +++ b/bungee/src/main/java/me/lucko/luckperms/bungee/messaging/BungeeMessenger.java @@ -46,7 +46,7 @@ import javax.annotation.Nonnull; * An implementation of {@link Messenger} using the plugin messaging channels. */ public class BungeeMessenger implements Messenger, Listener { - private static final String CHANNEL = "lpuc"; + private static final String CHANNEL = "luckperms:update"; private final LPBungeePlugin plugin; private final IncomingMessageConsumer consumer; diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/messaging/RedisBungeeMessenger.java b/bungee/src/main/java/me/lucko/luckperms/bungee/messaging/RedisBungeeMessenger.java index 549494658..8d19d4fb6 100644 --- a/bungee/src/main/java/me/lucko/luckperms/bungee/messaging/RedisBungeeMessenger.java +++ b/bungee/src/main/java/me/lucko/luckperms/bungee/messaging/RedisBungeeMessenger.java @@ -43,7 +43,7 @@ import javax.annotation.Nonnull; * An implementation of {@link Messenger} using Redis, via RedisBungee's API. */ public class RedisBungeeMessenger implements Messenger, Listener { - private static final String CHANNEL = "lpuc"; + private static final String CHANNEL = "luckperms:update"; private final LPBungeePlugin plugin; private final IncomingMessageConsumer consumer; diff --git a/common/src/main/java/me/lucko/luckperms/common/actionlog/LogEntryJsonSerializer.java b/common/src/main/java/me/lucko/luckperms/common/actionlog/LogEntryJsonSerializer.java new file mode 100644 index 000000000..38fb146f9 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/common/actionlog/LogEntryJsonSerializer.java @@ -0,0 +1,72 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.lucko.luckperms.common.actionlog; + +import com.google.common.base.Preconditions; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; + +import me.lucko.luckperms.api.LogEntry; + +import java.util.UUID; + +public final class LogEntryJsonSerializer { + + public static JsonObject serialize(LogEntry logEntry) { + JsonObject data = new JsonObject(); + data.add("actor", new JsonPrimitive(logEntry.getActor().toString())); + data.add("actorName", new JsonPrimitive(logEntry.getActorName())); + data.add("type", new JsonPrimitive(logEntry.getType().name())); + if (logEntry.getActed().isPresent()) { + data.add("acted", new JsonPrimitive(logEntry.getActed().get().toString())); + } + data.add("actedName", new JsonPrimitive(logEntry.getActedName())); + data.add("action", new JsonPrimitive(logEntry.getAction())); + + return data; + } + + public static ExtendedLogEntry deserialize(JsonElement element) { + Preconditions.checkArgument(element.isJsonObject()); + JsonObject data = element.getAsJsonObject(); + + ExtendedLogEntry.Builder builder = ExtendedLogEntry.build(); + + builder.actor(UUID.fromString(data.get("actor").getAsString())); + builder.actorName(data.get("actorName").getAsString()); + builder.type(LogEntry.Type.valueOf(data.get("type").getAsString())); + if (data.has("acted")) { + builder.actor(UUID.fromString(data.get("acted").getAsString())); + } + builder.actedName(data.get("actedName").getAsString()); + builder.action(data.get("action").getAsString()); + + return builder.build(); + } + + private LogEntryJsonSerializer() {} +} diff --git a/common/src/main/java/me/lucko/luckperms/common/messaging/LuckPermsMessagingService.java b/common/src/main/java/me/lucko/luckperms/common/messaging/LuckPermsMessagingService.java index e469ae070..e6f4ae5a0 100644 --- a/common/src/main/java/me/lucko/luckperms/common/messaging/LuckPermsMessagingService.java +++ b/common/src/main/java/me/lucko/luckperms/common/messaging/LuckPermsMessagingService.java @@ -25,6 +25,11 @@ package me.lucko.luckperms.common.messaging; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + import me.lucko.luckperms.api.LogEntry; import me.lucko.luckperms.api.messenger.IncomingMessageConsumer; import me.lucko.luckperms.api.messenger.Messenger; @@ -41,6 +46,7 @@ import me.lucko.luckperms.common.messaging.message.UpdateMessageImpl; import me.lucko.luckperms.common.messaging.message.UserUpdateMessageImpl; import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; +import me.lucko.luckperms.common.utils.gson.JObject; import java.util.Collections; import java.util.HashSet; @@ -50,8 +56,11 @@ import java.util.UUID; import java.util.concurrent.TimeUnit; import javax.annotation.Nonnull; +import javax.annotation.Nullable; public class LuckPermsMessagingService implements InternalMessagingService, IncomingMessageConsumer { + private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().create(); + private final LuckPermsPlugin plugin; private final Set receivedMessages; private final PushUpdateBuffer updateBuffer; @@ -137,77 +146,127 @@ public class LuckPermsMessagingService implements InternalMessagingService, Inco public boolean consumeIncomingMessage(@Nonnull Message message) { Objects.requireNonNull(message, "message"); - if (message instanceof UpdateMessage) { - UpdateMessage msg = (UpdateMessage) message; - if (!this.receivedMessages.add(msg.getId())) { - return false; - } - - this.plugin.getLogger().info("[" + getName() + " Messaging] Received update ping with id: " + msg.getId()); - - if (this.plugin.getEventFactory().handleNetworkPreSync(false, msg.getId())) { - return true; - } - - this.plugin.getUpdateTaskBuffer().request(); - return true; - - } else if (message instanceof UserUpdateMessage) { - UserUpdateMessage msg = (UserUpdateMessage) message; - if (!this.receivedMessages.add(msg.getId())) { - return false; - } - - User user = this.plugin.getUserManager().getIfLoaded(msg.getUser()); - if (user == null) { - return true; - } - - this.plugin.getLogger().info("[" + getName() + " Messaging] Received user update ping for '" + user.getFriendlyName() + "' with id: " + msg.getId()); - - if (this.plugin.getEventFactory().handleNetworkPreSync(false, msg.getId())) { - return true; - } - - this.plugin.getStorage().loadUser(user.getUuid(), null); - return true; - - } else if (message instanceof LogMessage) { - LogMessage msg = (LogMessage) message; - if (!this.receivedMessages.add(msg.getId())) { - return false; - } - - this.plugin.getEventFactory().handleLogReceive(msg.getId(), msg.getLogEntry()); - this.plugin.getLogDispatcher().dispatchFromRemote((ExtendedLogEntry) msg.getLogEntry()); - return true; - - } else { - this.plugin.getLogger().warn("Unable to decode incoming message: " + message + " (" + message.getClass().getName() + ")"); + if (!this.receivedMessages.add(message.getId())) { return false; } + + // determine if the message can be handled by us + boolean valid = message instanceof UpdateMessage || + message instanceof UserUpdateMessage || + message instanceof LogMessage; + + // instead of throwing an exception here, just return false + // it means an instance of LP can gracefully handle messages it doesn't + // "understand" yet. (sent from an instance running a newer version, etc) + if (!valid) { + return false; + } + + processIncomingMessage(message); + return true; } @Override public boolean consumeIncomingMessageAsString(@Nonnull String encodedString) { Objects.requireNonNull(encodedString, "encodedString"); + JsonObject decodedObject = GSON.fromJson(encodedString, JsonObject.class).getAsJsonObject(); - Message decoded = UpdateMessageImpl.decode(encodedString); - if (decoded != null) { - return consumeIncomingMessage(decoded); + // extract id + JsonElement idElement = decodedObject.get("id"); + if (idElement == null) { + throw new IllegalStateException("Incoming message has no id argument: " + encodedString); + } + UUID id = UUID.fromString(idElement.getAsString()); + + // ensure the message hasn't been received already + if (!this.receivedMessages.add(id)) { + return false; } - decoded = UserUpdateMessageImpl.decode(encodedString); - if (decoded != null) { - return consumeIncomingMessage(decoded); + // extract type + JsonElement typeElement = decodedObject.get("type"); + if (typeElement == null) { + throw new IllegalStateException("Incoming message has no type argument: " + encodedString); + } + String type = typeElement.getAsString(); + + // extract content + @Nullable JsonElement content = decodedObject.get("content"); + + // decode message + Message decoded; + switch (type) { + case UpdateMessageImpl.TYPE: + decoded = UpdateMessageImpl.decode(content, id); + break; + case UserUpdateMessageImpl.TYPE: + decoded = UserUpdateMessageImpl.decode(content, id); + break; + case LogMessageImpl.TYPE: + decoded = LogMessageImpl.decode(content, id); + break; + default: + // gracefully return if we just don't recognise the type + return false; } - decoded = LogMessageImpl.decode(encodedString); - return decoded != null && consumeIncomingMessage(decoded); + // consume the message + processIncomingMessage(decoded); + return true; + } + + public static String encodeMessageAsString(String type, UUID id, @Nullable JsonElement content) { + JsonObject json = new JObject() + .add("id", id.toString()) + .add("type", type) + .consume(o -> { + if (content != null) { + o.add("content", content); + } + }) + .toJson(); + + return GSON.toJson(json); + } + + private void processIncomingMessage(Message message) { + if (message instanceof UpdateMessage) { + UpdateMessage msg = (UpdateMessage) message; + + this.plugin.getLogger().info("[" + getName() + " Messaging] Received update ping with id: " + msg.getId()); + + if (this.plugin.getEventFactory().handleNetworkPreSync(false, msg.getId())) { + return; + } + + this.plugin.getUpdateTaskBuffer().request(); + } else if (message instanceof UserUpdateMessage) { + UserUpdateMessage msg = (UserUpdateMessage) message; + + User user = this.plugin.getUserManager().getIfLoaded(msg.getUser()); + if (user == null) { + return; + } + + this.plugin.getLogger().info("[" + getName() + " Messaging] Received user update ping for '" + user.getFriendlyName() + "' with id: " + msg.getId()); + + if (this.plugin.getEventFactory().handleNetworkPreSync(false, msg.getId())) { + return; + } + + this.plugin.getStorage().loadUser(user.getUuid(), null); + } else if (message instanceof LogMessage) { + LogMessage msg = (LogMessage) message; + + this.plugin.getEventFactory().handleLogReceive(msg.getId(), msg.getLogEntry()); + this.plugin.getLogDispatcher().dispatchFromRemote((ExtendedLogEntry) msg.getLogEntry()); + } else { + throw new IllegalArgumentException("Unknown message type: " + message.getClass().getName()); + } } private final class PushUpdateBuffer extends BufferedRequest { - public PushUpdateBuffer(LuckPermsPlugin plugin) { + PushUpdateBuffer(LuckPermsPlugin plugin) { super(2, TimeUnit.SECONDS, plugin.getBootstrap().getScheduler()); } diff --git a/common/src/main/java/me/lucko/luckperms/common/messaging/message/LogMessageImpl.java b/common/src/main/java/me/lucko/luckperms/common/messaging/message/LogMessageImpl.java index 37be3215f..fb5bbf379 100644 --- a/common/src/main/java/me/lucko/luckperms/common/messaging/message/LogMessageImpl.java +++ b/common/src/main/java/me/lucko/luckperms/common/messaging/message/LogMessageImpl.java @@ -25,37 +25,27 @@ package me.lucko.luckperms.common.messaging.message; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonObject; -import com.google.gson.JsonPrimitive; +import com.google.gson.JsonElement; import me.lucko.luckperms.api.LogEntry; import me.lucko.luckperms.api.messenger.message.type.LogMessage; -import me.lucko.luckperms.common.actionlog.ExtendedLogEntry; +import me.lucko.luckperms.common.actionlog.LogEntryJsonSerializer; +import me.lucko.luckperms.common.messaging.LuckPermsMessagingService; -import java.nio.ByteBuffer; -import java.util.Base64; import java.util.UUID; import javax.annotation.Nonnull; +import javax.annotation.Nullable; public class LogMessageImpl extends AbstractMessage implements LogMessage { - private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().create(); - private static final String LOG_HEADER = "log"; + public static final String TYPE = "log"; - public static LogMessageImpl decode(String msg) { - if (msg.startsWith(LOG_HEADER) && msg.length() > LOG_HEADER.length()) { - String content = msg.substring(LOG_HEADER.length()); - - try { - return decodeContent(GSON.fromJson(content, JsonObject.class)); - } catch (Exception e) { - return null; - } + public static LogMessageImpl decode(@Nullable JsonElement content, UUID id) { + if (content == null) { + throw new IllegalStateException("Missing content"); } - return null; + return new LogMessageImpl(id, LogEntryJsonSerializer.deserialize(content)); } private final LogEntry logEntry; @@ -74,65 +64,9 @@ public class LogMessageImpl extends AbstractMessage implements LogMessage { @Nonnull @Override public String asEncodedString() { - return LOG_HEADER + GSON.toJson(encodeContent(uuidToString(getId()), this.logEntry)); - } - - private static String uuidToString(UUID uuid) { - ByteBuffer buf = ByteBuffer.allocate(Long.BYTES * 2); - buf.putLong(uuid.getMostSignificantBits()); - buf.putLong(uuid.getLeastSignificantBits()); - return Base64.getEncoder().encodeToString(buf.array()); - } - - private static UUID uuidFromString(String s) { - try { - byte[] bytes = Base64.getDecoder().decode(s); - ByteBuffer buf = ByteBuffer.wrap(bytes); - return new UUID(buf.getLong(), buf.getLong()); - } catch (IllegalArgumentException e) { - return null; - } - } - - private static JsonObject encodeContent(String id, LogEntry entry) { - JsonObject data = new JsonObject(); - - data.add("id", new JsonPrimitive(id)); - data.add("actor", new JsonPrimitive(entry.getActor().toString())); - data.add("actorName", new JsonPrimitive(entry.getActorName())); - data.add("type", new JsonPrimitive(entry.getType().name())); - if (entry.getActed().isPresent()) { - data.add("acted", new JsonPrimitive(entry.getActed().get().toString())); - } - data.add("actedName", new JsonPrimitive(entry.getActedName())); - data.add("action", new JsonPrimitive(entry.getAction())); - - return data; - } - - private static LogMessageImpl decodeContent(JsonObject object) { - ExtendedLogEntry.Builder builder = ExtendedLogEntry.build(); - - String id = object.get("id").getAsString(); - if (id == null) { - return null; - } - - UUID uuid = uuidFromString(id); - if (uuid == null) { - return null; - } - - builder.actor(UUID.fromString(object.get("actor").getAsString())); - builder.actorName(object.get("actorName").getAsString()); - builder.type(LogEntry.Type.valueOf(object.get("type").getAsString())); - if (object.has("acted")) { - builder.actor(UUID.fromString(object.get("acted").getAsString())); - } - builder.actedName(object.get("actedName").getAsString()); - builder.action(object.get("action").getAsString()); - - return new LogMessageImpl(uuid, builder.build()); + return LuckPermsMessagingService.encodeMessageAsString( + TYPE, getId(), LogEntryJsonSerializer.serialize(logEntry) + ); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/messaging/message/UpdateMessageImpl.java b/common/src/main/java/me/lucko/luckperms/common/messaging/message/UpdateMessageImpl.java index 636c0fd57..876393b12 100644 --- a/common/src/main/java/me/lucko/luckperms/common/messaging/message/UpdateMessageImpl.java +++ b/common/src/main/java/me/lucko/luckperms/common/messaging/message/UpdateMessageImpl.java @@ -25,24 +25,21 @@ package me.lucko.luckperms.common.messaging.message; -import me.lucko.luckperms.api.messenger.message.type.UpdateMessage; +import com.google.gson.JsonElement; + +import me.lucko.luckperms.api.messenger.message.type.UpdateMessage; +import me.lucko.luckperms.common.messaging.LuckPermsMessagingService; -import java.nio.ByteBuffer; -import java.util.Base64; import java.util.UUID; import javax.annotation.Nonnull; +import javax.annotation.Nullable; public class UpdateMessageImpl extends AbstractMessage implements UpdateMessage { - private static final String UPDATE_HEADER = "update:"; + public static final String TYPE = "update"; - public static UpdateMessageImpl decode(String msg) { - if (msg.startsWith(UPDATE_HEADER) && msg.length() > UPDATE_HEADER.length()) { - String content = msg.substring(UPDATE_HEADER.length()); - return decodeContent(content); - } - - return null; + public static UpdateMessageImpl decode(@Nullable JsonElement content, UUID id) { + return new UpdateMessageImpl(id); } public UpdateMessageImpl(UUID id) { @@ -52,23 +49,6 @@ public class UpdateMessageImpl extends AbstractMessage implements UpdateMessage @Nonnull @Override public String asEncodedString() { - return UPDATE_HEADER + encodeContent(getId()); - } - - private static String encodeContent(UUID uuid) { - ByteBuffer buf = ByteBuffer.allocate(Long.BYTES * 2); - buf.putLong(uuid.getMostSignificantBits()); - buf.putLong(uuid.getLeastSignificantBits()); - return Base64.getEncoder().encodeToString(buf.array()); - } - - private static UpdateMessageImpl decodeContent(String s) { - try { - byte[] bytes = Base64.getDecoder().decode(s); - ByteBuffer buf = ByteBuffer.wrap(bytes); - return new UpdateMessageImpl(new UUID(buf.getLong(), buf.getLong())); - } catch (IllegalArgumentException e) { - return null; - } + return LuckPermsMessagingService.encodeMessageAsString(TYPE, getId(), null); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/messaging/message/UserUpdateMessageImpl.java b/common/src/main/java/me/lucko/luckperms/common/messaging/message/UserUpdateMessageImpl.java index 2db82d339..61bbf8d19 100644 --- a/common/src/main/java/me/lucko/luckperms/common/messaging/message/UserUpdateMessageImpl.java +++ b/common/src/main/java/me/lucko/luckperms/common/messaging/message/UserUpdateMessageImpl.java @@ -25,24 +25,33 @@ package me.lucko.luckperms.common.messaging.message; -import me.lucko.luckperms.api.messenger.message.type.UserUpdateMessage; +import com.google.gson.JsonElement; + +import me.lucko.luckperms.api.messenger.message.type.UserUpdateMessage; +import me.lucko.luckperms.common.messaging.LuckPermsMessagingService; +import me.lucko.luckperms.common.utils.gson.JObject; -import java.nio.ByteBuffer; -import java.util.Base64; import java.util.UUID; import javax.annotation.Nonnull; +import javax.annotation.Nullable; public class UserUpdateMessageImpl extends AbstractMessage implements UserUpdateMessage { - private static final String USER_UPDATE_HEADER = "userupdate:"; + public static final String TYPE = "userupdate"; - public static UserUpdateMessageImpl decode(String msg) { - if (msg.startsWith(USER_UPDATE_HEADER) && msg.length() > USER_UPDATE_HEADER.length()) { - String content = msg.substring(USER_UPDATE_HEADER.length()); - return decodeContent(content); + public static UserUpdateMessageImpl decode(@Nullable JsonElement content, UUID id) { + if (content == null) { + throw new IllegalStateException("Missing content"); } - return null; + // extract user uuid + JsonElement uuidElement = content.getAsJsonObject().get("userUuid"); + if (uuidElement == null) { + throw new IllegalStateException("Incoming message has no userUuid argument: " + content); + } + UUID userUuid = UUID.fromString(uuidElement.getAsString()); + + return new UserUpdateMessageImpl(id, userUuid); } private final UUID userUuid; @@ -61,27 +70,8 @@ public class UserUpdateMessageImpl extends AbstractMessage implements UserUpdate @Nonnull @Override public String asEncodedString() { - return USER_UPDATE_HEADER + encodeContent(getId(), this.userUuid); - } - - private static String encodeContent(UUID id, UUID userUuid) { - ByteBuffer buf = ByteBuffer.allocate(Long.BYTES * 4); - buf.putLong(id.getMostSignificantBits()); - buf.putLong(id.getLeastSignificantBits()); - buf.putLong(userUuid.getMostSignificantBits()); - buf.putLong(userUuid.getLeastSignificantBits()); - return Base64.getEncoder().encodeToString(buf.array()); - } - - private static UserUpdateMessageImpl decodeContent(String s) { - try { - byte[] bytes = Base64.getDecoder().decode(s); - ByteBuffer buf = ByteBuffer.wrap(bytes); - UUID id = new UUID(buf.getLong(), buf.getLong()); - UUID userUuid = new UUID(buf.getLong(), buf.getLong()); - return new UserUpdateMessageImpl(id, userUuid); - } catch (IllegalArgumentException e) { - return null; - } + return LuckPermsMessagingService.encodeMessageAsString( + TYPE, getId(), new JObject().add("userUuid", userUuid.toString()).toJson() + ); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/messaging/redis/RedisMessenger.java b/common/src/main/java/me/lucko/luckperms/common/messaging/redis/RedisMessenger.java index 831398be4..16cf76712 100644 --- a/common/src/main/java/me/lucko/luckperms/common/messaging/redis/RedisMessenger.java +++ b/common/src/main/java/me/lucko/luckperms/common/messaging/redis/RedisMessenger.java @@ -41,7 +41,7 @@ import javax.annotation.Nonnull; * An implementation of {@link Messenger} using Redis. */ public class RedisMessenger implements Messenger { - private static final String CHANNEL = "lpuc"; + private static final String CHANNEL = "luckperms:update"; private final LuckPermsPlugin plugin; private final IncomingMessageConsumer consumer; diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/FileActionLogger.java b/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/FileActionLogger.java index 8071f6758..284c0ca56 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/FileActionLogger.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/FileActionLogger.java @@ -28,24 +28,21 @@ package me.lucko.luckperms.common.storage.dao.file; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; -import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; import me.lucko.luckperms.api.LogEntry; -import me.lucko.luckperms.common.actionlog.ExtendedLogEntry; import me.lucko.luckperms.common.actionlog.Log; +import me.lucko.luckperms.common.actionlog.LogEntryJsonSerializer; import me.lucko.luckperms.common.buffers.BufferedRequest; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; -import me.lucko.luckperms.common.utils.gson.JObject; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.Queue; -import java.util.UUID; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; @@ -109,19 +106,7 @@ public class FileActionLogger { // poll the queue for new entries for (LogEntry e; (e = this.entryQueue.poll()) != null; ) { - JObject object = new JObject() - .add("timestamp", e.getTimestamp()) - .add("actor", e.getActor().toString()) - .add("actorName", e.getActorName()) - .add("type", Character.toString(e.getType().getCode())) - .add("actedName", e.getActedName()) - .add("action", e.getAction()); - - if (e.getActed().isPresent()) { - object.add("acted", e.getActed().get().toString()); - } - - array.add(object.toJson()); + array.add(LogEntryJsonSerializer.serialize(e)); } // write the full content back to the file @@ -142,24 +127,7 @@ public class FileActionLogger { try (JsonReader reader = new JsonReader(Files.newBufferedReader(this.contentFile, StandardCharsets.UTF_8))) { JsonArray array = JSON_PARSER.parse(reader).getAsJsonArray(); for (JsonElement element : array) { - JsonObject object = element.getAsJsonObject(); - - UUID actedUuid = null; - if (object.has("acted")) { - actedUuid = UUID.fromString(object.get("acted").getAsString()); - } - - ExtendedLogEntry e = ExtendedLogEntry.build() - .timestamp(object.get("timestamp").getAsLong()) - .actor(UUID.fromString(object.get("actor").getAsString())) - .actorName(object.get("actorName").getAsString()) - .type(LogEntry.Type.valueOf(object.get("type").getAsCharacter())) - .acted(actedUuid) - .actedName(object.get("actedName").getAsString()) - .action(object.get("action").getAsString()) - .build(); - - log.add(e); + log.add(LogEntryJsonSerializer.deserialize(element)); } } return log.build(); diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/messaging/BungeeMessenger.java b/sponge/src/main/java/me/lucko/luckperms/sponge/messaging/BungeeMessenger.java index bc2df14a7..b441bb177 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/messaging/BungeeMessenger.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/messaging/BungeeMessenger.java @@ -48,7 +48,7 @@ import javax.annotation.Nonnull; * An implementation of {@link Messenger} using the plugin messaging channels. */ public class BungeeMessenger implements Messenger, RawDataListener { - private static final String CHANNEL = "lpuc"; + private static final String CHANNEL = "luckperms:update"; private final LPSpongePlugin plugin; private final IncomingMessageConsumer consumer;