1.1 - Store data using lettuce instead of data.yml

This commit is contained in:
NotAlexNoyle committed 2026-04-13 03:29:35 -04:00
1 parent ff4118bb4e
commit 5bf3e2def8
26 files changed
+328 -451

No files matched your search

+10 -23
View File
@@ -14,6 +14,7 @@ Built for **Purpur 1.19.4**. Clients from **Minecraft 1.8 through 1.21.11** can
- **OpenInv support.** If installed, Vanish-OG hands off chest viewing to OpenInv so staff never enter spectator mode and can't get stuck there after a crash.
- **MiniPlaceholders support** (via Utilities-OG) for use in chat, tab, and hologram plugins.
- **Safer chest peeking.** Staff no longer occasionally fall through the floor when finishing a peek. Pair with [WGamemode](https://github.com/true-og/WGamemode) to auto-restore gamemodes after crashes if OpenInv is not installed.
- **KeyDB-backed storage.** Vanish state and player preferences are stored in KeyDB (Redis-compatible) via the Lettuce client instead of flat YAML files. Requires a `KeyDB.URI` in `config.yml`.
- **Removed old clutter.** Deprecated functions are removed and the code is updated for java 17 conventions.
### Chat-OG handles some events that used to be handled by SuperVanish
@@ -45,37 +46,25 @@ Main command: `/vanish` (also `/v`, `/sv`, `/supervanish`).
### State queries
- `VanishAPI.getInvisiblePlayers()`
Returns the UUIDs of all online vanished players. Run this on the main server thread.
Returns the UUIDs of all online vanished players.
- `VanishAPI.getAllInvisiblePlayers()`
Returns the UUIDs of all vanished players, including offline players stored in `data.yml`. Run this on the main server thread.
- `VanishAPI.isPlayerVanished(Player player)`
Preferred asynchronous check for an online player. Safe to call from either thread. The returned `CompletableFuture<Boolean>` completes off the main thread.
- `VanishAPI.isUUIDVanished(UUID uuid)`
Preferred asynchronous check for any player UUID. Safe to call from either thread. The returned `CompletableFuture<Boolean>` completes off the main thread.
If you touch Bukkit APIs in an async completion callback, switch back to the server thread first.
Returns the UUIDs of all vanished players, including offline players stored in KeyDB.
- `VanishAPI.isVanished(UUID uuid)`
Checks if a player is vanished by querying KeyDB. Returns `boolean`.
Java:
```java
VanishAPI.isUUIDVanished(player.getUniqueId()).thenAccept(vanished ->
Bukkit.getScheduler().runTask(plugin, () -> {
if (vanished) {
UtilitiesOG.trueogMessage(player, "You are vanished.");
}
})
);
if (VanishAPI.isVanished(player.getUniqueId())) {
UtilitiesOG.trueogMessage(player, "You are vanished.");
}
```
Kotlin:
```kotlin
VanishAPI.isUUIDVanished(player.uniqueId).thenAccept { vanished ->
Bukkit.getScheduler().runTask(plugin) {
if (vanished) {
UtilitiesOG.trueogMessage(player, "You are vanished.")
}
}
if (VanishAPI.isVanished(player.uniqueId)) {
UtilitiesOG.trueogMessage(player, "You are vanished.")
}
```
@@ -116,8 +105,6 @@ VanishAPI.showPlayer(target)
Returns `config.yml`. Main thread only; treat the returned `FileConfiguration` as Bukkit-owned mutable state.
- `VanishAPI.getMessages()`
Returns `messages.yml`. Main thread only; treat the returned `FileConfiguration` as Bukkit-owned mutable state.
- `VanishAPI.getPlayerData()`
Returns the persistent player storage file (`data.yml` / player data config). Main thread only.
- `VanishAPI.reloadConfig()`
Reloads the plugin. Main thread only.
- `VanishAPI.getPlugin()`
+4 -1
View File
@@ -22,7 +22,7 @@ java {
/* ----------------------------- Metadata ------------------------------ */
group = "de.myzelyam.vanishog" // Declare bundle identifier.
version = "6.2.22" // Declare plugin version (will be in .jar).
version = "1.1" // Declare plugin version (will be in .jar).
val apiVersion = "1.13" // Declare minecraft server target version.
@@ -66,6 +66,9 @@ dependencies {
// ProtocolLib (local jar in libs/).
compileOnly(files("libs/ProtocolLib-5.0.jar"))
// Lettuce API (for KeyDB).
implementation("io.lettuce:lettuce-core:7.5.1.RELEASE") // Import the Lettuce API for keydb.
// Citizens API.
compileOnly("net.citizensnpcs:citizensapi:2.0.28-SNAPSHOT")
@@ -11,12 +11,10 @@ package de.myzelyam.api.vanish;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.utils.Validation;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.concurrent.CompletableFuture;
import java.util.List;
import java.util.UUID;
@@ -48,31 +46,15 @@ public class VanishAPI {
}
/**
* Asynchronously checks if an online player is currently vanished.
*
* @param p - the player.
* @return A future that completes with TRUE if the player is vanished, FALSE
* otherwise.
*/
public static CompletableFuture<Boolean> isPlayerVanished(Player p) {
Validation.checkNotNull("Player cannot be null!", p);
return isUUIDVanished(p.getUniqueId());
}
/**
* Asynchronously checks if a player is vanished, online or offline.
* Checks if a player is vanished by querying KeyDB.
*
* @param uuid - the player's UUID.
* @return A future that completes with TRUE if the player is vanished, FALSE
* otherwise.
* @return TRUE if the player is vanished, FALSE otherwise.
*/
public static CompletableFuture<Boolean> isUUIDVanished(UUID uuid) {
public static boolean isVanished(UUID uuid) {
Validation.checkNotNull("UUID cannot be null!", uuid);
return CompletableFuture.supplyAsync(() -> PLUGIN.getVanishStateMgr().isVanished(uuid),
runnable -> Bukkit.getScheduler().runTaskAsynchronously(PLUGIN, runnable));
return PLUGIN.getVanishStateMgr().isVanished(uuid);
}
@@ -126,12 +108,6 @@ public class VanishAPI {
}
public static FileConfiguration getPlayerData() {
return PLUGIN.getPlayerData();
}
public static void reloadConfig() {
PLUGIN.reload();
@@ -44,8 +44,9 @@ import de.myzelyam.supervanish.listeners.WorldChangeListener;
import de.myzelyam.supervanish.utils.ExceptionLogger;
import de.myzelyam.supervanish.utils.VersionUtil;
import de.myzelyam.supervanish.visibility.ActionBarMgr;
import de.myzelyam.supervanish.visibility.FileVanishStateMgr;
import de.myzelyam.supervanish.visibility.KeyDBVanishStateMgr;
import de.myzelyam.supervanish.visibility.ServerListPacketListener;
import de.myzelyam.supervanish.visibility.VanishStateMgr;
import de.myzelyam.supervanish.visibility.VisibilityChanger;
import de.myzelyam.supervanish.visibility.hiders.PreventionHider;
import net.kyori.adventure.text.Component;
@@ -54,11 +55,6 @@ import net.trueog.utilitiesog.UtilitiesOG;
public class SuperVanish extends JavaPlugin implements SuperVanishPlugin {
public static final String[] NON_REQUIRED_SETTINGS_UPDATES = { "6.0.0", "6.0.1", "6.0.2", "6.0.3", "6.0.4", "6.0.5",
"6.1.0", "6.1.1", "6.1.2", "6.1.3", "6.1.4", "6.1.5", "6.1.6", "6.1.7", "6.1.8", "6.2.0", "6.2.1", "6.2.2",
"6.2.3", "6.2.4", "6.2.5", "6.2.6", "6.2.7", "6.2.8", "6.2.9", "6.2.10", "6.2.11", "6.2.12", "6.2.13",
"6.2.14", "6.2.15", "6.2.16", "6.2.17", "6.2.18", "6.2.19", "6.2.20" };
public static final String[] NON_REQUIRED_MESSAGES_UPDATES = { "6.0.0", "6.0.1", "6.0.2", "6.0.3", "6.0.4", "6.0.5",
"6.1.0", "6.1.1", "6.1.2", "6.1.3", "6.1.4", "6.1.5", "6.1.6", "6.1.7", "6.1.8", "6.2.0", "6.2.1", "6.2.2",
"6.2.3", "6.2.4", "6.2.5", "6.2.6", "6.2.7", "6.2.8", "6.2.9", "6.2.10", "6.2.11", "6.2.12", "6.2.13",
@@ -66,7 +62,7 @@ public class SuperVanish extends JavaPlugin implements SuperVanishPlugin {
private boolean useProtocolLib;
private ActionBarMgr actionBarMgr;
private FileVanishStateMgr vanishStateMgr;
private VanishStateMgr vanishStateMgr;
private VersionUtil versionUtil;
private ConfigMgr configMgr;
private FeatureMgr featureMgr;
@@ -86,7 +82,7 @@ public class SuperVanish extends JavaPlugin implements SuperVanishPlugin {
useProtocolLib = getServer().getPluginManager().isPluginEnabled("ProtocolLib");
if (!useProtocolLib) {
log(Level.INFO, "Please install ProtocolLib to be able to use all SuperVanish features: "
log(Level.INFO, "Please install ProtocolLib to be able to use all Vanish-OG features: "
+ "https://www.spigotmc.org/resources/protocollib.1997/");
}
@@ -97,7 +93,9 @@ public class SuperVanish extends JavaPlugin implements SuperVanishPlugin {
layeredPermissionChecker = new LayeredPermissionChecker(this);
command = new VanishCommand(this);
versionUtil = new VersionUtil(this);
vanishStateMgr = new FileVanishStateMgr(this);
vanishStateMgr = new KeyDBVanishStateMgr(this, getSettings().getString("KeyDB.URI"));
configMgr.checkFilesForLeftOvers();
visibilityChanger = new VisibilityChanger(new PreventionHider(this), this);
if (versionUtil.isOneDotXOrHigher(8) && useProtocolLib) {
@@ -149,6 +147,12 @@ public class SuperVanish extends JavaPlugin implements SuperVanishPlugin {
}
if (vanishStateMgr != null) {
vanishStateMgr.close();
}
vanishPlayers.clear();
VanishAPI.setPlugin(null);
@@ -174,8 +178,7 @@ public class SuperVanish extends JavaPlugin implements SuperVanishPlugin {
Bukkit.getOnlinePlayers().forEach((Player player) -> {
final boolean itemPickUps = getPlayerData().getBoolean(
"PlayerData." + player.getUniqueId() + ".itemPickUps",
final boolean itemPickUps = vanishStateMgr.getItemPickUps(player.getUniqueId(),
getSettings().getBoolean("InvisibilityFeatures.DefaultPickUpItemsOption"));
final boolean vanished = vanishStateMgr.isVanished(player.getUniqueId());
createVanishPlayer(player, itemPickUps);
@@ -316,7 +319,7 @@ public class SuperVanish extends JavaPlugin implements SuperVanishPlugin {
}
// ensure that there is always a vanish player
final boolean itemPickUps = getPlayerData().getBoolean("PlayerData." + player.getUniqueId() + ".itemPickUps",
final boolean itemPickUps = vanishStateMgr.getItemPickUps(player.getUniqueId(),
getSettings().getBoolean("InvisibilityFeatures.DefaultPickUpItemsOption"));
final VanishPlayer vanishPlayer = new VanishPlayer(player, this, itemPickUps);
vanishPlayers.add(vanishPlayer);
@@ -405,12 +408,6 @@ public class SuperVanish extends JavaPlugin implements SuperVanishPlugin {
}
public FileConfiguration getPlayerData() {
return configMgr.getPlayerData();
}
@Override
public FileConfiguration getConfig() {
@@ -452,7 +449,7 @@ public class SuperVanish extends JavaPlugin implements SuperVanishPlugin {
}
@Override
public FileVanishStateMgr getVanishStateMgr() {
public VanishStateMgr getVanishStateMgr() {
return vanishStateMgr;
@@ -38,30 +38,12 @@ public class RecreateFiles extends SubCommand {
}
String files;
String changes;
if (plugin.getConfigMgr().isSettingsUpdateRequired() && plugin.getConfigMgr().isMessagesUpdateRequired()) {
files = "the config and the messages file";
changes = "all settings and messages";
} else if (plugin.getConfigMgr().isSettingsUpdateRequired()) {
files = "the config";
changes = "all settings";
} else {
files = "the messages file";
changes = "all messages";
}
String files = "the messages file";
String changes = "all messages";
if (args.length != 2) {
if (!plugin.getConfigMgr().isSettingsUpdateRequired()
&& !plugin.getConfigMgr().isMessagesUpdateRequired())
{
if (!plugin.getConfigMgr().isMessagesUpdateRequired()) {
plugin.sendMessage(p, "NoConfigUpdateAvailable", p);
return;
@@ -77,9 +59,7 @@ public class RecreateFiles extends SubCommand {
if (StringUtils.equalsIgnoreCase("confirm", args[1]) || StringUtils.equalsIgnoreCase(args[1], "force")) {
if (!plugin.getConfigMgr().isSettingsUpdateRequired() && !plugin.getConfigMgr().isMessagesUpdateRequired()
&& !StringUtils.equalsIgnoreCase(args[1], "force"))
{
if (!plugin.getConfigMgr().isMessagesUpdateRequired() && !StringUtils.equalsIgnoreCase(args[1], "force")) {
plugin.sendMessage(p, "NoConfigUpdateAvailable", p);
return;
@@ -94,8 +74,8 @@ public class RecreateFiles extends SubCommand {
}
// Delete necessary files.
boolean success = false;
if (plugin.getConfigMgr().isSettingsUpdateRequired() || StringUtils.equalsIgnoreCase(args[1], "force")) {
boolean success = true;
if (StringUtils.equalsIgnoreCase(args[1], "force")) {
final File file = new File(plugin.getDataFolder().getPath() + File.separator + "config.yml");
success = file.delete();
@@ -143,14 +123,9 @@ public class RecreateFiles extends SubCommand {
} else if (StringUtils.equalsIgnoreCase("dismiss", args[1])) {
final String currentVersion = plugin.getPluginMeta().getVersion();
final boolean isDismissed = plugin.getPlayerData().getBoolean(
"PlayerData." + (p instanceof Player ? ((Player) p).getUniqueId().toString() : "CONSOLE")
+ ".dismissed." + currentVersion.replace(".", "_"),
false);
plugin.getPlayerData()
.set("PlayerData." + (p instanceof Player ? ((Player) p).getUniqueId().toString() : "CONSOLE")
+ ".dismissed." + currentVersion.replace(".", "_"), !isDismissed);
plugin.getConfigMgr().getPlayerDataFile().save();
final String dismissId = p instanceof Player ? ((Player) p).getUniqueId().toString() : "CONSOLE";
final boolean isDismissed = plugin.getVanishStateMgr().isDismissed(dismissId, currentVersion);
plugin.getVanishStateMgr().setDismissed(dismissId, currentVersion, !isDismissed);
if (!isDismissed) {
plugin.sendMessage(p, "DismissedRecreationWarning", p);
@@ -40,7 +40,7 @@ public class Reload extends SubCommand {
plugin.reload();
if (!Bukkit.getPluginManager().isPluginEnabled(plugin)) {
final String failMsg = "&cERROR: Failed to reload SuperVanish since it failed to restart itself. "
final String failMsg = "&cERROR: Failed to reload Vanish-OG since it failed to restart itself. "
+ "More information is in the console. (" + (System.currentTimeMillis() - before) + "ms)";
if (p instanceof Player player) {
@@ -40,10 +40,9 @@ public class ToggleItemPickups extends SubCommand {
private boolean toggleState(VanishPlayer vp) {
boolean hasEnabled = plugin.getPlayerData().getBoolean("PlayerData." + vp.getPlayerUUID() + ".itemPickUps");
plugin.getPlayerData().set("PlayerData." + vp.getPlayerUUID() + ".itemPickUps", !hasEnabled);
boolean hasEnabled = plugin.getVanishStateMgr().getItemPickUps(vp.getPlayerUUID(), false);
plugin.getVanishStateMgr().setItemPickUps(vp.getPlayerUUID(), !hasEnabled);
vp.setItemPickUps(!hasEnabled);
plugin.getConfigMgr().getPlayerDataFile().save();
return !hasEnabled;
}
@@ -64,7 +64,7 @@ public class VanishOther extends SubCommand {
if (target == null) {
offline = true;
uuid = plugin.getVanishStateMgr().getVanishedUUIDFromNameOnFile(name);
uuid = plugin.getVanishStateMgr().getVanishedUUIDFromName(name);
if (uuid == null) {
plugin.sendMessage(sender, "PlayerNonExistent", sender, name);
@@ -9,12 +9,9 @@
package de.myzelyam.supervanish.config;
import de.myzelyam.supervanish.SuperVanish;
import net.trueog.utilitiesog.UtilitiesOG;
import org.bukkit.configuration.file.FileConfiguration;
import java.util.List;
import java.util.Collections;
import java.util.logging.Level;
import static de.myzelyam.supervanish.SuperVanish.*;
@@ -23,14 +20,11 @@ public class ConfigMgr {
private final SuperVanish plugin;
private final FileMgr fileMgr;
private boolean settingsUpdateRequired;
private boolean messagesUpdateRequired;
private FileConfiguration settings;
private FileConfiguration messages;
private FileConfiguration playerData;
private ConfigurableFile messagesFile;
private ConfigurableFile settingsFile;
private StorageFile playerDataFile;
public ConfigMgr(SuperVanish plugin) {
@@ -42,20 +36,11 @@ public class ConfigMgr {
public void prepareFiles() {
// messages
messagesFile = (ConfigurableFile) fileMgr.addFile("messages", FileMgr.FileType.CONFIG);
messagesFile = (ConfigurableFile) fileMgr.addFile("messages");
messages = messagesFile.getConfig();
// settings
settingsFile = (ConfigurableFile) fileMgr.addFile("config", FileMgr.FileType.CONFIG);
settingsFile = (ConfigurableFile) fileMgr.addFile("config");
settings = settingsFile.getConfig();
// data
playerDataFile = (StorageFile) fileMgr.addFile("data", FileMgr.FileType.STORAGE);
playerData = playerDataFile.getConfig();
playerData.addDefault("InvisiblePlayers", Collections.emptyList());
playerData.options().copyDefaults(true);
playerData.options().setHeader(List.of("SuperVanish v" + plugin.getPluginMeta().getVersion() + " - Data file"));
playerDataFile.save();
checkFilesForLeftOvers();
}
@@ -63,31 +48,18 @@ public class ConfigMgr {
try {
String currentSettingsVersion = settings.getString("ConfigVersion");
String newestVersion = plugin.getPluginMeta().getVersion();
String currentMessagesVersion = messages.getString("MessagesVersion");
messagesUpdateRequired = fileRequiresRecreation(currentMessagesVersion, false);
settingsUpdateRequired = fileRequiresRecreation(currentSettingsVersion, true);
if (newestVersion.equals(currentSettingsVersion))
settingsUpdateRequired = false;
messagesUpdateRequired = fileRequiresRecreation(currentMessagesVersion);
if (newestVersion.equals(currentMessagesVersion))
messagesUpdateRequired = false;
if (settingsUpdateRequired || messagesUpdateRequired) {
if (messagesUpdateRequired) {
String currentVersion = plugin.getPluginMeta().getVersion();
boolean isDismissed = playerData
.getBoolean("PlayerData.CONSOLE.dismissed." + currentVersion.replace(".", "_"), false);
boolean isDismissed = plugin.getVanishStateMgr().isDismissed("CONSOLE", currentVersion);
if (!isDismissed)
plugin.log(Level.WARNING, "At least one config file needs to be recreated. "
+ "Use '/sv recreatefiles' to regenerate it.");
}
if (currentSettingsVersion.startsWith("1.5.") || currentSettingsVersion.startsWith("1.4.")) {
UtilitiesOG.logToConsole("[SuperVanish]",
"<yellow>You have a very old config file. Your settings will not work until you "
+ "regenerate your SV files using /sv recreatefiles.");
plugin.log(Level.WARNING,
"Messages file needs to be recreated. " + "Use '/sv recreatefiles' to regenerate it.");
}
@@ -99,11 +71,11 @@ public class ConfigMgr {
}
private boolean fileRequiresRecreation(String currentVersion, boolean isSettingsFile) {
private boolean fileRequiresRecreation(String currentVersion) {
if (currentVersion == null)
return true;
for (String ignoredVersion : isSettingsFile ? NON_REQUIRED_SETTINGS_UPDATES : NON_REQUIRED_MESSAGES_UPDATES) {
for (String ignoredVersion : NON_REQUIRED_MESSAGES_UPDATES) {
if (currentVersion.equalsIgnoreCase(ignoredVersion))
return false;
@@ -120,12 +92,6 @@ public class ConfigMgr {
}
public boolean isSettingsUpdateRequired() {
return settingsUpdateRequired;
}
public boolean isMessagesUpdateRequired() {
return messagesUpdateRequired;
@@ -144,12 +110,6 @@ public class ConfigMgr {
}
public FileConfiguration getPlayerData() {
return playerData;
}
public void setSettings(FileConfiguration settings) {
this.settings = settings;
@@ -174,10 +134,4 @@ public class ConfigMgr {
}
public StorageFile getPlayerDataFile() {
return playerDataFile;
}
}
@@ -26,27 +26,13 @@ public class FileMgr {
}
public PluginFile<?> addFile(String name, FileType type) {
public PluginFile<?> addFile(String name) {
if (name == null)
throw new IllegalArgumentException("The file name cannot be null!");
if (type == FileType.STORAGE) {
StorageFile file = new StorageFile(name, (SuperVanish) plugin);
files.put(name, file);
return file;
} else if (type == FileType.CONFIG) {
ConfigurableFile file = new ConfigurableFile(name, (SuperVanish) plugin);
files.put(name, file);
return file;
} else {
throw new IllegalArgumentException("The FileType cannot be null!");
}
ConfigurableFile file = new ConfigurableFile(name, (SuperVanish) plugin);
files.put(name, file);
return file;
}
@@ -67,8 +53,4 @@ public class FileMgr {
}
public enum FileType {
STORAGE, CONFIG
}
}
@@ -1,78 +0,0 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.config;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
public class StorageFile implements PluginFile<FileConfiguration> {
private final SuperVanish plugin;
private String name;
private File file;
private FileConfiguration config;
public StorageFile(String name, SuperVanish plugin) {
this.name = name;
this.plugin = plugin;
setup();
}
@Override
public String getName() {
return name;
}
private void setup() {
file = new File(plugin.getDataFolder().getPath() + File.separator + name + ".yml");
config = YamlConfiguration.loadConfiguration(file);
save();
}
@Override
public void reload() {
setup();
}
@Override
public FileConfiguration getConfig() {
return config;
}
@Override
public void save() {
try {
config.save(file);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@@ -149,11 +149,11 @@ public class SilentOpenChestPacketAdapter extends PacketAdapter {
silentOpenChest.plugin.getLogger()
.warning("IMPORTANT: Please make sure that you are using the latest "
+ "dev-build of ProtocolLib and that your server is up-to-date! This error likely "
+ "happened inside of ProtocolLib code which is out of SuperVanish's control. It's part "
+ "happened inside of ProtocolLib code which is out of Vanish-OG's control. It's part "
+ "of an optional feature module and can be removed safely by disabling "
+ "OpenChestsSilently in the config file. Please report this "
+ "error if you can reproduce it on an up-to-date server with only latest "
+ "ProtocolLib and latest SV installed.");
+ "ProtocolLib and latest Vanish-OG installed.");
suppressErrors = true;
}
@@ -188,11 +188,11 @@ public class VanishIndication extends Feature {
VanishIndication.this.plugin.logException(e);
plugin.getLogger().warning("IMPORTANT: Please make sure that you are using the latest "
+ "dev-build of ProtocolLib and that your server is up-to-date! This error likely "
+ "happened inside of ProtocolLib code which is out of SuperVanish's control. It's part "
+ "happened inside of ProtocolLib code which is out of Vanish-OG's control. It's part "
+ "of an optional feature module and can be removed safely by disabling "
+ "MarkVanishedPlayersAsSpectators in the config file. Please report this "
+ "error if you can reproduce it on an up-to-date server with only latest "
+ "ProtocolLib and latest SV installed.");
+ "ProtocolLib and latest Vanish-OG installed.");
suppressErrors = true;
}
@@ -83,7 +83,7 @@ public class PluginHookMgr implements Listener {
if (er.getMessage() != null && er.getMessage().contains("Unable to find handler list for event")) {
this.plugin.log(Level.WARNING, "" + er.getMessage() + "; This is not an issue with SuperVanish");
this.plugin.log(Level.WARNING, "" + er.getMessage() + "; This is not an issue with Vanish-OG");
return;
} else if (er.getCause() != null && er.getCause().getMessage() != null
@@ -91,7 +91,7 @@ public class PluginHookMgr implements Listener {
{
this.plugin.log(Level.WARNING,
"" + er.getCause().getMessage() + "; This is not an issue with SuperVanish");
"" + er.getCause().getMessage() + "; This is not an issue with Vanish-OG");
return;
}
@@ -89,13 +89,12 @@ public class JoinListener implements EventExecutor, Listener {
// not necessarily vanished:
// recreate files msg
if ((p.hasPermission("sv.recreatecfg") || p.hasPermission("sv.recreatefiles"))
&& (plugin.getConfigMgr().isSettingsUpdateRequired()
|| plugin.getConfigMgr().isMessagesUpdateRequired()))
&& plugin.getConfigMgr().isMessagesUpdateRequired())
{
String currentVersion = plugin.getPluginMeta().getVersion();
boolean isDismissed = plugin.getPlayerData().getBoolean(
"PlayerData." + p.getUniqueId() + ".dismissed." + currentVersion.replace(".", "_"), false);
boolean isDismissed = plugin.getVanishStateMgr().isDismissed(p.getUniqueId().toString(),
currentVersion);
if (!isDismissed)
new BukkitRunnable() {
@@ -37,7 +37,7 @@ public class LoginListener implements Listener {
return;
final Player p = e.getPlayer();
boolean vanished = plugin.getVanishStateMgr().isVanished(p.getUniqueId());
boolean itemPickUps = plugin.getPlayerData().getBoolean("PlayerData." + p.getUniqueId() + ".itemPickUps",
boolean itemPickUps = plugin.getVanishStateMgr().getItemPickUps(p.getUniqueId(),
plugin.getSettings().getBoolean("InvisibilityFeatures.DefaultPickUpItemsOption"));
plugin.createVanishPlayer(p, itemPickUps);
if (vanished && plugin.getSettings().getBoolean("VanishStateFeatures.CheckPermissionOnLogin", false)
@@ -23,7 +23,7 @@ public class ExceptionLogger {
plugin.log(loggingLevel, "Unknown exception occurred!");
else
plugin.log(loggingLevel, "Printing information...");
if (plugin.getConfigMgr().isSettingsUpdateRequired() || plugin.getConfigMgr().isMessagesUpdateRequired()) {
if (plugin.getConfigMgr().isMessagesUpdateRequired()) {
if (realEx)
plugin.log(loggingLevel, "Your config files may need to be recreated. "
@@ -42,7 +42,7 @@ public class ExceptionLogger {
StringBuilder plugins = new StringBuilder();
for (Plugin pl : Bukkit.getServer().getPluginManager().getPlugins()) {
if (pl.getName().equalsIgnoreCase("SuperVanish"))
if (pl.getName().equalsIgnoreCase("Vanish-OG"))
continue;
plugins.append(pl.getName()).append(" v").append(pl.getPluginMeta().getVersion()).append(", ");
@@ -76,8 +76,7 @@ public class ExceptionLogger {
e.printStackTrace();
if (realEx) {
if (plugin.getConfigMgr().isSettingsUpdateRequired()
|| plugin.getConfigMgr().isMessagesUpdateRequired())
if (plugin.getConfigMgr().isMessagesUpdateRequired())
plugin.log(loggingLevel, "Your config files may need to be recreated. "
+ "Running '/sv recreatefiles' might fix this problem.");
plugin.log(loggingLevel, "Please include this information");
@@ -53,11 +53,11 @@ public class ActionBarMgr {
plugin.logException(e);
plugin.getLogger().warning("IMPORTANT: Please make sure that you are using the latest "
+ "dev-build of ProtocolLib and that your server is up-to-date! This error likely "
+ "happened inside of ProtocolLib code which is out of SuperVanish's control. It's part "
+ "happened inside of ProtocolLib code which is out of Vanish-OG's control. It's part "
+ "of an optional feature module and can be removed safely by disabling "
+ "DisplayActionBar in the config file. Please report this "
+ "error if you can reproduce it on an up-to-date server with only latest "
+ "ProtocolLib and latest SV installed.");
+ "ProtocolLib and latest Vanish-OG installed.");
}
@@ -88,7 +88,7 @@ public class ActionBarMgr {
} catch (NoSuchMethodError e) {
p.sendActionBar(Component.text("SuperVanish: Please update ProtocolLib"));
p.sendActionBar(Component.text("Vanish-OG: Please update ProtocolLib"));
}
else
@@ -1,136 +0,0 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.visibility;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.Bukkit;
import de.myzelyam.api.vanish.PlayerVanishStateChangeEvent;
import de.myzelyam.supervanish.SuperVanish;
public class FileVanishStateMgr extends VanishStateMgr {
private final SuperVanish plugin;
public FileVanishStateMgr(SuperVanish plugin) {
super(plugin);
this.plugin = plugin;
}
@Override
public boolean isVanished(final UUID uuid) {
return getVanishedPlayersOnFile().contains(uuid);
}
@Override
public void setVanishedState(final UUID uuid, String name, boolean hide, String causeName) {
final PlayerVanishStateChangeEvent event = new PlayerVanishStateChangeEvent(uuid, name, hide, causeName);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
final Set<UUID> vanishedPlayers = getVanishedPlayersOnFile();
if (hide) {
vanishedPlayers.add(uuid);
} else {
vanishedPlayers.remove(uuid);
}
setVanishedPlayersOnFile(vanishedPlayers);
if (hide) {
plugin.getPlayerData().set("PlayerData." + uuid + ".information.name", name);
plugin.getConfigMgr().getPlayerDataFile().save();
}
}
@Override
public Set<UUID> getVanishedPlayers() {
return getVanishedPlayersOnFile();
}
@Override
public Collection<UUID> getOnlineVanishedPlayers() {
final Set<UUID> onlineVanishedPlayers = new HashSet<>();
getVanishedPlayers().stream().filter(vanishedUUID -> Bukkit.getPlayer(vanishedUUID) != null)
.forEach(onlineVanishedPlayers::add);
return onlineVanishedPlayers;
}
public UUID getVanishedUUIDFromNameOnFile(String name) {
return getVanishedPlayersOnFile().stream()
.filter(uuid -> StringUtils.equalsIgnoreCase(
plugin.getPlayerData().getString("PlayerData." + uuid + ".information.name"), name))
.findFirst().orElse(null);
}
private Set<UUID> getVanishedPlayersOnFile() {
final List<String> vanishedPlayerUUIDStrings = plugin.getPlayerData().getStringList("InvisiblePlayers");
final Set<UUID> vanishedPlayerUUIDs = new HashSet<>();
new ArrayList<>(vanishedPlayerUUIDStrings).forEach(uuidString -> {
try {
vanishedPlayerUUIDs.add(UUID.fromString(uuidString));
} catch (IllegalArgumentException e) {
vanishedPlayerUUIDStrings.remove(uuidString);
plugin.log(Level.WARNING, "The data.yml file contains an invalid player uuid," + " deleting it.");
plugin.getPlayerData().set("InvisiblePlayers", vanishedPlayerUUIDStrings);
plugin.getConfigMgr().getPlayerDataFile().save();
}
});
return vanishedPlayerUUIDs;
}
private void setVanishedPlayersOnFile(Set<UUID> vanishedPlayers) {
final List<String> vanishedPlayerUUIDStrings = new ArrayList<>();
vanishedPlayers.forEach(uuid -> vanishedPlayerUUIDStrings.add(uuid.toString()));
plugin.getPlayerData().set("InvisiblePlayers", vanishedPlayerUUIDStrings);
plugin.getConfigMgr().getPlayerDataFile().save();
}
}
@@ -0,0 +1,186 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.visibility;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import de.myzelyam.api.vanish.PlayerVanishStateChangeEvent;
import de.myzelyam.supervanish.SuperVanish;
import io.lettuce.core.RedisClient;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;
public class KeyDBVanishStateMgr extends VanishStateMgr {
private static final String INVISIBLE_PLAYERS_KEY = "vanish:invisible_players";
private static final String PLAYER_NAMES_KEY = "vanish:player_names";
private static final String ITEM_PICKUPS_KEY = "vanish:item_pickups";
private static final String DISMISSED_KEY = "vanish:dismissed";
private final SuperVanish plugin;
private final RedisClient redisClient;
private final StatefulRedisConnection<String, String> connection;
private final RedisCommands<String, String> commands;
public KeyDBVanishStateMgr(SuperVanish plugin, String uri) {
super(plugin);
this.plugin = plugin;
this.redisClient = RedisClient.create(uri);
this.connection = redisClient.connect();
this.commands = connection.sync();
}
@Override
public boolean isVanished(final UUID uuid) {
return commands.sismember(INVISIBLE_PLAYERS_KEY, uuid.toString());
}
@Override
public void setVanishedState(final UUID uuid, String name, boolean hide, String causeName) {
final PlayerVanishStateChangeEvent event = new PlayerVanishStateChangeEvent(uuid, name, hide, causeName);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
if (hide) {
commands.sadd(INVISIBLE_PLAYERS_KEY, uuid.toString());
commands.hset(PLAYER_NAMES_KEY, uuid.toString(), name);
} else {
commands.srem(INVISIBLE_PLAYERS_KEY, uuid.toString());
commands.hdel(PLAYER_NAMES_KEY, uuid.toString());
}
}
@Override
public Set<UUID> getVanishedPlayers() {
Set<String> uuidStrings = commands.smembers(INVISIBLE_PLAYERS_KEY);
Set<UUID> vanishedPlayers = new HashSet<>();
for (String uuidString : uuidStrings) {
try {
vanishedPlayers.add(UUID.fromString(uuidString));
} catch (IllegalArgumentException e) {
commands.srem(INVISIBLE_PLAYERS_KEY, uuidString);
plugin.log(Level.WARNING, "KeyDB contained an invalid player uuid, deleting it.");
}
}
return vanishedPlayers;
}
@Override
public Collection<UUID> getOnlineVanishedPlayers() {
Set<UUID> onlineVanishedPlayers = new HashSet<>();
getVanishedPlayers().stream().filter(uuid -> Bukkit.getPlayer(uuid) != null)
.forEach(onlineVanishedPlayers::add);
return onlineVanishedPlayers;
}
@Override
public UUID getVanishedUUIDFromName(String name) {
Map<String, String> allNames = commands.hgetall(PLAYER_NAMES_KEY);
for (Map.Entry<String, String> entry : allNames.entrySet()) {
if (entry.getValue().equalsIgnoreCase(name)) {
try {
return UUID.fromString(entry.getKey());
} catch (IllegalArgumentException e) {
return null;
}
}
}
return null;
}
@Override
public boolean getItemPickUps(UUID uuid, boolean defaultValue) {
String value = commands.hget(ITEM_PICKUPS_KEY, uuid.toString());
if (value == null) {
return defaultValue;
}
return Boolean.parseBoolean(value);
}
@Override
public void setItemPickUps(UUID uuid, boolean value) {
commands.hset(ITEM_PICKUPS_KEY, uuid.toString(), String.valueOf(value));
}
@Override
public boolean isDismissed(String id, String version) {
String value = commands.hget(DISMISSED_KEY, id + ":" + version);
return Boolean.parseBoolean(value);
}
@Override
public void setDismissed(String id, String version, boolean value) {
commands.hset(DISMISSED_KEY, id + ":" + version, String.valueOf(value));
}
@Override
public void close() {
connection.close();
redisClient.shutdown();
}
}
@@ -38,4 +38,18 @@ public abstract class VanishStateMgr {
public abstract Collection<UUID> getOnlineVanishedPlayers();
public abstract UUID getVanishedUUIDFromName(String name);
public abstract boolean getItemPickUps(UUID uuid, boolean defaultValue);
public abstract void setItemPickUps(UUID uuid, boolean value);
public abstract boolean isDismissed(String id, String version);
public abstract void setDismissed(String id, String version, boolean value);
public void close() {
}
}
@@ -14,7 +14,6 @@ import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.wrappers.PlayerInfoData;
import com.google.common.collect.ImmutableList;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.visibility.hiders.PlayerHider;
import org.bukkit.entity.Player;
@@ -58,10 +57,22 @@ public class PlayerInfoModule extends PacketAdapter {
event.setPacket(event.getPacket().shallowClone());
try {
List<PlayerInfoData> infoDataList = new ArrayList<>(event.getPacket().getPlayerInfoDataLists().read(0));
List<PlayerInfoData> rawList = event.getPacket().getPlayerInfoDataLists().read(0);
if (rawList == null)
return;
List<PlayerInfoData> infoDataList = new ArrayList<>(rawList);
Player receiver = event.getPlayer();
for (PlayerInfoData infoData : ImmutableList.copyOf(infoDataList)) {
if (receiver == null)
return;
for (PlayerInfoData infoData : new ArrayList<>(infoDataList)) {
if (infoData == null) {
infoDataList.remove(infoData);
continue;
}
UUID uuid = extractUUID(infoData);
if (uuid == null)
@@ -89,13 +100,14 @@ public class PlayerInfoModule extends PacketAdapter {
if (errorLogged)
return;
plugin.logException(e);
plugin.getLogger().warning("IMPORTANT: Please make sure that you are using the latest "
+ "dev-build of ProtocolLib and that your server is up-to-date! This error likely "
+ "happened inside of ProtocolLib code which is out of SuperVanish's control. It's part "
+ "of an optional invisibility module and can be removed safely by disabling "
+ "ModifyTablistPackets in the config. Please report this "
+ "error if you can reproduce it on an up-to-date server with only latest "
+ "ProtocolLib and latest SV installed.");
plugin.getLogger()
.warning("IMPORTANT: Please make sure that you are using the latest "
+ "dev-build of ProtocolLib and that your server is up-to-date! This error likely "
+ "happened inside of ProtocolLib code which is out of Vanish-OG's control. It's part "
+ "of an optional invisibility module and can be removed safely by disabling "
+ "ModifyTablistPackets in the config. Please report this "
+ "error if you can reproduce it on an up-to-date server with only latest "
+ "ProtocolLib and latest Vanish-OG installed.");
errorLogged = true;
}
@@ -122,13 +122,14 @@ public class TabCompleteModule extends PacketAdapter {
if (errorLogged)
return;
plugin.logException(e);
plugin.getLogger().warning("IMPORTANT: Please make sure that you are using the latest "
+ "dev-build of ProtocolLib and that your server is up-to-date! This error likely "
+ "happened inside of ProtocolLib code which is out of SuperVanish's control. It's part "
+ "of an optional invisibility module and can be removed safely by disabling "
+ "ModifyTabCompletePackets in the config. Please report this "
+ "error if you can reproduce it on an up-to-date server with only latest "
+ "ProtocolLib and latest SV installed.");
plugin.getLogger()
.warning("IMPORTANT: Please make sure that you are using the latest "
+ "dev-build of ProtocolLib and that your server is up-to-date! This error likely "
+ "happened inside of ProtocolLib code which is out of Vanish-OG's control. It's part "
+ "of an optional invisibility module and can be removed safely by disabling "
+ "ModifyTabCompletePackets in the config. Please report this "
+ "error if you can reproduce it on an up-to-date server with only latest "
+ "ProtocolLib and latest Vanish-OG installed.");
errorLogged = true;
}
+11 -4
View File
@@ -1,4 +1,4 @@
# SuperVanish v${project.version} - Configuration
# Vanish-OG v${project.version} - Configuration
############# Invisibility Features ##############
InvisibilityFeatures:
@@ -142,7 +142,7 @@ HookOptions:
############# Compatibility Options ##############
CompatibilityOptions:
# This section is for advanced users only!
# The event priority which SuperVanish should use for the specific event.
# The event priority which Vanish-OG should use for the specific event.
# Allowed values are LOWEST, LOW, NORMAL, HIGH, HIGHEST and MONITOR
# Higher priorities might override other plugins while lower ones might not
@@ -151,5 +151,12 @@ CompatibilityOptions:
# The quit listener still needs to run after some plugins that adjust vanish state on logout.
PlayerQuitEventPriority: HIGHEST
################# Do Not Touch ###################
ConfigVersion: ${project.version}
################## KeyDB Options ##################
KeyDB:
# Connection URI for KeyDB/Redis. If left empty, vanish state is stored in data.yml instead.
# Format: redis://[password@]host[:port][/database]
# Examples:
# redis://localhost:6379
# redis://password@keydb.example.com:6379/0
URI: ""
+7 -7
View File
@@ -1,11 +1,11 @@
# SuperVanish v${project.version} - Messages
# Vanish-OG v${project.version} - Messages
#
# Information:
# <..> means that .. is required; [..] means that .. is optional and can be left out; | inside [] or <> stands for 'OR'
# You can use the & character for color codes; Example: '&cThe color of this text would be red!'
# You can use #XXXXXX for HEX color codes. Example: '#663EF6This text would be purple!'
# Use MiniPlaceholder-style formatting. Legacy %placeholder% syntax is no longer supported.
# SuperVanish inline tags:
# Vanish-OG inline tags:
# <sv_player_name>, <sv_player_display_name>, <sv_player_tab_name>
# <sv_player_prefix>, <sv_player_suffix>, <sv_player_group>, <sv_player_nick>
# <sv_other_name>, <time>, <files>, <changes>, <death_message>
@@ -13,7 +13,7 @@
# Some messages allow different, unique variables too
#
# NOTE: Utilities-OG expands MiniPlaceholders in these messages, so you can also use
# its own global, audience, relational, and SuperVanish placeholders here.
# its own global, audience, relational, and Vanish-OG placeholders here.
#
# Empty messages will not be sent
# Using \n starts a new line
@@ -40,7 +40,7 @@ Messages:
CannotHideOtherPlayer: '&cYou''re not allowed to change <sv_other_name>''s visibility!'
AlreadyInvisibleMessage: '&cPlayer &e<sv_other_name>&c is already invisible!'
AlreadyVisibleMessage: '&cPlayer &e<sv_other_name>&c is already visible!'
PluginReloaded: '&aSuccessfully reloaded SuperVanish (<time>ms)!'
PluginReloaded: '&aSuccessfully reloaded Vanish-OG (<time>ms)!'
InvalidSender: '&cYou must be a player to execute this command!'
PlayerNotOnline: '&cThat player is not online!'
PlayerNonExistent: '&cThat player doesn''t exist!'
@@ -48,8 +48,8 @@ Messages:
ToggledPickingUpItemsOff: '&ePicking up items is now turned &cOFF&e.'
UpdateWarning: '&cWarning! Recreating <files> resets <changes>. Please use &e/sv recreatefiles confirm&c if you''d like to continue.'
RecreatedConfig: '&aSuccessfully recreated <files>! Please check <changes>.'
NoConfigUpdateAvailable: '&eNo SuperVanish files need to be recreated.'
RecreationRequiredMsg: '&c[SV] Some SuperVanish files need to be recreated. Use &e/sv recreatefiles&c to recreate them, or use /sv recreatefiles dismiss&c to dismiss this message.'
NoConfigUpdateAvailable: '&eNo Vanish-OG files need to be recreated.'
RecreationRequiredMsg: '&c[SV] Some Vanish-OG files need to be recreated. Use &e/sv recreatefiles&c to recreate them, or use /sv recreatefiles dismiss&c to dismiss this message.'
DismissedRecreationWarning: '&eYou are no longer receiving notifications about this recreation.'
UndismissedRecreationWarning: '&eYou are now receiving notifications about this recreation.'
PrintedStacktrace: '&eSuccessfully created a stacktrace, see console!'
@@ -58,7 +58,7 @@ Messages:
BlockBreakDenied: '&c[SV] You can''t break blocks in vanish!'
DynmapFakeJoin: '<sv_player_display_name> joined'
DynmapFakeQuit: '<sv_player_display_name> quit'
HelpHeader: "&a<---------------&e SuperVanish-Help &a--------------->"
HelpHeader: "&a<---------------&e Vanish-OG Help &a--------------->"
HelpFormat: "&6<usage> &7- &b<description> &c(<permission>)"
PlaceholderIsVanishedYes: "Yes"
PlaceholderIsVanishedNo: "No"
+4 -4
View File
@@ -1,4 +1,4 @@
name: SuperVanish-OG
name: Vanish-OG
main: de.myzelyam.supervanish.SuperVanish
authors: [MyzelYam, NotAlexNoyle]
description: Advanced /vanish plugin which makes other players think that you're not on the server
@@ -20,7 +20,7 @@ softdepend:
commands:
sv:
usage: /sv
description: SuperVanish's main command
description: Vanish-OG's main command
aliases: [supervanish, v, vanish]
permissions:
sv.*:
@@ -42,11 +42,11 @@ permissions:
sv.damage: true
sv.stacktrace: true
sv.silentchest: true
description: Grants you all SuperVanish permissions
description: Grants you all Vanish-OG permissions
supervanish.*:
children:
sv.*: true
description: Grants you all SuperVanish permissions
description: Grants you all Vanish-OG permissions
sv.see:
description: You can see other vanished players
sv.notoggle: