Common:
- Fix rare NPE occurs when players disconnect while KB is being processed or a command is being run Fabric: - Check if native player object is null before constructing PlatformPlayer
This commit is contained in:
1 parent
622c23a729
commit
35faf08cfa
11 files changed
+58
-35
No files matched your search
@@ -78,7 +78,6 @@ public class BukkitPlayer implements PlatformPlayer {
|
||||
Preconditions.checkArgument(player != null);
|
||||
this.bukkitPlayer = player;
|
||||
this.user = PacketEvents.getAPI().getPlayerManager().getUser(bukkitPlayer);
|
||||
Preconditions.checkArgument(user != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -220,7 +219,7 @@ public class BukkitPlayer implements PlatformPlayer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUser() {
|
||||
public @Nullable User getUser() {
|
||||
return this.user;
|
||||
}
|
||||
|
||||
|
||||
+23
-18
@@ -1,11 +1,13 @@
|
||||
package me.caseload.knockbacksync.command.subcommand;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import me.caseload.knockbacksync.Base;
|
||||
import me.caseload.knockbacksync.ConfigWrapper;
|
||||
import me.caseload.knockbacksync.command.generic.BuilderCommand;
|
||||
import me.caseload.knockbacksync.command.generic.PlayerSelector;
|
||||
import me.caseload.knockbacksync.event.KBSyncEventHandler;
|
||||
import me.caseload.knockbacksync.event.events.ConfigReloadEvent;
|
||||
import me.caseload.knockbacksync.manager.ConfigManager;
|
||||
import me.caseload.knockbacksync.manager.PlayerDataManager;
|
||||
import me.caseload.knockbacksync.player.PlayerData;
|
||||
import me.caseload.knockbacksync.sender.Sender;
|
||||
@@ -18,6 +20,8 @@ import java.util.function.Predicate;
|
||||
|
||||
public class PingCommand implements BuilderCommand {
|
||||
|
||||
private static final ConfigManager configManager = Base.INSTANCE.getConfigManager();
|
||||
|
||||
private String pingSelfAvailableMessage;
|
||||
private String pingSelfUnavailableMessage;
|
||||
private String pingOtherAvailableMessage;
|
||||
@@ -51,17 +55,17 @@ public class PingCommand implements BuilderCommand {
|
||||
if (context.sender().isConsole()) {
|
||||
context.sender().sendMessage(ChatUtil.translateAlternateColorCodes('&', mustSpecifyPlayerFromConsoleMessage));
|
||||
} else {
|
||||
context.sender().sendMessage(getPingMessage(context.sender().getUniqueId(), null));
|
||||
context.sender().sendMessage(getPingMessage(context.sender().getUniqueId(), context.sender().getName(), null, null));
|
||||
}
|
||||
} else {
|
||||
context.sender().sendMessage(getPingMessage(context.sender().getUniqueId(), targetSelector.getSinglePlayer().getUUID()));
|
||||
context.sender().sendMessage(getPingMessage(context.sender().getUniqueId(), context.sender().getName(), targetSelector.getSinglePlayer().getUUID(), targetSelector.getSinglePlayer().getName()));
|
||||
}
|
||||
})
|
||||
);
|
||||
Base.INSTANCE.getEventBus().registerListeners(this);
|
||||
}
|
||||
private void loadConfig() {
|
||||
ConfigWrapper configWrapper = Base.INSTANCE.getConfigManager().getConfigWrapper();
|
||||
ConfigWrapper configWrapper = configManager.getConfigWrapper();
|
||||
pingSelfAvailableMessage = configWrapper.getString("messages.ping.self.available",
|
||||
"Your real ping is &b%ping%&rms. Jitter: &b%jitter%&rms. Spike: &b%spike%&r. Compensated ping: &b%compensated%&rms.");
|
||||
pingSelfUnavailableMessage = configWrapper.getString("messages.ping.self.unavailable",
|
||||
@@ -78,26 +82,27 @@ public class PingCommand implements BuilderCommand {
|
||||
"&cKnockback synchronization is currently disabled for the target player.");
|
||||
}
|
||||
|
||||
private String getPingMessage(UUID senderUUID, UUID targetUUID) {
|
||||
PlayerData playerData = null;
|
||||
private String getPingMessage(UUID senderUUID, String senderName, UUID targetUUID, String targetName) {
|
||||
boolean isSelf = senderUUID.equals(targetUUID) || targetUUID == null;
|
||||
|
||||
if (senderUUID == null) {
|
||||
senderUUID = targetUUID;
|
||||
}
|
||||
|
||||
String message;
|
||||
if (isSelf) {
|
||||
playerData = PlayerDataManager.getPlayerData(Base.INSTANCE.getPlatformServer().getPlayer(senderUUID).getUser());
|
||||
if (playerData == null) {
|
||||
return ChatUtil.translateAlternateColorCodes('&', knockbacksyncDisabledForYouMessage);
|
||||
}
|
||||
message = knockbacksyncDisabledForYouMessage;
|
||||
targetUUID = senderUUID;
|
||||
targetName = senderName;
|
||||
} else {
|
||||
playerData = PlayerDataManager.getPlayerData(Base.INSTANCE.getPlatformServer().getPlayer(targetUUID).getUser());
|
||||
if (playerData == null) {
|
||||
return ChatUtil.translateAlternateColorCodes('&', knockbacksyncDisabledForTargetMessage);
|
||||
}
|
||||
message = knockbacksyncDisabledForTargetMessage;
|
||||
}
|
||||
|
||||
User targetUser = Base.INSTANCE.getPlatformServer().getPlayer(targetUUID).getUser();
|
||||
if (targetUser == null)
|
||||
return ChatUtil.translateAlternateColorCodes('&',
|
||||
configManager.getPlayerDisconnectedWhileExecutingCommand()
|
||||
).replace("%player%", targetName);
|
||||
|
||||
PlayerData playerData = PlayerDataManager.getPlayerData(targetUser);
|
||||
if (playerData == null)
|
||||
return ChatUtil.translateAlternateColorCodes('&', message);
|
||||
|
||||
String rawReturnString;
|
||||
if (playerData.getPing() == null) {
|
||||
rawReturnString = isSelf ? pingSelfUnavailableMessage : pingOtherUnavailableMessage;
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import java.util.function.Predicate;
|
||||
|
||||
public class ReloadCommand implements BuilderCommand {
|
||||
|
||||
private final ConfigManager configManager = Base.INSTANCE.getConfigManager();
|
||||
private static final ConfigManager configManager = Base.INSTANCE.getConfigManager();
|
||||
private String rawReloadMessage = configManager.getConfigWrapper().getString("messages.reload.success", "&aSuccessfully reloaded KnockbackSync.");
|
||||
|
||||
public void register(CommandManager<Sender> manager) {
|
||||
|
||||
+7
-1
@@ -14,7 +14,6 @@ import me.caseload.knockbacksync.util.ChatUtil;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.permission.PredicatePermission;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class StatusCommand implements BuilderCommand {
|
||||
@@ -85,6 +84,13 @@ public class StatusCommand implements BuilderCommand {
|
||||
}
|
||||
|
||||
private void showPlayerStatus(Sender sender, PlatformPlayer target) {
|
||||
if (target.getUser() == null) {
|
||||
String message = ChatUtil.translateAlternateColorCodes('&',
|
||||
configManager.getPlayerDisconnectedWhileExecutingCommand()
|
||||
).replace("%player%", target.getName());
|
||||
sender.sendMessage(message);
|
||||
}
|
||||
|
||||
boolean globalStatus = configManager.isToggled();
|
||||
boolean playerStatus = PlayerDataManager.containsPlayerData(target.getUser());
|
||||
|
||||
|
||||
+12
-9
@@ -1,5 +1,4 @@
|
||||
package me.caseload.knockbacksync.command.subcommand;
|
||||
import com.github.retrooper.packetevents.protocol.player.Combat;
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import me.caseload.knockbacksync.Base;
|
||||
import me.caseload.knockbacksync.ConfigWrapper;
|
||||
@@ -11,13 +10,11 @@ import me.caseload.knockbacksync.manager.ConfigManager;
|
||||
import me.caseload.knockbacksync.manager.PlayerDataManager;
|
||||
import me.caseload.knockbacksync.permission.PermissionChecker;
|
||||
import me.caseload.knockbacksync.player.PlatformPlayer;
|
||||
import me.caseload.knockbacksync.player.PlayerData;
|
||||
import me.caseload.knockbacksync.sender.Sender;
|
||||
import me.caseload.knockbacksync.util.ChatUtil;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.permission.PredicatePermission;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class ToggleCommand implements BuilderCommand {
|
||||
@@ -70,7 +67,7 @@ public class ToggleCommand implements BuilderCommand {
|
||||
if (targetSelector == null) {
|
||||
// Global toggle
|
||||
if (permissionChecker.hasPermission(sender, TOGGLE_GLOBAL_PERMISSION, false)) {
|
||||
toggleGlobalKnockback(configManager, sender);
|
||||
toggleGlobalKnockback(sender);
|
||||
} else {
|
||||
sender.sendMessage(ChatUtil.translateAlternateColorCodes('&', noGlobalPermissionMessage));
|
||||
}
|
||||
@@ -88,7 +85,7 @@ public class ToggleCommand implements BuilderCommand {
|
||||
if (!configManager.isToggled()) {
|
||||
sender.sendMessage(ChatUtil.translateAlternateColorCodes('&', serverDisabledMessage));
|
||||
} else {
|
||||
togglePlayerKnockback(target, configManager, sender);
|
||||
togglePlayerKnockback(target, sender);
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -96,7 +93,7 @@ public class ToggleCommand implements BuilderCommand {
|
||||
}
|
||||
|
||||
|
||||
private static void toggleGlobalKnockback(ConfigManager configManager, Sender sender) {
|
||||
private static void toggleGlobalKnockback(Sender sender) {
|
||||
boolean toggledState = !configManager.isToggled();
|
||||
ToggleOnOffEvent toggleOnOffEvent = new ToggleOnOffEvent(toggledState);
|
||||
toggleOnOffEvent.post();
|
||||
@@ -106,8 +103,8 @@ public class ToggleCommand implements BuilderCommand {
|
||||
toggledState = toggleOnOffEvent.getStatus();
|
||||
configManager.setToggled(toggledState);
|
||||
|
||||
Base.INSTANCE.getConfigManager().getConfigWrapper().set("enabled", toggledState);
|
||||
Base.INSTANCE.getConfigManager().saveConfig();
|
||||
configManager.getConfigWrapper().set("enabled", toggledState);
|
||||
configManager.saveConfig();
|
||||
|
||||
String message = ChatUtil.translateAlternateColorCodes('&',
|
||||
toggledState ? configManager.getEnableMessage() : configManager.getDisableMessage()
|
||||
@@ -115,8 +112,14 @@ public class ToggleCommand implements BuilderCommand {
|
||||
sender.sendMessage(ChatUtil.translateAlternateColorCodes('&', message));
|
||||
}
|
||||
|
||||
private static void togglePlayerKnockback(PlatformPlayer target, ConfigManager configManager, Sender sender) {
|
||||
private static void togglePlayerKnockback(PlatformPlayer target, Sender sender) {
|
||||
User user = target.getUser();
|
||||
if (user == null) {
|
||||
String message = ChatUtil.translateAlternateColorCodes('&',
|
||||
configManager.getPlayerDisconnectedWhileExecutingCommand()
|
||||
).replace("%player%", target.getName());
|
||||
sender.sendMessage(message);
|
||||
}
|
||||
|
||||
if (PlayerDataManager.shouldExempt(target.getUUID())) {
|
||||
String message = ChatUtil.translateAlternateColorCodes('&',
|
||||
|
||||
@@ -12,7 +12,7 @@ public abstract class PlayerDamageListener {
|
||||
return;
|
||||
|
||||
User user = victim.getUser();
|
||||
if (user == null) return; // Prevent errors with fake players
|
||||
if (user == null) return; // Prevent errors with players disconnecting while this is running (or with fake player?)
|
||||
|
||||
PlayerData playerData = PlayerDataManager.getPlayerData(user);
|
||||
if (playerData == null)
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ public abstract class PlayerKnockbackListener {
|
||||
return;
|
||||
|
||||
User user = victim.getUser();
|
||||
if (user == null) return; // Prevent errors with fake players
|
||||
if (user == null) return; // Prevent errors with players disconnecting while this is running (or with fake player?)
|
||||
|
||||
PlayerData victimPlayerData = PlayerDataManager.getPlayerData(user);
|
||||
if (victimPlayerData == null)
|
||||
|
||||
@@ -36,6 +36,7 @@ public class ConfigManager {
|
||||
private String playerEnableMessage;
|
||||
private String playerDisableMessage;
|
||||
private String playerIneligibleMessage;
|
||||
private String playerDisconnectedWhileExecutingCommand;
|
||||
|
||||
private AbstractTaskHandle pingTask;
|
||||
|
||||
@@ -122,6 +123,7 @@ public class ConfigManager {
|
||||
playerEnableMessage = configWrapper.getString("messages.toggle.player.enable", "&aSuccessfully enabled KnockbackSync for %player%.");
|
||||
playerDisableMessage = configWrapper.getString("messages.toggle.player.disable", "&aSuccessfully &cdisabled &aKnockbackSync for %player%.");
|
||||
playerIneligibleMessage = configWrapper.getString("messages.toggle.player.ineligible", "&c%player% is ineligible for KnockbackSync. If you believe this is in error, please contact your server administrators.");
|
||||
playerDisconnectedWhileExecutingCommand = configWrapper.getString("messages.toggle.player.disconnected-while-executing-command", "&c%player% disconnected while executing command.");
|
||||
}
|
||||
|
||||
public void updateConfig() {
|
||||
|
||||
@@ -52,7 +52,12 @@ public interface PlatformPlayer {
|
||||
|
||||
BoundingBox getBoundingBox();
|
||||
|
||||
User getUser();
|
||||
/**
|
||||
* If a player disconnects while we are running the constructor of a PlatformPlayer
|
||||
* PacketEvents.getAPI().getPlayerManager().getUser(bukkitPlayer) may return null
|
||||
* This will make the internal field null and thus this function may return null.
|
||||
*/
|
||||
@Nullable User getUser();
|
||||
|
||||
void setClientBrand(String brand);
|
||||
|
||||
|
||||
@@ -194,6 +194,7 @@ messages:
|
||||
enable: "&aSuccessfully enabled KnockbackSync for %player%."
|
||||
disable: "&aSuccessfully &cdisabled &aKnockbackSync for %player%."
|
||||
ineligible: "&c%player% is ineligible for KnockbackSync. If you believe this is in error, please contact your server administrators."
|
||||
disconnected-while-executing-command: "&c%player% disconnected while executing command."
|
||||
permission:
|
||||
no_global: "&cYou don't have permission to toggle the global setting."
|
||||
no_self: "&cYou do not have permission to toggle your knockback."
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import com.github.retrooper.packetevents.protocol.world.BoundingBox;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.google.common.base.Preconditions;
|
||||
import me.caseload.knockbacksync.world.FabricWorld;
|
||||
import me.caseload.knockbacksync.world.PlatformWorld;
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
@@ -33,6 +34,7 @@ public class FabricPlayer implements PlatformPlayer {
|
||||
private String clientBrand = "vanilla";
|
||||
|
||||
public FabricPlayer(ServerPlayerEntity player) {
|
||||
Preconditions.checkArgument(player != null);
|
||||
this.fabricPlayer = player;
|
||||
this.user = PacketEvents.getAPI().getPlayerManager().getUser(fabricPlayer);
|
||||
}
|
||||
@@ -156,7 +158,7 @@ public class FabricPlayer implements PlatformPlayer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUser() {
|
||||
public @Nullable User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user