mirror of
https://github.com/DiscordSRV/Ascension.git
synced 2024-11-22 11:55:54 +01:00
Debug reports
This commit is contained in:
parent
6f638ffb33
commit
d1d05e7081
@ -31,6 +31,9 @@ import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.ServicesManager;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@ -127,6 +130,12 @@ public class VaultIntegration extends PluginIntegration<BukkitDiscordSRV> implem
|
||||
return discordSRV.plugin().getServer().getOfflinePlayer(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getGroups() {
|
||||
String[] groups = permission.getGroups();
|
||||
return groups != null ? Arrays.asList(groups) : Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> hasGroup(UUID player, String groupName, boolean includeInherited) {
|
||||
if (permission == null || !permission.isEnabled() || !permission.hasGroupSupport()) {
|
||||
|
@ -40,6 +40,9 @@ dependencies {
|
||||
runtimeDownloadApi 'org.spongepowered:configurate-yaml:' + rootProject.configurateVersion
|
||||
runtimeDownloadApi 'org.spongepowered:configurate-hocon:' + rootProject.configurateVersion
|
||||
|
||||
// Jackson (transitive in :api)
|
||||
compileOnly 'com.fasterxml.jackson.core:jackson-databind:2.13.1'
|
||||
|
||||
// Logging
|
||||
compileOnlyApi project(':common:common-slf4j-hack')
|
||||
compileOnly 'org.apache.logging.log4j:log4j-core:2.0-beta9'
|
||||
|
@ -101,8 +101,8 @@ public abstract class AbstractDiscordSRV<C extends MainConfig, CC extends Connec
|
||||
*/
|
||||
protected final void load() {
|
||||
this.logger = new DiscordSRVLogger(this);
|
||||
this.moduleManager = new ModuleManager(this);
|
||||
this.eventBus = new EventBusImpl(this);
|
||||
this.moduleManager = new ModuleManager(this);
|
||||
this.placeholderService = new PlaceholderServiceImpl(this);
|
||||
this.componentFactory = new ComponentFactory(this);
|
||||
this.discordAPI = new DiscordAPIImpl(this);
|
||||
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* This file is part of DiscordSRV, licensed under the GPLv3 License
|
||||
* Copyright (c) 2016-2022 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.discordsrv.common.debug;
|
||||
|
||||
import com.discordsrv.api.event.events.Event;
|
||||
import com.discordsrv.common.debug.file.DebugFile;
|
||||
|
||||
public class DebugGenerateEvent implements Event {
|
||||
|
||||
private final DebugReport report;
|
||||
|
||||
public DebugGenerateEvent(DebugReport report) {
|
||||
this.report = report;
|
||||
}
|
||||
|
||||
public void addFile(DebugFile file) {
|
||||
report.addFile(file);
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* This file is part of DiscordSRV, licensed under the GPLv3 License
|
||||
* Copyright (c) 2016-2022 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.discordsrv.common.debug;
|
||||
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.debug.file.DebugFile;
|
||||
import com.discordsrv.common.debug.file.KeyValueDebugFile;
|
||||
import com.discordsrv.common.debug.file.TextDebugFile;
|
||||
import com.discordsrv.common.plugin.Plugin;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class DebugReport {
|
||||
|
||||
private final List<DebugFile> files = new ArrayList<>();
|
||||
private final DiscordSRV discordSRV;
|
||||
|
||||
public DebugReport(DiscordSRV discordSRV) {
|
||||
this.discordSRV = discordSRV;
|
||||
}
|
||||
|
||||
public void generate() {
|
||||
discordSRV.eventBus().publish(new DebugGenerateEvent(this));
|
||||
|
||||
addFile(environment());
|
||||
addFile(plugins());
|
||||
for (Path debugLog : discordSRV.logger().getDebugLogs()) {
|
||||
addFile(readFile(1, debugLog));
|
||||
}
|
||||
}
|
||||
|
||||
public void addFile(DebugFile file) {
|
||||
files.add(file);
|
||||
}
|
||||
|
||||
public List<DebugFile> getFiles() {
|
||||
return files;
|
||||
}
|
||||
|
||||
private DebugFile environment() {
|
||||
Map<String, Object> values = new LinkedHashMap<>();
|
||||
values.put("discordSRV", discordSRV.getClass().getSimpleName());
|
||||
values.put("version", discordSRV.version());
|
||||
values.put("status", discordSRV.status().name());
|
||||
values.put("jdaStatus", discordSRV.jda().map(jda -> jda.getStatus().name()).orElse("JDA null"));
|
||||
values.put("platformLogger", discordSRV.platformLogger().getClass().getName());
|
||||
values.put("onlineMode", discordSRV.onlineMode().name());
|
||||
|
||||
values.put("javaVersion", System.getProperty("java.version"));
|
||||
values.put("javaVendor", System.getProperty("java.vendor")
|
||||
+ " (" + System.getProperty("java.vendor.url") + ")");
|
||||
|
||||
values.put("operatingSystem", System.getProperty("os.name")
|
||||
+ " " + System.getProperty("os.version")
|
||||
+ " (" + System.getProperty("os.arch") + ")");
|
||||
|
||||
return new KeyValueDebugFile(10, "environment.json", values);
|
||||
}
|
||||
|
||||
private DebugFile plugins() {
|
||||
List<Plugin> plugins = discordSRV.pluginManager().getPlugins();
|
||||
StringBuilder builder = new StringBuilder("Plugins (" + plugins.size() + "):\n");
|
||||
|
||||
for (Plugin plugin : plugins) {
|
||||
builder.append('\n')
|
||||
.append(plugin.name())
|
||||
.append(" v").append(plugin.version())
|
||||
.append(" ").append(plugin.authors());
|
||||
}
|
||||
return new TextDebugFile(5, "plugins.txt", builder.toString());
|
||||
}
|
||||
|
||||
private DebugFile readFile(int order, Path file) {
|
||||
String fileName = file.getFileName().toString();
|
||||
if (!Files.exists(file)) {
|
||||
return new TextDebugFile(order, fileName, "File does not exist");
|
||||
}
|
||||
|
||||
try {
|
||||
List<String> lines = Files.readAllLines(file, StandardCharsets.UTF_8);
|
||||
return new TextDebugFile(order, fileName, String.join("\n", lines));
|
||||
} catch (IOException e) {
|
||||
return new TextDebugFile(order, fileName, ExceptionUtils.getStackTrace(e));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* This file is part of DiscordSRV, licensed under the GPLv3 License
|
||||
* Copyright (c) 2016-2022 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.discordsrv.common.debug.file;
|
||||
|
||||
public interface DebugFile {
|
||||
|
||||
int order();
|
||||
String name();
|
||||
String content();
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* This file is part of DiscordSRV, licensed under the GPLv3 License
|
||||
* Copyright (c) 2016-2022 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.discordsrv.common.debug.file;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class KeyValueDebugFile implements DebugFile {
|
||||
|
||||
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||
|
||||
private final int order;
|
||||
private final String name;
|
||||
private final Map<String, Object> values;
|
||||
|
||||
public KeyValueDebugFile(int order, String name, Map<String, Object> values) {
|
||||
this.order = order;
|
||||
this.name = name;
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int order() {
|
||||
return order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String content() {
|
||||
try {
|
||||
return OBJECT_MAPPER.writeValueAsString(values);
|
||||
} catch (JsonProcessingException e) {
|
||||
return ExceptionUtils.getStackTrace(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* This file is part of DiscordSRV, licensed under the GPLv3 License
|
||||
* Copyright (c) 2016-2022 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.discordsrv.common.debug.file;
|
||||
|
||||
public class TextDebugFile implements DebugFile {
|
||||
|
||||
private final int order;
|
||||
private final String name;
|
||||
private final String content;
|
||||
|
||||
public TextDebugFile(String name, CharSequence content) {
|
||||
this(0, name, content);
|
||||
}
|
||||
|
||||
public TextDebugFile(int order, String name, CharSequence content) {
|
||||
this.order = order;
|
||||
this.name = name;
|
||||
this.content = content.toString();
|
||||
}
|
||||
|
||||
public int order() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String content() {
|
||||
return content;
|
||||
}
|
||||
|
||||
}
|
@ -27,6 +27,8 @@ import com.discordsrv.api.event.events.Cancellable;
|
||||
import com.discordsrv.api.event.events.Event;
|
||||
import com.discordsrv.api.event.events.Processable;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.debug.DebugGenerateEvent;
|
||||
import com.discordsrv.common.debug.file.TextDebugFile;
|
||||
import com.discordsrv.common.exception.InvalidListenerMethodException;
|
||||
import com.discordsrv.common.logging.Logger;
|
||||
import com.discordsrv.common.logging.NamedLogger;
|
||||
@ -60,6 +62,7 @@ public class EventBusImpl implements EventBus {
|
||||
public EventBusImpl(DiscordSRV discordSRV) {
|
||||
this.discordSRV = discordSRV;
|
||||
this.logger = new NamedLogger(discordSRV, "EVENT_BUS");
|
||||
subscribe(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -234,4 +237,32 @@ public class EventBusImpl implements EventBus {
|
||||
state.getValue().remove();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onDebugGenerate(DebugGenerateEvent event) {
|
||||
StringBuilder builder = new StringBuilder("Registered listeners (" + listeners.size() + "/" + allListeners.size() + "):\n");
|
||||
|
||||
for (Map.Entry<Object, List<EventListenerImpl>> entry : listeners.entrySet()) {
|
||||
Object listener = entry.getKey();
|
||||
List<EventListenerImpl> eventListeners = entry.getValue();
|
||||
builder.append('\n')
|
||||
.append(listener)
|
||||
.append(" (")
|
||||
.append(listener.getClass().getName())
|
||||
.append(") [")
|
||||
.append(eventListeners.size())
|
||||
.append("]\n");
|
||||
for (EventListenerImpl eventListener : eventListeners) {
|
||||
builder.append(" - ")
|
||||
.append(eventListener.eventClass().getName())
|
||||
.append(": ")
|
||||
.append(eventListener.methodName())
|
||||
.append(" @ ")
|
||||
.append(eventListener.priority().name())
|
||||
.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
event.addFile(new TextDebugFile("event-bus.txt", builder));
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,8 @@ import com.discordsrv.api.discord.events.member.role.DiscordMemberRoleRemoveEven
|
||||
import com.discordsrv.api.event.bus.Subscribe;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.config.main.GroupSyncConfig;
|
||||
import com.discordsrv.common.debug.DebugGenerateEvent;
|
||||
import com.discordsrv.common.debug.file.TextDebugFile;
|
||||
import com.discordsrv.common.future.util.CompletableFutureUtil;
|
||||
import com.discordsrv.common.groupsync.enums.GroupSyncCause;
|
||||
import com.discordsrv.common.groupsync.enums.GroupSyncDirection;
|
||||
@ -115,6 +117,36 @@ public class GroupSyncModule extends AbstractModule<DiscordSRV> {
|
||||
}
|
||||
}
|
||||
|
||||
// Debug
|
||||
|
||||
@Subscribe
|
||||
public void onDebugGenerate(DebugGenerateEvent event) {
|
||||
StringBuilder builder = new StringBuilder("Active pairs:");
|
||||
|
||||
for (Map.Entry<GroupSyncConfig.PairConfig, Future<?>> entry : pairs.entrySet()) {
|
||||
GroupSyncConfig.PairConfig pair = entry.getKey();
|
||||
builder.append("\n- ").append(pair)
|
||||
.append(" (tie-breaker: ").append(pair.tieBreaker())
|
||||
.append(", direction: ").append(pair.direction())
|
||||
.append(", server context: ").append(pair.serverContext).append(")");
|
||||
if (entry.getValue() != null) {
|
||||
builder.append(" [Timed]");
|
||||
}
|
||||
}
|
||||
|
||||
PermissionDataProvider.Groups groups = getPermissionProvider();
|
||||
if (groups != null) {
|
||||
builder.append("\n\nAvailable groups (").append(groups.getClass().getName()).append("):");
|
||||
|
||||
for (String group : groups.getGroups()) {
|
||||
builder.append("\n- ").append(group);
|
||||
}
|
||||
} else {
|
||||
builder.append("\n\nNo permission provider available");
|
||||
}
|
||||
event.addFile(new TextDebugFile("group-sync.txt", builder));
|
||||
}
|
||||
|
||||
private void logSummary(
|
||||
UUID player,
|
||||
GroupSyncCause cause,
|
||||
@ -146,6 +178,15 @@ public class GroupSyncModule extends AbstractModule<DiscordSRV> {
|
||||
return groupsContext == null ? discordSRV.getModule(PermissionDataProvider.Groups.class) : groupsContext;
|
||||
}
|
||||
|
||||
private boolean noPermissionProvider() {
|
||||
PermissionDataProvider.Groups groups = getPermissionProvider();
|
||||
return groups == null || !groups.isEnabled();
|
||||
}
|
||||
|
||||
private boolean supportsOffline() {
|
||||
return getPermissionProvider().supportsOffline();
|
||||
}
|
||||
|
||||
private CompletableFuture<Boolean> hasGroup(
|
||||
UUID player,
|
||||
String groupName,
|
||||
@ -209,6 +250,10 @@ public class GroupSyncModule extends AbstractModule<DiscordSRV> {
|
||||
}
|
||||
|
||||
public void resync(UUID player, long userId, GroupSyncCause cause) {
|
||||
if (noPermissionProvider() || (!discordSRV.playerProvider().player(player).isPresent() && !supportsOffline())) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<GroupSyncConfig.PairConfig, CompletableFuture<GroupSyncResult>> futures = new LinkedHashMap<>();
|
||||
for (GroupSyncConfig.PairConfig pair : pairs.keySet()) {
|
||||
futures.put(pair, resyncPair(pair, player, userId));
|
||||
@ -218,6 +263,10 @@ public class GroupSyncModule extends AbstractModule<DiscordSRV> {
|
||||
}
|
||||
|
||||
private void resyncPair(GroupSyncConfig.PairConfig pair, GroupSyncCause cause) {
|
||||
if (noPermissionProvider()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (IPlayer player : discordSRV.playerProvider().allPlayers()) {
|
||||
UUID uuid = player.uniqueId();
|
||||
Long userId = getLinkedAccount(uuid);
|
||||
@ -352,6 +401,10 @@ public class GroupSyncModule extends AbstractModule<DiscordSRV> {
|
||||
}
|
||||
|
||||
private void roleChanged(long userId, long roleId, boolean remove) {
|
||||
if (noPermissionProvider()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (checkExpectation(expectedDiscordChanges, userId, roleId, remove)) {
|
||||
return;
|
||||
}
|
||||
@ -405,6 +458,10 @@ public class GroupSyncModule extends AbstractModule<DiscordSRV> {
|
||||
}
|
||||
|
||||
private void groupChanged(UUID player, String groupName, @Nullable Set<String> serverContext, GroupSyncCause cause, boolean remove) {
|
||||
if (noPermissionProvider()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cause.isDiscordSRVCanCause() && checkExpectation(expectedMinecraftChanges, player, groupName, remove)) {
|
||||
return;
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class LuckPermsIntegration extends PluginIntegration<DiscordSRV> implements PermissionDataProvider.All {
|
||||
|
||||
@ -241,4 +242,10 @@ public class LuckPermsIntegration extends PluginIntegration<DiscordSRV> implemen
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getGroups() {
|
||||
return luckPerms.getGroupManager().getLoadedGroups().stream()
|
||||
.map(Group::getName)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
@ -22,10 +22,14 @@ import com.discordsrv.api.event.bus.EventPriority;
|
||||
import com.discordsrv.api.event.bus.Subscribe;
|
||||
import com.discordsrv.api.event.events.lifecycle.DiscordSRVReloadEvent;
|
||||
import com.discordsrv.api.event.events.lifecycle.DiscordSRVShuttingDownEvent;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.module.type.AbstractModule;
|
||||
import com.discordsrv.api.module.type.Module;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.debug.DebugGenerateEvent;
|
||||
import com.discordsrv.common.debug.file.TextDebugFile;
|
||||
import com.discordsrv.common.module.type.AbstractModule;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -33,20 +37,21 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
public class ModuleManager {
|
||||
|
||||
private final Set<AbstractModule<?>> modules = new CopyOnWriteArraySet<>();
|
||||
private final Map<String, AbstractModule<?>> moduleLookupTable = new ConcurrentHashMap<>();
|
||||
private final Set<Module> modules = new CopyOnWriteArraySet<>();
|
||||
private final Map<String, Module> moduleLookupTable = new ConcurrentHashMap<>();
|
||||
private final DiscordSRV discordSRV;
|
||||
|
||||
public ModuleManager(DiscordSRV discordSRV) {
|
||||
this.discordSRV = discordSRV;
|
||||
discordSRV.eventBus().subscribe(this);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Module> T getModule(Class<T> moduleType) {
|
||||
return (T) moduleLookupTable.computeIfAbsent(moduleType.getName(), key -> {
|
||||
AbstractModule<?> bestCandidate = null;
|
||||
Module bestCandidate = null;
|
||||
int bestCandidatePriority = Integer.MIN_VALUE;
|
||||
for (AbstractModule<?> module : modules) {
|
||||
for (Module module : modules) {
|
||||
int priority;
|
||||
if (moduleType.isAssignableFrom(module.getClass()) && ((priority = module.priority(moduleType)) > bestCandidatePriority)) {
|
||||
bestCandidate = module;
|
||||
@ -61,25 +66,29 @@ public class ModuleManager {
|
||||
this.modules.add(module);
|
||||
this.moduleLookupTable.put(module.getClass().getName(), module);
|
||||
|
||||
enable(module);
|
||||
enable(module, true);
|
||||
}
|
||||
|
||||
private void enable(AbstractModule<?> module) {
|
||||
private void enable(Module module, boolean enableNonAbstract) {
|
||||
try {
|
||||
module.enableModule();
|
||||
if (module instanceof AbstractModule) {
|
||||
((AbstractModule<?>) module).enableModule();
|
||||
} else if (enableNonAbstract) {
|
||||
module.enable();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
discordSRV.logger().error("Failed to enable " + module.getClass().getSimpleName(), t);
|
||||
}
|
||||
}
|
||||
|
||||
public void unregister(AbstractModule<?> module) {
|
||||
public void unregister(Module module) {
|
||||
this.modules.remove(module);
|
||||
this.moduleLookupTable.values().removeIf(mod -> mod == module);
|
||||
|
||||
disable(module);
|
||||
}
|
||||
|
||||
private void disable(AbstractModule<?> module) {
|
||||
private void disable(Module module) {
|
||||
try {
|
||||
module.disable();
|
||||
} catch (Throwable t) {
|
||||
@ -89,16 +98,16 @@ public class ModuleManager {
|
||||
|
||||
@Subscribe(priority = EventPriority.EARLY)
|
||||
public void onShuttingDown(DiscordSRVShuttingDownEvent event) {
|
||||
for (AbstractModule<?> module : modules) {
|
||||
for (Module module : modules) {
|
||||
unregister(module);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe(priority = EventPriority.EARLY)
|
||||
public void onReload(DiscordSRVReloadEvent event) {
|
||||
for (AbstractModule<?> module : modules) {
|
||||
for (Module module : modules) {
|
||||
// Check if the module needs to be enabled due to reload
|
||||
enable(module);
|
||||
enable(module, false);
|
||||
|
||||
try {
|
||||
module.reload();
|
||||
@ -107,4 +116,30 @@ public class ModuleManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onDebugGenerate(DebugGenerateEvent event) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
builder.append("Enabled modules:");
|
||||
List<Module> disabled = new ArrayList<>();
|
||||
for (Module module : modules) {
|
||||
if (!module.isEnabled()) {
|
||||
disabled.add(module);
|
||||
continue;
|
||||
}
|
||||
appendModule(builder, module);
|
||||
}
|
||||
|
||||
builder.append("\n\nDisabled modules:");
|
||||
for (Module module : disabled) {
|
||||
appendModule(builder, module);
|
||||
}
|
||||
|
||||
event.addFile(new TextDebugFile("modules.txt", builder));
|
||||
}
|
||||
|
||||
private void appendModule(StringBuilder builder, Module module) {
|
||||
builder.append('\n').append(module.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ package com.discordsrv.common.module.type;
|
||||
import com.discordsrv.api.module.type.Module;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@ -33,6 +34,7 @@ public interface PermissionDataProvider extends Module {
|
||||
interface All extends Basic, Meta, GroupsContext {}
|
||||
|
||||
interface Groups extends PermissionDataProvider {
|
||||
List<String> getGroups();
|
||||
CompletableFuture<Boolean> hasGroup(UUID player, String groupName, boolean includeInherited);
|
||||
CompletableFuture<Void> addGroup(UUID player, String groupName);
|
||||
CompletableFuture<Void> removeGroup(UUID player, String groupName);
|
||||
|
Loading…
Reference in New Issue
Block a user