Dispatch log entries via the messaging service

This commit is contained in:
Luck 2017-08-20 13:32:52 +02:00
parent f0ad40825b
commit ae8be97db7
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
29 changed files with 696 additions and 101 deletions

View File

@ -1,3 +1,28 @@
/*
* 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.api; package me.lucko.luckperms.api;
import me.lucko.luckperms.api.caching.MetaContexts; import me.lucko.luckperms.api.caching.MetaContexts;

View File

@ -44,4 +44,31 @@ public interface LogBroadcastEvent extends LuckPermsEvent, Cancellable {
@Nonnull @Nonnull
LogEntry getEntry(); LogEntry getEntry();
/**
* Gets where the log entry originated from.
*
* @return the origin of the log
* @since 3.3
*/
@Nonnull
Origin getOrigin();
/**
* Represents where a log entry is from
*
* @since 3.3
*/
enum Origin {
/**
* Represents a log entry which originated from the current server instance
*/
LOCAL,
/**
* Represents a log entry which was sent to this server via the messaging service
*/
REMOTE
}
} }

View File

@ -0,0 +1,59 @@
/*
* 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.api.event.log;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.event.Cancellable;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import java.util.UUID;
import javax.annotation.Nonnull;
/**
* Called when a log is about to be published to the network via the MessagingService
*
* @since 3.3
*/
public interface LogNetworkPublishEvent extends LuckPermsEvent, Cancellable {
/**
* Gets the ID of the log entry being published
*
* @return the id of the log entry being published
*/
@Nonnull
UUID getLogId();
/**
* Gets the log entry to be published
*
* @return the log entry to be published
*/
@Nonnull
LogEntry getEntry();
}

View File

@ -0,0 +1,58 @@
/*
* 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.api.event.log;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import java.util.UUID;
import javax.annotation.Nonnull;
/**
* Called when a log entry is received via the MessagingService
*
* @since 3.3
*/
public interface LogReceiveEvent extends LuckPermsEvent {
/**
* Gets the ID of the log entry being received
*
* @return the id of the log entry being received
*/
@Nonnull
UUID getLogId();
/**
* Gets the log entry being received
*
* @return the log entry being received
*/
@Nonnull
LogEntry getEntry();
}

View File

@ -33,7 +33,7 @@ import java.util.UUID;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
/** /**
* Called before a network sync task runs * Called before a received network sync task runs
*/ */
public interface PreNetworkSyncEvent extends LuckPermsEvent, Cancellable { public interface PreNetworkSyncEvent extends LuckPermsEvent, Cancellable {

View File

@ -43,6 +43,7 @@ import me.lucko.luckperms.bukkit.model.LPPermissible;
import me.lucko.luckperms.bukkit.processors.ChildPermissionProvider; import me.lucko.luckperms.bukkit.processors.ChildPermissionProvider;
import me.lucko.luckperms.bukkit.processors.DefaultsProvider; import me.lucko.luckperms.bukkit.processors.DefaultsProvider;
import me.lucko.luckperms.bukkit.vault.VaultHookManager; import me.lucko.luckperms.bukkit.vault.VaultHookManager;
import me.lucko.luckperms.common.actionlog.LogDispatcher;
import me.lucko.luckperms.common.api.ApiHandler; import me.lucko.luckperms.common.api.ApiHandler;
import me.lucko.luckperms.common.api.ApiProvider; import me.lucko.luckperms.common.api.ApiProvider;
import me.lucko.luckperms.common.buffers.BufferedRequest; import me.lucko.luckperms.common.buffers.BufferedRequest;
@ -109,8 +110,7 @@ import java.util.stream.Collectors;
@Getter @Getter
public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin { public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
private Set<UUID> ignoringLogs;
private Set<UUID> uniqueConnections;
private long startTime; private long startTime;
private LPBukkitScheduler scheduler; private LPBukkitScheduler scheduler;
private BukkitCommand commandManager; private BukkitCommand commandManager;
@ -139,6 +139,8 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
private VerboseHandler verboseHandler; private VerboseHandler verboseHandler;
private BukkitSenderFactory senderFactory; private BukkitSenderFactory senderFactory;
private PermissionVault permissionVault; private PermissionVault permissionVault;
private LogDispatcher logDispatcher;
private Set<UUID> uniqueConnections = ConcurrentHashMap.newKeySet();
@Override @Override
public void onLoad() { public void onLoad() {
@ -182,11 +184,9 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
private void enable() { private void enable() {
startTime = System.currentTimeMillis(); startTime = System.currentTimeMillis();
LuckPermsPlugin.sendStartupBanner(getConsoleSender(), this); LuckPermsPlugin.sendStartupBanner(getConsoleSender(), this);
verboseHandler = new VerboseHandler(scheduler.asyncBukkit(), getVersion());
ignoringLogs = ConcurrentHashMap.newKeySet(); permissionVault = new PermissionVault(scheduler.asyncBukkit());
uniqueConnections = ConcurrentHashMap.newKeySet(); logDispatcher = new LogDispatcher(this);
verboseHandler = new VerboseHandler(scheduler.getAsyncBukkitExecutor(), getVersion());
permissionVault = new PermissionVault(scheduler.getAsyncBukkitExecutor());
getLog().info("Loading configuration..."); getLog().info("Loading configuration...");
configuration = new BukkitConfig(this); configuration = new BukkitConfig(this);
@ -448,7 +448,6 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
HandlerList.unregisterAll(this); HandlerList.unregisterAll(this);
// Null everything // Null everything
ignoringLogs = null;
vaultHookManager = null; vaultHookManager = null;
configuration = null; configuration = null;
userManager = null; userManager = null;
@ -472,6 +471,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
verboseHandler = null; verboseHandler = null;
senderFactory = null; senderFactory = null;
permissionVault = null; permissionVault = null;
logDispatcher = null;
} }
public void tryVaultHook(boolean force) { public void tryVaultHook(boolean force) {

View File

@ -27,6 +27,7 @@ package me.lucko.luckperms.bukkit;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.experimental.Accessors;
import me.lucko.luckperms.common.plugin.LuckPermsScheduler; import me.lucko.luckperms.common.plugin.LuckPermsScheduler;
@ -43,10 +44,16 @@ public class LPBukkitScheduler implements LuckPermsScheduler {
private final LPBukkitPlugin plugin; private final LPBukkitPlugin plugin;
@Getter @Getter
private ExecutorService asyncLpExecutor; @Accessors(fluent = true)
private ExecutorService asyncLp;
@Getter @Getter
private Executor asyncBukkitExecutor; @Accessors(fluent = true)
private Executor syncExecutor; private Executor asyncBukkit;
@Getter
@Accessors(fluent = true)
private Executor sync;
@Getter @Getter
@Setter @Setter
@ -57,19 +64,14 @@ public class LPBukkitScheduler implements LuckPermsScheduler {
public LPBukkitScheduler(LPBukkitPlugin plugin) { public LPBukkitScheduler(LPBukkitPlugin plugin) {
this.plugin = plugin; this.plugin = plugin;
this.asyncLpExecutor = Executors.newCachedThreadPool(); this.asyncLp = Executors.newCachedThreadPool();
this.asyncBukkitExecutor = r -> plugin.getServer().getScheduler().runTaskAsynchronously(plugin, r); this.asyncBukkit = r -> plugin.getServer().getScheduler().runTaskAsynchronously(plugin, r);
this.syncExecutor = r -> plugin.getServer().getScheduler().runTask(plugin, r); this.sync = r -> plugin.getServer().getScheduler().runTask(plugin, r);
} }
@Override @Override
public Executor async() { public Executor async() {
return useBukkitAsync ? asyncBukkitExecutor : asyncLpExecutor; return useBukkitAsync ? asyncBukkit : asyncLp;
}
@Override
public Executor sync() {
return syncExecutor;
} }
@Override @Override
@ -108,9 +110,9 @@ public class LPBukkitScheduler implements LuckPermsScheduler {
public void shutdown() { public void shutdown() {
tasks.forEach(BukkitTask::cancel); tasks.forEach(BukkitTask::cancel);
// wait for executor // wait for executor
asyncLpExecutor.shutdown(); asyncLp.shutdown();
try { try {
asyncLpExecutor.awaitTermination(30, TimeUnit.SECONDS); asyncLp.awaitTermination(30, TimeUnit.SECONDS);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -328,6 +328,16 @@ messaging-service: none
# If LuckPerms should automatically push updates after a change has been made with a command. # If LuckPerms should automatically push updates after a change has been made with a command.
auto-push-updates: true auto-push-updates: true
# If LuckPerms should push logging entries to connected servers via the messaging service.
push-log-entries: true
# If LuckPerms should broadcast received logging entries to players on this platform.
#
# If you have LuckPerms installed on your backend servers as well as a BungeeCord proxy, you should
# set this option to false on either your backends or your proxies, to avoid players being messaged
# twice about log entries.
broadcast-received-log-entries: true
# Settings for Redis. # Settings for Redis.
# Port 6379 is used by default; set address to "host:port" if differs # Port 6379 is used by default; set address to "host:port" if differs
redis: redis:

View File

@ -37,6 +37,7 @@ import me.lucko.luckperms.bungee.contexts.BackendServerCalculator;
import me.lucko.luckperms.bungee.messaging.BungeeMessagingService; import me.lucko.luckperms.bungee.messaging.BungeeMessagingService;
import me.lucko.luckperms.bungee.messaging.RedisBungeeMessagingService; import me.lucko.luckperms.bungee.messaging.RedisBungeeMessagingService;
import me.lucko.luckperms.bungee.util.RedisBungeeUtil; import me.lucko.luckperms.bungee.util.RedisBungeeUtil;
import me.lucko.luckperms.common.actionlog.LogDispatcher;
import me.lucko.luckperms.common.api.ApiHandler; import me.lucko.luckperms.common.api.ApiHandler;
import me.lucko.luckperms.common.api.ApiProvider; import me.lucko.luckperms.common.api.ApiProvider;
import me.lucko.luckperms.common.buffers.BufferedRequest; import me.lucko.luckperms.common.buffers.BufferedRequest;
@ -93,8 +94,7 @@ import java.util.stream.Collectors;
@Getter @Getter
public class LPBungeePlugin extends Plugin implements LuckPermsPlugin { public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
private final Set<UUID> ignoringLogs = ConcurrentHashMap.newKeySet();
private Set<UUID> uniqueConnections = ConcurrentHashMap.newKeySet();
private long startTime; private long startTime;
private LuckPermsScheduler scheduler; private LuckPermsScheduler scheduler;
private CommandManager commandManager; private CommandManager commandManager;
@ -116,6 +116,8 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
private VerboseHandler verboseHandler; private VerboseHandler verboseHandler;
private BungeeSenderFactory senderFactory; private BungeeSenderFactory senderFactory;
private PermissionVault permissionVault; private PermissionVault permissionVault;
private LogDispatcher logDispatcher;
private Set<UUID> uniqueConnections = ConcurrentHashMap.newKeySet();
@Override @Override
public void onLoad() { public void onLoad() {
@ -134,6 +136,7 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
LuckPermsPlugin.sendStartupBanner(getConsoleSender(), this); LuckPermsPlugin.sendStartupBanner(getConsoleSender(), this);
verboseHandler = new VerboseHandler(scheduler.async(), getVersion()); verboseHandler = new VerboseHandler(scheduler.async(), getVersion());
permissionVault = new PermissionVault(scheduler.async()); permissionVault = new PermissionVault(scheduler.async());
logDispatcher = new LogDispatcher(this);
getLog().info("Loading configuration..."); getLog().info("Loading configuration...");
configuration = new BungeeConfig(this); configuration = new BungeeConfig(this);

View File

@ -89,7 +89,7 @@ public class BungeeMessagingService extends AbstractMessagingService implements
onMessage(e.getTag(), msg, u -> { onMessage(e.getTag(), msg, u -> {
// Forward to other servers // Forward to other servers
plugin.doAsync(() -> sendMessage(CHANNEL, "update:" + u.toString())); plugin.doAsync(() -> sendMessage(CHANNEL, u));
}); });
} }
} }

View File

@ -263,6 +263,16 @@ messaging-service: none
# If LuckPerms should automatically push updates after a change has been made with a command. # If LuckPerms should automatically push updates after a change has been made with a command.
auto-push-updates: true auto-push-updates: true
# If LuckPerms should push logging entries to connected servers via the messaging service.
push-log-entries: true
# If LuckPerms should broadcast received logging entries to players on this platform.
#
# If you have LuckPerms installed on your backend servers as well as a BungeeCord proxy, you should
# set this option to false on either your backends or your proxies, to avoid players being messaged
# twice about log entries.
broadcast-received-log-entries: false
# Settings for Redis. # Settings for Redis.
# Port 6379 is used by default; set address to "host:port" if differs # Port 6379 is used by default; set address to "host:port" if differs
redis: redis:

View File

@ -25,11 +25,12 @@
package me.lucko.luckperms.common.actionlog; package me.lucko.luckperms.common.actionlog;
import com.google.common.collect.Maps;
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.common.commands.sender.Sender; import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.constants.CommandPermission;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder; import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.Track; import me.lucko.luckperms.common.model.Track;
@ -37,7 +38,8 @@ 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.DateUtil; import me.lucko.luckperms.common.utils.DateUtil;
import java.util.List; import java.util.Map;
import java.util.UUID;
/** /**
* An extended version of {@link LogEntry}, with helper methods for * An extended version of {@link LogEntry}, with helper methods for
@ -52,36 +54,41 @@ public class ExtendedLogEntry extends LogEntry {
return (ExtendedLogEntry) super.copy(); return (ExtendedLogEntry) super.copy();
} }
public void submit(LuckPermsPlugin plugin) { public void submit(LuckPermsPlugin plugin, Sender sender) {
submit(plugin, null); plugin.getLogDispatcher().dispatch(this, sender);
} }
public void submit(LuckPermsPlugin plugin, Sender sender) { public static JsonObject serializeWithId(UUID id, LogEntry entry) {
if (!plugin.getApiProvider().getEventFactory().handleLogPublish(false, this)) { JsonObject data = new JsonObject();
plugin.getStorage().logAction(this);
data.add("id", new JsonPrimitive(id.toString()));
data.add("actor", new JsonPrimitive(entry.getActor().toString()));
data.add("actorName", new JsonPrimitive(entry.getActorName()));
data.add("type", new JsonPrimitive(entry.getEntryType().name()));
if (entry.getActed() != null) {
data.add("acted", new JsonPrimitive(entry.getActed().toString()));
} }
data.add("actedName", new JsonPrimitive(entry.getActedName()));
data.add("action", new JsonPrimitive(entry.getAction()));
if (plugin.getApiProvider().getEventFactory().handleLogBroadcast(!plugin.getConfiguration().get(ConfigKeys.LOG_NOTIFY), this)) { return data;
return; }
public static Map.Entry<UUID, LogEntry> deserialize(JsonObject object) {
LogEntry.LogEntryBuilder builder = LogEntry.builder();
UUID id = UUID.fromString(object.get("id").getAsString());
builder.actor(UUID.fromString(object.get("actor").getAsString()));
builder.actorName(object.get("actorName").getAsString());
builder.entryType(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());
final String msg = super.getFormatted(); return Maps.immutableEntry(id, builder.build());
List<Sender> senders = plugin.getOnlineSenders();
senders.add(plugin.getConsoleSender());
if (sender == null) {
senders.stream()
.filter(CommandPermission.LOG_NOTIFY::isAuthorized)
.filter(s -> !plugin.getIgnoringLogs().contains(s.getUuid()))
.forEach(s -> Message.LOG.send(s, msg));
} else {
senders.stream()
.filter(CommandPermission.LOG_NOTIFY::isAuthorized)
.filter(s -> !plugin.getIgnoringLogs().contains(s.getUuid()))
.filter(s -> !s.getUuid().equals(sender.getUuid()))
.forEach(s -> Message.LOG.send(s, msg));
}
} }
public static class ExtendedLogEntryBuilder extends AbstractLogEntryBuilder<ExtendedLogEntry, ExtendedLogEntryBuilder> { public static class ExtendedLogEntryBuilder extends AbstractLogEntryBuilder<ExtendedLogEntry, ExtendedLogEntryBuilder> {

View File

@ -0,0 +1,88 @@
/*
* 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 lombok.RequiredArgsConstructor;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.event.log.LogBroadcastEvent;
import me.lucko.luckperms.common.commands.impl.log.LogNotify;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.constants.CommandPermission;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.messaging.InternalMessagingService;
import me.lucko.luckperms.common.messaging.NoopMessagingService;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import java.util.List;
@RequiredArgsConstructor
public class LogDispatcher {
private final LuckPermsPlugin plugin;
public void dispatch(LogEntry entry, Sender sender) {
if (!plugin.getApiProvider().getEventFactory().handleLogPublish(false, entry)) {
plugin.getStorage().logAction(entry);
}
InternalMessagingService messagingService = plugin.getMessagingService();
if (!sender.isImport() && !(messagingService instanceof NoopMessagingService)) {
messagingService.pushLog(entry);
}
if (!plugin.getApiProvider().getEventFactory().handleLogBroadcast(!plugin.getConfiguration().get(ConfigKeys.LOG_NOTIFY), entry, LogBroadcastEvent.Origin.LOCAL)) {
final String msg = entry.getFormatted();
List<Sender> senders = plugin.getOnlineSenders();
senders.add(plugin.getConsoleSender());
senders.stream()
.filter(CommandPermission.LOG_NOTIFY::isAuthorized)
.filter(s -> !LogNotify.isIgnoring(plugin, s.getUuid()))
.filter(s -> !s.getUuid().equals(sender.getUuid()))
.forEach(s -> Message.LOG.send(s, msg));
}
}
public void dispatchFromRemote(LogEntry entry) {
if (!plugin.getConfiguration().get(ConfigKeys.BROADCAST_RECEIVED_LOG_ENTRIES)) {
return;
}
if (!plugin.getApiProvider().getEventFactory().handleLogBroadcast(!plugin.getConfiguration().get(ConfigKeys.LOG_NOTIFY), entry, LogBroadcastEvent.Origin.REMOTE)) {
final String msg = entry.getFormatted();
List<Sender> senders = plugin.getOnlineSenders();
senders.add(plugin.getConsoleSender());
senders.stream()
.filter(CommandPermission.LOG_NOTIFY::isAuthorized)
.filter(s -> !LogNotify.isIgnoring(plugin, s.getUuid()))
.forEach(s -> Message.LOG.send(s, msg));
}
}
}

View File

@ -25,6 +25,7 @@
package me.lucko.luckperms.common.commands.impl.log; package me.lucko.luckperms.common.commands.impl.log;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.common.actionlog.Log; import me.lucko.luckperms.common.actionlog.Log;
import me.lucko.luckperms.common.commands.CommandException; import me.lucko.luckperms.common.commands.CommandException;
import me.lucko.luckperms.common.commands.CommandResult; import me.lucko.luckperms.common.commands.CommandResult;
@ -34,11 +35,13 @@ import me.lucko.luckperms.common.constants.CommandPermission;
import me.lucko.luckperms.common.locale.CommandSpec; import me.lucko.luckperms.common.locale.CommandSpec;
import me.lucko.luckperms.common.locale.LocaleManager; import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.Message; import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.node.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.Predicates; import me.lucko.luckperms.common.utils.Predicates;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
public class LogNotify extends SubCommand<Log> { public class LogNotify extends SubCommand<Log> {
@ -46,45 +49,81 @@ public class LogNotify extends SubCommand<Log> {
super(CommandSpec.LOG_NOTIFY.spec(locale), "notify", CommandPermission.LOG_NOTIFY, Predicates.notInRange(0, 1)); super(CommandSpec.LOG_NOTIFY.spec(locale), "notify", CommandPermission.LOG_NOTIFY, Predicates.notInRange(0, 1));
} }
public static boolean isIgnoring(LuckPermsPlugin plugin, UUID uuid) {
User user = plugin.getUserManager().getIfLoaded(plugin.getUuidCache().getUUID(uuid));
if (user == null) {
return false;
}
Optional<Node> ret = user.getOwnNodes().stream()
.filter(n -> n.getPermission().equalsIgnoreCase("luckperms.log.notify.ignoring"))
.findFirst();
// if they don't have the perm, they're not ignoring
// if set to false, ignore it, return false
return ret.map(Node::getValue).orElse(false);
}
private static void setIgnoring(LuckPermsPlugin plugin, UUID uuid, boolean state) {
User user = plugin.getUserManager().getIfLoaded(plugin.getUuidCache().getUUID(uuid));
if (user == null) {
return;
}
if (state) {
// add the perm
user.setPermission(NodeFactory.make("luckperms.log.notify.ignoring"));
} else {
// remove the perm
user.removeIf(n -> n.getPermission().equalsIgnoreCase("luckperms.log.notify.ignoring"));
}
plugin.getStorage().force().saveUser(user).join();
}
@Override @Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Log log, List<String> args, String label) throws CommandException { public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Log log, List<String> args, String label) throws CommandException {
final Set<UUID> ignoring = plugin.getIgnoringLogs(); if (sender.isConsole() || sender.isImport()) {
Message.LOG_NOTIFY_CONSOLE.send(sender);
return CommandResult.SUCCESS;
}
final UUID uuid = sender.getUuid(); final UUID uuid = sender.getUuid();
if (args.size() == 0) { if (args.size() == 0) {
if (ignoring.contains(uuid)) { if (isIgnoring(plugin, uuid)) {
// toggle on // toggle on
ignoring.remove(uuid); setIgnoring(plugin, uuid, false);
Message.LOG_NOTIFY_TOGGLE_ON.send(sender); Message.LOG_NOTIFY_TOGGLE_ON.send(sender);
return CommandResult.SUCCESS; return CommandResult.SUCCESS;
} }
// toggle off // toggle off
ignoring.add(uuid); setIgnoring(plugin, uuid, true);
Message.LOG_NOTIFY_TOGGLE_OFF.send(sender); Message.LOG_NOTIFY_TOGGLE_OFF.send(sender);
return CommandResult.SUCCESS; return CommandResult.SUCCESS;
} }
if (args.get(0).equalsIgnoreCase("on")) { if (args.get(0).equalsIgnoreCase("on")) {
if (!ignoring.contains(uuid)) { if (!isIgnoring(plugin, uuid)) {
// already on // already on
Message.LOG_NOTIFY_ALREADY_ON.send(sender); Message.LOG_NOTIFY_ALREADY_ON.send(sender);
return CommandResult.STATE_ERROR; return CommandResult.STATE_ERROR;
} }
// toggle on // toggle on
ignoring.remove(uuid); setIgnoring(plugin, uuid, false);
Message.LOG_NOTIFY_TOGGLE_ON.send(sender); Message.LOG_NOTIFY_TOGGLE_ON.send(sender);
return CommandResult.SUCCESS; return CommandResult.SUCCESS;
} }
if (args.get(0).equalsIgnoreCase("off")) { if (args.get(0).equalsIgnoreCase("off")) {
if (ignoring.contains(uuid)) { if (isIgnoring(plugin, uuid)) {
// already off // already off
Message.LOG_NOTIFY_ALREADY_OFF.send(sender); Message.LOG_NOTIFY_ALREADY_OFF.send(sender);
return CommandResult.STATE_ERROR; return CommandResult.STATE_ERROR;
} }
// toggle off // toggle off
ignoring.add(uuid); setIgnoring(plugin, uuid, true);
Message.LOG_NOTIFY_TOGGLE_OFF.send(sender); Message.LOG_NOTIFY_TOGGLE_OFF.send(sender);
return CommandResult.SUCCESS; return CommandResult.SUCCESS;
} }

View File

@ -392,7 +392,7 @@ public class ConfigKeys {
})); }));
/** /**
* The name of the messaging service in use, or "none" if not enabled. * The name of the messaging service in use, or "none" if not enabled
*/ */
public static final ConfigKey<String> MESSAGING_SERVICE = EnduringKey.wrap(LowercaseStringKey.of("messaging-service", "none")); public static final ConfigKey<String> MESSAGING_SERVICE = EnduringKey.wrap(LowercaseStringKey.of("messaging-service", "none"));
@ -401,6 +401,16 @@ public class ConfigKeys {
*/ */
public static final ConfigKey<Boolean> AUTO_PUSH_UPDATES = EnduringKey.wrap(BooleanKey.of("auto-push-updates", true)); public static final ConfigKey<Boolean> AUTO_PUSH_UPDATES = EnduringKey.wrap(BooleanKey.of("auto-push-updates", true));
/**
* If LuckPerms should push logging entries to connected servers via the messaging service
*/
public static final ConfigKey<Boolean> PUSH_LOG_ENTRIES = EnduringKey.wrap(BooleanKey.of("push-log-entries", true));
/**
* If LuckPerms should broadcast received logging entries to players on this platform
*/
public static final ConfigKey<Boolean> BROADCAST_RECEIVED_LOG_ENTRIES = EnduringKey.wrap(BooleanKey.of("broadcast-received-log-entries", false));
/** /**
* If redis messaging is enabled * If redis messaging is enabled
*/ */

View File

@ -36,13 +36,16 @@ import me.lucko.luckperms.api.caching.UserData;
import me.lucko.luckperms.api.event.LuckPermsEvent; import me.lucko.luckperms.api.event.LuckPermsEvent;
import me.lucko.luckperms.api.event.cause.CreationCause; import me.lucko.luckperms.api.event.cause.CreationCause;
import me.lucko.luckperms.api.event.cause.DeletionCause; import me.lucko.luckperms.api.event.cause.DeletionCause;
import me.lucko.luckperms.api.event.log.LogBroadcastEvent;
import me.lucko.luckperms.common.event.impl.EventConfigReload; import me.lucko.luckperms.common.event.impl.EventConfigReload;
import me.lucko.luckperms.common.event.impl.EventGroupCreate; import me.lucko.luckperms.common.event.impl.EventGroupCreate;
import me.lucko.luckperms.common.event.impl.EventGroupDelete; import me.lucko.luckperms.common.event.impl.EventGroupDelete;
import me.lucko.luckperms.common.event.impl.EventGroupLoad; import me.lucko.luckperms.common.event.impl.EventGroupLoad;
import me.lucko.luckperms.common.event.impl.EventGroupLoadAll; import me.lucko.luckperms.common.event.impl.EventGroupLoadAll;
import me.lucko.luckperms.common.event.impl.EventLogBroadcast; import me.lucko.luckperms.common.event.impl.EventLogBroadcast;
import me.lucko.luckperms.common.event.impl.EventLogNetworkPublish;
import me.lucko.luckperms.common.event.impl.EventLogPublish; import me.lucko.luckperms.common.event.impl.EventLogPublish;
import me.lucko.luckperms.common.event.impl.EventLogReceive;
import me.lucko.luckperms.common.event.impl.EventNodeAdd; import me.lucko.luckperms.common.event.impl.EventNodeAdd;
import me.lucko.luckperms.common.event.impl.EventNodeClear; import me.lucko.luckperms.common.event.impl.EventNodeClear;
import me.lucko.luckperms.common.event.impl.EventNodeRemove; import me.lucko.luckperms.common.event.impl.EventNodeRemove;
@ -100,9 +103,9 @@ public final class EventFactory {
fireEvent(event); fireEvent(event);
} }
public boolean handleLogBroadcast(boolean initialState, LogEntry entry) { public boolean handleLogBroadcast(boolean initialState, LogEntry entry, LogBroadcastEvent.Origin origin) {
AtomicBoolean cancel = new AtomicBoolean(initialState); AtomicBoolean cancel = new AtomicBoolean(initialState);
EventLogBroadcast event = new EventLogBroadcast(cancel, entry); EventLogBroadcast event = new EventLogBroadcast(cancel, entry, origin);
eventBus.fireEvent(event); eventBus.fireEvent(event);
return cancel.get(); return cancel.get();
} }
@ -114,6 +117,18 @@ public final class EventFactory {
return cancel.get(); return cancel.get();
} }
public boolean handleLogNetworkPublish(boolean initialState, UUID id, LogEntry entry) {
AtomicBoolean cancel = new AtomicBoolean(initialState);
EventLogNetworkPublish event = new EventLogNetworkPublish(cancel, id, entry);
eventBus.fireEvent(event);
return cancel.get();
}
public void handleLogReceive(UUID id, LogEntry entry) {
EventLogReceive event = new EventLogReceive(id, entry);
fireEvent(event);
}
public void handleNodeAdd(Node node, PermissionHolder target, Collection<Node> before, Collection<Node> after) { public void handleNodeAdd(Node node, PermissionHolder target, Collection<Node> before, Collection<Node> after) {
EventNodeAdd event = new EventNodeAdd(node, target.getDelegate(), ImmutableSet.copyOf(before), ImmutableSet.copyOf(after)); EventNodeAdd event = new EventNodeAdd(node, target.getDelegate(), ImmutableSet.copyOf(before), ImmutableSet.copyOf(after));
fireEvent(event); fireEvent(event);

View File

@ -42,5 +42,6 @@ public class EventLogBroadcast extends AbstractEvent implements LogBroadcastEven
private final AtomicBoolean cancellationState; private final AtomicBoolean cancellationState;
private final LogEntry entry; private final LogEntry entry;
private final Origin origin;
} }

View File

@ -0,0 +1,48 @@
/*
* 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.event.impl;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.event.log.LogNetworkPublishEvent;
import me.lucko.luckperms.common.event.AbstractEvent;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
@Getter
@ToString
@AllArgsConstructor
public class EventLogNetworkPublish extends AbstractEvent implements LogNetworkPublishEvent {
private final AtomicBoolean cancellationState;
private final UUID logId;
private final LogEntry entry;
}

View File

@ -0,0 +1,46 @@
/*
* 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.event.impl;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.event.log.LogReceiveEvent;
import me.lucko.luckperms.common.event.AbstractEvent;
import java.util.UUID;
@Getter
@ToString
@AllArgsConstructor
public class EventLogReceive extends AbstractEvent implements LogReceiveEvent {
private final UUID logId;
private final LogEntry entry;
}

View File

@ -364,6 +364,7 @@ public enum Message {
LOG_NO_ENTRIES("&bNo log entries to show.", true), LOG_NO_ENTRIES("&bNo log entries to show.", true),
LOG_ENTRY("&b#{0} -> &8(&7{1} ago&8) {2}", true), LOG_ENTRY("&b#{0} -> &8(&7{1} ago&8) {2}", true),
LOG_NOTIFY_CONSOLE("&cCannot toggle notifications for console.", true),
LOG_NOTIFY_TOGGLE_ON("&aEnabled&b logging output.", true), LOG_NOTIFY_TOGGLE_ON("&aEnabled&b logging output.", true),
LOG_NOTIFY_TOGGLE_OFF("&cDisabled&b logging output.", true), LOG_NOTIFY_TOGGLE_OFF("&cDisabled&b logging output.", true),
LOG_NOTIFY_ALREADY_ON("You are already receiving notifications.", true), LOG_NOTIFY_ALREADY_ON("You are already receiving notifications.", true),

View File

@ -28,11 +28,18 @@ package me.lucko.luckperms.common.messaging;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
import me.lucko.luckperms.common.buffers.BufferedRequest; import me.lucko.luckperms.common.buffers.BufferedRequest;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -50,7 +57,8 @@ public abstract class AbstractMessagingService implements InternalMessagingServi
@Getter @Getter
private final String name; private final String name;
private final Set<UUID> receivedMsgs = Collections.synchronizedSet(new HashSet<>()); private final Set<UUID> receivedMessages = Collections.synchronizedSet(new HashSet<>());
private final Gson gson = new Gson();
@Getter @Getter
private final BufferedRequest<Void> updateBuffer = new BufferedRequest<Void>(10000L, r -> getPlugin().doAsync(r)) { private final BufferedRequest<Void> updateBuffer = new BufferedRequest<Void>(10000L, r -> getPlugin().doAsync(r)) {
@ -63,54 +71,91 @@ public abstract class AbstractMessagingService implements InternalMessagingServi
protected abstract void sendMessage(String channel, String message); protected abstract void sendMessage(String channel, String message);
protected void onMessage(String channel, String msg, Consumer<UUID> callback) { protected void onMessage(String channel, String msg, Consumer<String> callback) {
if (!channel.equals(CHANNEL)) { if (!channel.equals(CHANNEL)) {
return; return;
} }
UUID uuid = parseUpdateMessage(msg); if (msg.startsWith("update:") && msg.length() > "update:".length()) {
if (uuid == null) { UUID uuid = parseUpdateMessage(msg);
return; if (uuid == null) {
return;
}
if (!receivedMessages.add(uuid)) {
return;
}
plugin.getLog().info("[" + name + " Messaging] Received update ping with id: " + uuid.toString());
if (plugin.getApiProvider().getEventFactory().handleNetworkPreSync(false, uuid)) {
return;
}
plugin.getUpdateTaskBuffer().request();
if (callback != null) {
callback.accept(msg);
}
} else if (msg.startsWith("log:") && msg.length() > "log:".length()) {
String logData = msg.substring("log:".length());
Map.Entry<UUID, LogEntry> entry = null;
try {
entry = ExtendedLogEntry.deserialize(gson.fromJson(logData, JsonObject.class));
} catch (Exception e) {
plugin.getLog().warn("Error whilst deserializing log: " + logData);
e.printStackTrace();
}
if (entry == null) {
return;
}
if (!receivedMessages.add(entry.getKey())) {
return;
}
plugin.getApiProvider().getEventFactory().handleLogReceive(entry.getKey(), entry.getValue());
plugin.getLogDispatcher().dispatchFromRemote(entry.getValue());
if (callback != null) {
callback.accept(msg);
}
} }
}
if (!receivedMsgs.add(uuid)) { @Override
return; public void pushLog(LogEntry logEntry) {
} plugin.doAsync(() -> {
UUID id = generatePingId();
plugin.getLog().info("[" + name + " Messaging] Received update ping with id: " + uuid.toString()); if (plugin.getApiProvider().getEventFactory().handleLogNetworkPublish(!plugin.getConfiguration().get(ConfigKeys.PUSH_LOG_ENTRIES), id, logEntry)) {
return;
}
if (plugin.getApiProvider().getEventFactory().handleNetworkPreSync(false, uuid)) { plugin.getLog().info("[" + name + " Messaging] Sending log with id: " + id.toString());
return; sendMessage(CHANNEL, "log:" + gson.toJson(ExtendedLogEntry.serializeWithId(id, logEntry)));
} });
plugin.getUpdateTaskBuffer().request();
if (callback != null) {
callback.accept(uuid);
}
} }
@Override @Override
public void pushUpdate() { public void pushUpdate() {
plugin.doAsync(() -> { plugin.doAsync(() -> {
UUID id = generateId(); UUID id = generatePingId();
plugin.getLog().info("[" + name + " Messaging] Sending ping with id: " + id.toString()); plugin.getLog().info("[" + name + " Messaging] Sending ping with id: " + id.toString());
sendMessage(CHANNEL, "update:" + id.toString()); sendMessage(CHANNEL, "update:" + id.toString());
}); });
} }
private UUID generateId() { private UUID generatePingId() {
UUID uuid = UUID.randomUUID(); UUID uuid = UUID.randomUUID();
receivedMsgs.add(uuid); receivedMessages.add(uuid);
return uuid; return uuid;
} }
private static UUID parseUpdateMessage(String msg) { private static UUID parseUpdateMessage(String msg) {
if (!msg.startsWith("update:")) {
return null;
}
String requestId = msg.substring("update:".length()); String requestId = msg.substring("update:".length());
try { try {
return UUID.fromString(requestId); return UUID.fromString(requestId);

View File

@ -25,6 +25,7 @@
package me.lucko.luckperms.common.messaging; package me.lucko.luckperms.common.messaging;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.MessagingService; import me.lucko.luckperms.api.MessagingService;
import me.lucko.luckperms.common.buffers.BufferedRequest; import me.lucko.luckperms.common.buffers.BufferedRequest;
@ -49,4 +50,11 @@ public interface InternalMessagingService extends MessagingService {
*/ */
BufferedRequest<Void> getUpdateBuffer(); BufferedRequest<Void> getUpdateBuffer();
/**
* Pushes a log entry to connected servers.
*
* @param logEntry the log entry
*/
void pushLog(LogEntry logEntry);
} }

View File

@ -25,6 +25,7 @@
package me.lucko.luckperms.common.messaging; package me.lucko.luckperms.common.messaging;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.common.buffers.BufferedRequest; import me.lucko.luckperms.common.buffers.BufferedRequest;
public class NoopMessagingService implements InternalMessagingService { public class NoopMessagingService implements InternalMessagingService {
@ -44,6 +45,11 @@ public class NoopMessagingService implements InternalMessagingService {
return null; return null;
} }
@Override
public void pushLog(LogEntry logEntry) {
}
@Override @Override
public void pushUpdate() { public void pushUpdate() {

View File

@ -28,6 +28,7 @@ package me.lucko.luckperms.common.plugin;
import me.lucko.luckperms.api.Contexts; import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.Logger; import me.lucko.luckperms.api.Logger;
import me.lucko.luckperms.api.PlatformType; import me.lucko.luckperms.api.PlatformType;
import me.lucko.luckperms.common.actionlog.LogDispatcher;
import me.lucko.luckperms.common.api.ApiProvider; import me.lucko.luckperms.common.api.ApiProvider;
import me.lucko.luckperms.common.buffers.BufferedRequest; import me.lucko.luckperms.common.buffers.BufferedRequest;
import me.lucko.luckperms.common.caching.handlers.CachedStateManager; import me.lucko.luckperms.common.caching.handlers.CachedStateManager;
@ -181,6 +182,13 @@ public interface LuckPermsPlugin {
*/ */
PermissionVault getPermissionVault(); PermissionVault getPermissionVault();
/**
* Gets the log dispatcher running on the platform
*
* @return the log dispatcher
*/
LogDispatcher getLogDispatcher();
/** /**
* Gets the LuckPerms Scheduler instance * Gets the LuckPerms Scheduler instance
* *
@ -380,13 +388,6 @@ public interface LuckPermsPlugin {
return null; return null;
} }
/**
* Gets a set of players ignoring logging output
*
* @return a {@link Set} of {@link UUID}s
*/
Set<UUID> getIgnoringLogs();
/** /**
* Gets the update task buffer of the platform, used for scheduling and running update tasks. * Gets the update task buffer of the platform, used for scheduling and running update tasks.
* *

View File

@ -1,3 +1,28 @@
/*
* 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.storage.backing.file; package me.lucko.luckperms.common.storage.backing.file;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;

View File

@ -1,3 +1,28 @@
/*
* 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.utils; package me.lucko.luckperms.common.utils;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;

View File

@ -1,3 +1,28 @@
/*
* 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.verbose; package me.lucko.luckperms.common.verbose;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;

View File

@ -33,6 +33,7 @@ import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.LuckPermsApi; import me.lucko.luckperms.api.LuckPermsApi;
import me.lucko.luckperms.api.PlatformType; import me.lucko.luckperms.api.PlatformType;
import me.lucko.luckperms.api.context.ImmutableContextSet; import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.common.actionlog.LogDispatcher;
import me.lucko.luckperms.common.api.ApiHandler; import me.lucko.luckperms.common.api.ApiHandler;
import me.lucko.luckperms.common.api.ApiProvider; import me.lucko.luckperms.common.api.ApiProvider;
import me.lucko.luckperms.common.backup.ImporterSender; import me.lucko.luckperms.common.backup.ImporterSender;
@ -125,9 +126,6 @@ import java.util.stream.Collectors;
@Plugin(id = "luckperms", name = "LuckPerms", version = VersionData.VERSION, authors = {"Luck"}, description = "A permissions plugin") @Plugin(id = "luckperms", name = "LuckPerms", version = VersionData.VERSION, authors = {"Luck"}, description = "A permissions plugin")
public class LPSpongePlugin implements LuckPermsPlugin { public class LPSpongePlugin implements LuckPermsPlugin {
private final Set<UUID> ignoringLogs = ConcurrentHashMap.newKeySet();
private Set<UUID> uniqueConnections = ConcurrentHashMap.newKeySet();
@Inject @Inject
private Logger logger; private Logger logger;
@ -173,6 +171,8 @@ public class LPSpongePlugin implements LuckPermsPlugin {
private VerboseHandler verboseHandler; private VerboseHandler verboseHandler;
private SpongeSenderFactory senderFactory; private SpongeSenderFactory senderFactory;
private PermissionVault permissionVault; private PermissionVault permissionVault;
private LogDispatcher logDispatcher;
private Set<UUID> uniqueConnections = ConcurrentHashMap.newKeySet();
@Listener(order = Order.FIRST) @Listener(order = Order.FIRST)
public void onEnable(GamePreInitializationEvent event) { public void onEnable(GamePreInitializationEvent event) {
@ -185,6 +185,7 @@ public class LPSpongePlugin implements LuckPermsPlugin {
LuckPermsPlugin.sendStartupBanner(getConsoleSender(), this); LuckPermsPlugin.sendStartupBanner(getConsoleSender(), this);
verboseHandler = new VerboseHandler(scheduler.async(), getVersion()); verboseHandler = new VerboseHandler(scheduler.async(), getVersion());
permissionVault = new PermissionVault(scheduler.async()); permissionVault = new PermissionVault(scheduler.async());
logDispatcher = new LogDispatcher(this);
timings = new LPTimings(this); timings = new LPTimings(this);
getLog().info("Loading configuration..."); getLog().info("Loading configuration...");

View File

@ -278,6 +278,16 @@ messaging-service="none"
# If LuckPerms should automatically push updates after a change has been made with a command. # If LuckPerms should automatically push updates after a change has been made with a command.
auto-push-updates=true auto-push-updates=true
# If LuckPerms should push logging entries to connected servers via the messaging service.
push-log-entries=true
# If LuckPerms should broadcast received logging entries to players on this platform.
#
# If you have LuckPerms installed on your backend servers as well as a BungeeCord proxy, you should
# set this option to false on either your backends or your proxies, to avoid players being messaged
# twice about log entries.
broadcast-received-log-entries=true
# Settings for Redis. # Settings for Redis.
# Port 6379 is used by default; set address to "host:port" if differs # Port 6379 is used by default; set address to "host:port" if differs
redis { redis {