mirror of
https://github.com/DiscordSRV/Ascension.git
synced 2025-02-28 03:42:46 +01:00
Resync command
This commit is contained in:
parent
daf4b313a6
commit
58929ce957
@ -23,10 +23,7 @@ import com.discordsrv.common.DiscordSRV;
|
|||||||
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
||||||
import com.discordsrv.common.command.game.abstraction.GameCommandArguments;
|
import com.discordsrv.common.command.game.abstraction.GameCommandArguments;
|
||||||
import com.discordsrv.common.command.game.abstraction.GameCommandExecutor;
|
import com.discordsrv.common.command.game.abstraction.GameCommandExecutor;
|
||||||
import com.discordsrv.common.command.game.command.subcommand.DebugCommand;
|
import com.discordsrv.common.command.game.command.subcommand.*;
|
||||||
import com.discordsrv.common.command.game.command.subcommand.LinkCommand;
|
|
||||||
import com.discordsrv.common.command.game.command.subcommand.ReloadCommand;
|
|
||||||
import com.discordsrv.common.command.game.command.subcommand.VersionCommand;
|
|
||||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||||
import com.discordsrv.common.component.util.ComponentUtil;
|
import com.discordsrv.common.component.util.ComponentUtil;
|
||||||
|
|
||||||
@ -42,6 +39,7 @@ public class DiscordSRVCommand implements GameCommandExecutor {
|
|||||||
.then(DebugCommand.get(discordSRV))
|
.then(DebugCommand.get(discordSRV))
|
||||||
.then(LinkCommand.get(discordSRV))
|
.then(LinkCommand.get(discordSRV))
|
||||||
.then(ReloadCommand.get(discordSRV))
|
.then(ReloadCommand.get(discordSRV))
|
||||||
|
.then(ResyncCommand.get(discordSRV))
|
||||||
.then(VersionCommand.get(discordSRV));
|
.then(VersionCommand.get(discordSRV));
|
||||||
}
|
}
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
|
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* 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.command.game.command.subcommand;
|
||||||
|
|
||||||
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
||||||
|
import com.discordsrv.common.command.game.abstraction.GameCommandArguments;
|
||||||
|
import com.discordsrv.common.command.game.abstraction.GameCommandExecutor;
|
||||||
|
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||||
|
import com.discordsrv.common.future.util.CompletableFutureUtil;
|
||||||
|
import com.discordsrv.common.groupsync.GroupSyncModule;
|
||||||
|
import com.discordsrv.common.groupsync.enums.GroupSyncCause;
|
||||||
|
import com.discordsrv.common.groupsync.enums.GroupSyncResult;
|
||||||
|
import com.discordsrv.common.player.IPlayer;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.event.HoverEvent;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class ResyncCommand implements GameCommandExecutor {
|
||||||
|
|
||||||
|
private static GameCommand INSTANCE;
|
||||||
|
|
||||||
|
public static GameCommand get(DiscordSRV discordSRV) {
|
||||||
|
if (INSTANCE == null) {
|
||||||
|
INSTANCE = GameCommand.literal("resync")
|
||||||
|
.requiredPermission("discordsrv.admin.resync")
|
||||||
|
.executor(new ResyncCommand(discordSRV));
|
||||||
|
}
|
||||||
|
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final DiscordSRV discordSRV;
|
||||||
|
|
||||||
|
public ResyncCommand(DiscordSRV discordSRV) {
|
||||||
|
this.discordSRV = discordSRV;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(ICommandSender sender, GameCommandArguments arguments) {
|
||||||
|
GroupSyncModule module = discordSRV.getModule(GroupSyncModule.class);
|
||||||
|
if (module == null) {
|
||||||
|
sender.sendMessage(Component.text("GroupSync module has not initialized correctly.", NamedTextColor.RED));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.sendMessage(Component.text("Synchronizing online players", NamedTextColor.GRAY));
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
CompletableFutureUtil.combine(resyncOnlinePlayers(module))
|
||||||
|
.whenComplete((results, t) -> {
|
||||||
|
EnumMap<GroupSyncResult, AtomicInteger> resultCounts = new EnumMap<>(GroupSyncResult.class);
|
||||||
|
int total = 0;
|
||||||
|
for (Set<GroupSyncResult> result : results) {
|
||||||
|
for (GroupSyncResult singleResult : result) {
|
||||||
|
total++;
|
||||||
|
resultCounts.computeIfAbsent(singleResult, key -> new AtomicInteger(0)).getAndIncrement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String resultHover;
|
||||||
|
if (total == 0) {
|
||||||
|
resultHover = "Nothing done";
|
||||||
|
} else {
|
||||||
|
resultHover = total + " result" + (total == 1 ? "" : "s") + ":\n\n" +
|
||||||
|
resultCounts.entrySet().stream()
|
||||||
|
.map(entry -> entry.getKey().toString() + ": " + entry.getValue().get())
|
||||||
|
.collect(Collectors.joining("\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
long time = System.currentTimeMillis() - startTime;
|
||||||
|
sender.sendMessage(
|
||||||
|
Component.text("Synchronization completed in ", NamedTextColor.GRAY)
|
||||||
|
.append(Component.text(time + "ms", NamedTextColor.GREEN))
|
||||||
|
.append(Component.text(" (", NamedTextColor.GRAY))
|
||||||
|
.append(Component.text(total, NamedTextColor.GREEN))
|
||||||
|
.append(Component.text(" result" + (total == 1 ? "" : "s") + ")", NamedTextColor.GRAY))
|
||||||
|
.hoverEvent(HoverEvent.showText(Component.text(resultHover)))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<CompletableFuture<Set<GroupSyncResult>>> resyncOnlinePlayers(GroupSyncModule module) {
|
||||||
|
List<CompletableFuture<Set<GroupSyncResult>>> futures = new ArrayList<>();
|
||||||
|
for (IPlayer player : discordSRV.playerProvider().allPlayers()) {
|
||||||
|
futures.add(module.resync(player.uniqueId(), GroupSyncCause.COMMAND));
|
||||||
|
}
|
||||||
|
return futures;
|
||||||
|
}
|
||||||
|
}
|
@ -23,6 +23,7 @@ import com.discordsrv.api.discord.api.entity.guild.DiscordRole;
|
|||||||
import com.discordsrv.api.discord.events.member.role.DiscordMemberRoleAddEvent;
|
import com.discordsrv.api.discord.events.member.role.DiscordMemberRoleAddEvent;
|
||||||
import com.discordsrv.api.discord.events.member.role.DiscordMemberRoleRemoveEvent;
|
import com.discordsrv.api.discord.events.member.role.DiscordMemberRoleRemoveEvent;
|
||||||
import com.discordsrv.api.event.bus.Subscribe;
|
import com.discordsrv.api.event.bus.Subscribe;
|
||||||
|
import com.discordsrv.api.module.type.PermissionDataProvider;
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
import com.discordsrv.common.config.main.GroupSyncConfig;
|
import com.discordsrv.common.config.main.GroupSyncConfig;
|
||||||
import com.discordsrv.common.debug.DebugGenerateEvent;
|
import com.discordsrv.common.debug.DebugGenerateEvent;
|
||||||
@ -34,8 +35,8 @@ import com.discordsrv.common.groupsync.enums.GroupSyncResult;
|
|||||||
import com.discordsrv.common.groupsync.enums.GroupSyncSide;
|
import com.discordsrv.common.groupsync.enums.GroupSyncSide;
|
||||||
import com.discordsrv.common.logging.NamedLogger;
|
import com.discordsrv.common.logging.NamedLogger;
|
||||||
import com.discordsrv.common.module.type.AbstractModule;
|
import com.discordsrv.common.module.type.AbstractModule;
|
||||||
import com.discordsrv.api.module.type.PermissionDataProvider;
|
|
||||||
import com.discordsrv.common.player.IPlayer;
|
import com.discordsrv.common.player.IPlayer;
|
||||||
|
import com.discordsrv.common.player.event.PlayerConnectedEvent;
|
||||||
import com.github.benmanes.caffeine.cache.Cache;
|
import com.github.benmanes.caffeine.cache.Cache;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@ -237,29 +238,29 @@ public class GroupSyncModule extends AbstractModule<DiscordSRV> {
|
|||||||
|
|
||||||
// Resync user
|
// Resync user
|
||||||
|
|
||||||
public void resync(UUID player, GroupSyncCause cause) {
|
public CompletableFuture<Set<GroupSyncResult>> resync(UUID player, GroupSyncCause cause) {
|
||||||
lookupLinkedAccount(player).whenComplete((userId, t) -> {
|
return lookupLinkedAccount(player).thenCompose(userId -> {
|
||||||
if (userId == null) {
|
if (userId == null) {
|
||||||
return;
|
return CompletableFuture.completedFuture(Collections.emptySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
resync(player, userId, cause);
|
return CompletableFutureUtil.combine(resync(player, userId, cause));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resync(long userId, GroupSyncCause cause) {
|
public CompletableFuture<Set<GroupSyncResult>> resync(long userId, GroupSyncCause cause) {
|
||||||
lookupLinkedAccount(userId).whenComplete((player, t) -> {
|
return lookupLinkedAccount(userId).thenCompose(player -> {
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
return;
|
return CompletableFuture.completedFuture(Collections.emptySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
resync(player, userId, cause);
|
return CompletableFutureUtil.combine(resync(player, userId, cause));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resync(UUID player, long userId, GroupSyncCause cause) {
|
public Collection<CompletableFuture<GroupSyncResult>> resync(UUID player, long userId, GroupSyncCause cause) {
|
||||||
if (noPermissionProvider() || (!discordSRV.playerProvider().player(player).isPresent() && !supportsOffline())) {
|
if (noPermissionProvider() || (!discordSRV.playerProvider().player(player).isPresent() && !supportsOffline())) {
|
||||||
return;
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<GroupSyncConfig.PairConfig, CompletableFuture<GroupSyncResult>> futures = new LinkedHashMap<>();
|
Map<GroupSyncConfig.PairConfig, CompletableFuture<GroupSyncResult>> futures = new LinkedHashMap<>();
|
||||||
@ -268,6 +269,7 @@ public class GroupSyncModule extends AbstractModule<DiscordSRV> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logSummary(player, cause, futures);
|
logSummary(player, cause, futures);
|
||||||
|
return futures.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resyncPair(GroupSyncConfig.PairConfig pair, GroupSyncCause cause) {
|
private void resyncPair(GroupSyncConfig.PairConfig pair, GroupSyncCause cause) {
|
||||||
@ -378,6 +380,11 @@ public class GroupSyncModule extends AbstractModule<DiscordSRV> {
|
|||||||
|
|
||||||
// Listeners & methods to indicate something changed
|
// Listeners & methods to indicate something changed
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onPlayerConnected(PlayerConnectedEvent event) {
|
||||||
|
resync(event.player().uniqueId(), GroupSyncCause.GAME_JOIN);
|
||||||
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onDiscordMemberRoleAdd(DiscordMemberRoleAddEvent event) {
|
public void onDiscordMemberRoleAdd(DiscordMemberRoleAddEvent event) {
|
||||||
event.getRoles().forEach(role -> roleChanged(event.getMember().getId(), role.getId(), false));
|
event.getRoles().forEach(role -> roleChanged(event.getMember().getId(), role.getId(), false));
|
||||||
|
@ -48,7 +48,7 @@ public class SynchronizationSummary {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
int count = pairs.size();
|
int count = pairs.size();
|
||||||
StringBuilder message = new StringBuilder(
|
StringBuilder message = new StringBuilder(
|
||||||
"Group synchronization (of " + count + " pairs) for " + player + " (" + cause + ")");
|
"Group synchronization (of " + count + " pair" + (count == 1 ? "" : "s") + ") for " + player + " (" + cause + ")");
|
||||||
|
|
||||||
for (Map.Entry<GroupSyncResult, Set<GroupSyncConfig.PairConfig>> entry : pairs.entrySet()) {
|
for (Map.Entry<GroupSyncResult, Set<GroupSyncConfig.PairConfig>> entry : pairs.entrySet()) {
|
||||||
message.append(count == 1 ? ": " : "\n")
|
message.append(count == 1 ? ": " : "\n")
|
||||||
|
Loading…
Reference in New Issue
Block a user