Added config option for syncing dead player inventories, cancel damage if locked

feat/data-edit-commands
William 2 years ago
parent 1ed2414241
commit d1c95030f0

@ -14,6 +14,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
@ -121,6 +122,13 @@ public class BukkitEventListener extends EventListener implements Listener {
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onPlayerTakeDamage(@NotNull EntityDamageEvent event) {
if (event.getEntity() instanceof Player player) {
event.setCancelled(cancelPlayerEvent(BukkitPlayer.adapt(player)));
}
}
@EventHandler(ignoreCancelled = true)
public void onPlayerDeath(PlayerDeathEvent event) {
if (cancelPlayerEvent(BukkitPlayer.adapt(event.getEntity()))) {

@ -97,7 +97,7 @@ public class BukkitPlayer extends OnlineUser {
final double currentHealth = player.getHealth();
if (statusData.health != currentHealth) {
final double healthToSet = currentHealth > currentMaxHealth ? currentMaxHealth : statusData.health;
if (healthToSet <= 0) {
if (healthToSet < 1) {
Bukkit.getScheduler().runTask(BukkitHuskSync.getInstance(), () -> player.setHealth(healthToSet));
} else {
player.setHealth(healthToSet);
@ -572,6 +572,11 @@ public class BukkitPlayer extends OnlineUser {
});
}
@Override
public boolean isDead() {
return player.getHealth() < 1;
}
@Override
public void sendActionBar(@NotNull MineDown mineDown) {
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, mineDown.replace().toComponent());

@ -72,7 +72,7 @@ public abstract class BaseHuskSyncAPI {
public final CompletableFuture<Optional<UserData>> getUserData(@NotNull User user) {
return CompletableFuture.supplyAsync(() -> {
if (user instanceof OnlineUser) {
return ((OnlineUser) user).getUserData(plugin.getLoggingAdapter()).join();
return ((OnlineUser) user).getUserData(plugin.getLoggingAdapter(), plugin.getSettings()).join();
} else {
return plugin.getDatabase().getCurrentUserData(user).join().map(UserDataSnapshot::userData);
}
@ -103,7 +103,8 @@ public abstract class BaseHuskSyncAPI {
* @since 2.0
*/
public final CompletableFuture<Void> saveUserData(@NotNull OnlineUser user) {
return CompletableFuture.runAsync(() -> user.getUserData(plugin.getLoggingAdapter()).thenAccept(optionalUserData -> optionalUserData.ifPresent(
return CompletableFuture.runAsync(() -> user.getUserData(plugin.getLoggingAdapter(), plugin.getSettings())
.thenAccept(optionalUserData -> optionalUserData.ifPresent(
userData -> plugin.getDatabase().setUserData(user, userData, DataSaveCause.API).join())));
}

@ -144,6 +144,7 @@ public class Settings {
SYNCHRONIZATION_SAVE_ON_WORLD_SAVE("synchronization.save_on_world_save", OptionType.BOOLEAN, true),
SYNCHRONIZATION_COMPRESS_DATA("synchronization.compress_data", OptionType.BOOLEAN, true),
SYNCHRONIZATION_NETWORK_LATENCY_MILLISECONDS("synchronization.network_latency_milliseconds", OptionType.INTEGER, 500),
SYNCHRONIZATION_SAVE_DEAD_PLAYER_INVENTORIES("synchronization.save_dead_player_inventories", OptionType.BOOLEAN, true),
SYNCHRONIZATION_SYNC_INVENTORIES("synchronization.features.inventories", OptionType.BOOLEAN, true),
SYNCHRONIZATION_SYNC_ENDER_CHESTS("synchronization.features.ender_chests", OptionType.BOOLEAN, true),
SYNCHRONIZATION_SYNC_HEALTH("synchronization.features.health", OptionType.BOOLEAN, true),

@ -152,9 +152,10 @@ public abstract class EventListener {
// Handle asynchronous disconnection
lockedPlayers.add(user.uuid);
CompletableFuture.runAsync(() -> plugin.getRedisManager().setUserServerSwitch(user)
.thenRun(() -> user.getUserData(plugin.getLoggingAdapter()).thenAccept(optionalUserData ->
optionalUserData.ifPresent(userData -> plugin.getRedisManager().setUserData(user, userData)
.thenRun(() -> plugin.getDatabase().setUserData(user, userData, DataSaveCause.DISCONNECT)))))
.thenRun(() -> user.getUserData(plugin.getLoggingAdapter(), plugin.getSettings()).thenAccept(
optionalUserData -> optionalUserData.ifPresent(userData -> plugin.getRedisManager()
.setUserData(user, userData).thenRun(() -> plugin.getDatabase()
.setUserData(user, userData, DataSaveCause.DISCONNECT)))))
.thenRun(() -> lockedPlayers.remove(user.uuid)).exceptionally(throwable -> {
plugin.getLoggingAdapter().log(Level.SEVERE,
"An exception occurred handling a player disconnection");
@ -172,7 +173,7 @@ public abstract class EventListener {
if (disabling || !plugin.getSettings().getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_SAVE_ON_WORLD_SAVE)) {
return;
}
usersInWorld.forEach(user -> user.getUserData(plugin.getLoggingAdapter()).join().ifPresent(
usersInWorld.forEach(user -> user.getUserData(plugin.getLoggingAdapter(), plugin.getSettings()).join().ifPresent(
userData -> plugin.getDatabase().setUserData(user, userData, DataSaveCause.WORLD_SAVE).join()));
}
@ -217,7 +218,7 @@ public abstract class EventListener {
disabling = true;
plugin.getOnlineUsers().stream().filter(user -> !lockedPlayers.contains(user.uuid)).forEach(
user -> user.getUserData(plugin.getLoggingAdapter()).join().ifPresent(
user -> user.getUserData(plugin.getLoggingAdapter(), plugin.getSettings()).join().ifPresent(
userData -> plugin.getDatabase().setUserData(user, userData, DataSaveCause.SERVER_SHUTDOWN).join()));
plugin.getDatabase().close();

@ -260,16 +260,28 @@ public abstract class OnlineUser extends User {
*/
public abstract void showMenu(@NotNull ItemEditorMenu menu);
/**
* Returns true if the player is dead
*
* @return true if the player is dead
*/
public abstract boolean isDead();
/**
* Get the player's current {@link UserData} in an {@link Optional}
* </p>
* <p>
* If the {@code SYNCHRONIZATION_SAVE_DEAD_PLAYER_INVENTORIES} ConfigOption has been set,
* the user's inventory will only be returned if they are alive
* <p>
* If the user data could not be returned due to an exception, the optional will return empty
*
* @param logger The logger to use for handling exceptions
* @return the player's current {@link UserData} in an optional; empty if an exception occurs
*/
public final CompletableFuture<Optional<UserData>> getUserData(@NotNull Logger logger) {
return CompletableFuture.supplyAsync(() -> Optional.of(new UserData(getStatus().join(), getInventory().join(),
public final CompletableFuture<Optional<UserData>> getUserData(@NotNull Logger logger, @NotNull Settings settings) {
return CompletableFuture.supplyAsync(() -> Optional.of(new UserData(getStatus().join(),
(settings.getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_SAVE_DEAD_PLAYER_INVENTORIES)
? getInventory().join() : (isDead() ? new ItemData("") : getInventory().join())),
getEnderChest().join(), getPotionEffects().join(), getAdvancements().join(),
getStatistics().join(), getLocation().join(), getPersistentDataContainer().join(),
getMinecraftVersion().toString())))

@ -38,6 +38,7 @@ synchronization:
max_user_data_snapshots: 5
save_on_world_save: true
compress_data: true
save_dead_player_inventories: true
network_latency_milliseconds: 500
features:
inventories: true

Loading…
Cancel
Save