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.
This commit is contained in:
Luck 2018-07-15 22:42:37 -07:00
parent 08869da96e
commit 07469599bc
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
12 changed files with 238 additions and 235 deletions

View File

@ -47,7 +47,7 @@ import javax.annotation.Nonnull;
* An implementation of {@link Messenger} using the plugin messaging channels. * An implementation of {@link Messenger} using the plugin messaging channels.
*/ */
public class BungeeMessenger implements Messenger, PluginMessageListener { 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 LPBukkitPlugin plugin;
private final IncomingMessageConsumer consumer; private final IncomingMessageConsumer consumer;

View File

@ -45,7 +45,7 @@ import javax.annotation.Nonnull;
* An implementation of {@link Messenger} using LilyPad. * An implementation of {@link Messenger} using LilyPad.
*/ */
public class LilyPadMessenger implements Messenger { public class LilyPadMessenger implements Messenger {
private static final String CHANNEL = "lpuc"; private static final String CHANNEL = "luckperms:update";
private final LPBukkitPlugin plugin; private final LPBukkitPlugin plugin;
private final IncomingMessageConsumer consumer; private final IncomingMessageConsumer consumer;

View File

@ -46,7 +46,7 @@ import javax.annotation.Nonnull;
* An implementation of {@link Messenger} using the plugin messaging channels. * An implementation of {@link Messenger} using the plugin messaging channels.
*/ */
public class BungeeMessenger implements Messenger, Listener { 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 LPBungeePlugin plugin;
private final IncomingMessageConsumer consumer; private final IncomingMessageConsumer consumer;

View File

@ -43,7 +43,7 @@ import javax.annotation.Nonnull;
* An implementation of {@link Messenger} using Redis, via RedisBungee's API. * An implementation of {@link Messenger} using Redis, via RedisBungee's API.
*/ */
public class RedisBungeeMessenger implements Messenger, Listener { 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 LPBungeePlugin plugin;
private final IncomingMessageConsumer consumer; private final IncomingMessageConsumer consumer;

View File

@ -0,0 +1,72 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* 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() {}
}

View File

@ -25,6 +25,11 @@
package me.lucko.luckperms.common.messaging; 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.LogEntry;
import me.lucko.luckperms.api.messenger.IncomingMessageConsumer; import me.lucko.luckperms.api.messenger.IncomingMessageConsumer;
import me.lucko.luckperms.api.messenger.Messenger; 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.messaging.message.UserUpdateMessageImpl;
import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.gson.JObject;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
@ -50,8 +56,11 @@ import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class LuckPermsMessagingService implements InternalMessagingService, IncomingMessageConsumer { public class LuckPermsMessagingService implements InternalMessagingService, IncomingMessageConsumer {
private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().create();
private final LuckPermsPlugin plugin; private final LuckPermsPlugin plugin;
private final Set<UUID> receivedMessages; private final Set<UUID> receivedMessages;
private final PushUpdateBuffer updateBuffer; private final PushUpdateBuffer updateBuffer;
@ -137,77 +146,127 @@ public class LuckPermsMessagingService implements InternalMessagingService, Inco
public boolean consumeIncomingMessage(@Nonnull Message message) { public boolean consumeIncomingMessage(@Nonnull Message message) {
Objects.requireNonNull(message, "message"); Objects.requireNonNull(message, "message");
if (message instanceof UpdateMessage) { if (!this.receivedMessages.add(message.getId())) {
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() + ")");
return false; 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 @Override
public boolean consumeIncomingMessageAsString(@Nonnull String encodedString) { public boolean consumeIncomingMessageAsString(@Nonnull String encodedString) {
Objects.requireNonNull(encodedString, "encodedString"); Objects.requireNonNull(encodedString, "encodedString");
JsonObject decodedObject = GSON.fromJson(encodedString, JsonObject.class).getAsJsonObject();
Message decoded = UpdateMessageImpl.decode(encodedString); // extract id
if (decoded != null) { JsonElement idElement = decodedObject.get("id");
return consumeIncomingMessage(decoded); 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); // extract type
if (decoded != null) { JsonElement typeElement = decodedObject.get("type");
return consumeIncomingMessage(decoded); 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); // consume the message
return decoded != null && consumeIncomingMessage(decoded); 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<Void> { private final class PushUpdateBuffer extends BufferedRequest<Void> {
public PushUpdateBuffer(LuckPermsPlugin plugin) { PushUpdateBuffer(LuckPermsPlugin plugin) {
super(2, TimeUnit.SECONDS, plugin.getBootstrap().getScheduler()); super(2, TimeUnit.SECONDS, plugin.getBootstrap().getScheduler());
} }

View File

@ -25,37 +25,27 @@
package me.lucko.luckperms.common.messaging.message; package me.lucko.luckperms.common.messaging.message;
import com.google.gson.Gson; import com.google.gson.JsonElement;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import me.lucko.luckperms.api.LogEntry; import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.messenger.message.type.LogMessage; 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 java.util.UUID;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class LogMessageImpl extends AbstractMessage implements LogMessage { public class LogMessageImpl extends AbstractMessage implements LogMessage {
private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().create(); public static final String TYPE = "log";
private static final String LOG_HEADER = "log";
public static LogMessageImpl decode(String msg) { public static LogMessageImpl decode(@Nullable JsonElement content, UUID id) {
if (msg.startsWith(LOG_HEADER) && msg.length() > LOG_HEADER.length()) { if (content == null) {
String content = msg.substring(LOG_HEADER.length()); throw new IllegalStateException("Missing content");
try {
return decodeContent(GSON.fromJson(content, JsonObject.class));
} catch (Exception e) {
return null;
}
} }
return null; return new LogMessageImpl(id, LogEntryJsonSerializer.deserialize(content));
} }
private final LogEntry logEntry; private final LogEntry logEntry;
@ -74,65 +64,9 @@ public class LogMessageImpl extends AbstractMessage implements LogMessage {
@Nonnull @Nonnull
@Override @Override
public String asEncodedString() { public String asEncodedString() {
return LOG_HEADER + GSON.toJson(encodeContent(uuidToString(getId()), this.logEntry)); return LuckPermsMessagingService.encodeMessageAsString(
} TYPE, getId(), LogEntryJsonSerializer.serialize(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());
} }
} }

View File

@ -25,24 +25,21 @@
package me.lucko.luckperms.common.messaging.message; 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 java.util.UUID;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class UpdateMessageImpl extends AbstractMessage implements UpdateMessage { 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) { public static UpdateMessageImpl decode(@Nullable JsonElement content, UUID id) {
if (msg.startsWith(UPDATE_HEADER) && msg.length() > UPDATE_HEADER.length()) { return new UpdateMessageImpl(id);
String content = msg.substring(UPDATE_HEADER.length());
return decodeContent(content);
}
return null;
} }
public UpdateMessageImpl(UUID id) { public UpdateMessageImpl(UUID id) {
@ -52,23 +49,6 @@ public class UpdateMessageImpl extends AbstractMessage implements UpdateMessage
@Nonnull @Nonnull
@Override @Override
public String asEncodedString() { public String asEncodedString() {
return UPDATE_HEADER + encodeContent(getId()); return LuckPermsMessagingService.encodeMessageAsString(TYPE, getId(), null);
}
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;
}
} }
} }

View File

@ -25,24 +25,33 @@
package me.lucko.luckperms.common.messaging.message; 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 java.util.UUID;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class UserUpdateMessageImpl extends AbstractMessage implements UserUpdateMessage { 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) { public static UserUpdateMessageImpl decode(@Nullable JsonElement content, UUID id) {
if (msg.startsWith(USER_UPDATE_HEADER) && msg.length() > USER_UPDATE_HEADER.length()) { if (content == null) {
String content = msg.substring(USER_UPDATE_HEADER.length()); throw new IllegalStateException("Missing content");
return decodeContent(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; private final UUID userUuid;
@ -61,27 +70,8 @@ public class UserUpdateMessageImpl extends AbstractMessage implements UserUpdate
@Nonnull @Nonnull
@Override @Override
public String asEncodedString() { public String asEncodedString() {
return USER_UPDATE_HEADER + encodeContent(getId(), this.userUuid); return LuckPermsMessagingService.encodeMessageAsString(
} TYPE, getId(), new JObject().add("userUuid", userUuid.toString()).toJson()
);
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;
}
} }
} }

View File

@ -41,7 +41,7 @@ import javax.annotation.Nonnull;
* An implementation of {@link Messenger} using Redis. * An implementation of {@link Messenger} using Redis.
*/ */
public class RedisMessenger implements Messenger { public class RedisMessenger implements Messenger {
private static final String CHANNEL = "lpuc"; private static final String CHANNEL = "luckperms:update";
private final LuckPermsPlugin plugin; private final LuckPermsPlugin plugin;
private final IncomingMessageConsumer consumer; private final IncomingMessageConsumer consumer;

View File

@ -28,24 +28,21 @@ package me.lucko.luckperms.common.storage.dao.file;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter; import com.google.gson.stream.JsonWriter;
import me.lucko.luckperms.api.LogEntry; 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.Log;
import me.lucko.luckperms.common.actionlog.LogEntryJsonSerializer;
import me.lucko.luckperms.common.buffers.BufferedRequest; import me.lucko.luckperms.common.buffers.BufferedRequest;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.gson.JObject;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Queue; import java.util.Queue;
import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
@ -109,19 +106,7 @@ public class FileActionLogger {
// poll the queue for new entries // poll the queue for new entries
for (LogEntry e; (e = this.entryQueue.poll()) != null; ) { for (LogEntry e; (e = this.entryQueue.poll()) != null; ) {
JObject object = new JObject() array.add(LogEntryJsonSerializer.serialize(e));
.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());
} }
// write the full content back to the file // 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))) { try (JsonReader reader = new JsonReader(Files.newBufferedReader(this.contentFile, StandardCharsets.UTF_8))) {
JsonArray array = JSON_PARSER.parse(reader).getAsJsonArray(); JsonArray array = JSON_PARSER.parse(reader).getAsJsonArray();
for (JsonElement element : array) { for (JsonElement element : array) {
JsonObject object = element.getAsJsonObject(); log.add(LogEntryJsonSerializer.deserialize(element));
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);
} }
} }
return log.build(); return log.build();

View File

@ -48,7 +48,7 @@ import javax.annotation.Nonnull;
* An implementation of {@link Messenger} using the plugin messaging channels. * An implementation of {@link Messenger} using the plugin messaging channels.
*/ */
public class BungeeMessenger implements Messenger, RawDataListener { 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 LPSpongePlugin plugin;
private final IncomingMessageConsumer consumer; private final IncomingMessageConsumer consumer;