Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,16 @@ public Try<Void> setUseImprovedRespawnLocationDetection(boolean useImprovedRespa
return this.configHandle.set(configNodes.useImprovedRespawnLocationDetection, useImprovedRespawnLocationDetection);
}

@ApiStatus.AvailableSince("5.2")
public boolean getValidateBedAnchorRespawnLocation() {
return this.configHandle.get(configNodes.validateBedAnchorRespawnLocation);
}

@ApiStatus.AvailableSince("5.2")
public Try<Void> setValidateBedAnchorRespawnLocation(boolean validateBedAnchorRespawnLocation) {
return this.configHandle.set(configNodes.validateBedAnchorRespawnLocation, validateBedAnchorRespawnLocation);
}

public boolean getResetLastLocationOnDeath() {
return this.configHandle.get(configNodes.resetLastLocationOnDeath);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,16 @@ public Object serialize(Shares sharables, Class<Shares> aClass) {
.name("use-improved-respawn-location-detection")
.build());

final ConfigNode<Boolean> validateBedAnchorRespawnLocation = node(ConfigNode.builder("sharables.validate-bed-anchor-respawn-location", Boolean.class)
.comment("")
.comment("When enabled, we will validate the bed/anchor respawn location on group/world change.")
.comment("The validation checks if the bed/anchor block still exists at the saved location and is usable.")
.comment("When the validation fails, the respawn location will be cleared and default world spawn will be used instead.")
.comment("Disable this if you don't want validation, or you want another plugin to handle respawn logic.")
.defaultValue(true)
.name("validate-bed-anchor-respawn-location")
.build());

final ConfigNode<Boolean> resetLastLocationOnDeath = node(ConfigNode.builder("sharables.reset-last-location-on-death", Boolean.class)
.comment("")
.comment("When set to true, the last location of the player will be reset when they die.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.mvplugins.multiverse.inventories.MultiverseInventories;
import org.mvplugins.multiverse.inventories.handleshare.SingleShareWriter;
import org.mvplugins.multiverse.inventories.share.Sharables;
import org.mvplugins.multiverse.inventories.util.RespawnLocation;

import static org.mvplugins.multiverse.inventories.util.MinecraftTools.findAnchorFromRespawnLocation;
import static org.mvplugins.multiverse.inventories.util.MinecraftTools.findBedFromRespawnLocation;
Expand Down Expand Up @@ -41,15 +42,26 @@ public void onEvent(PlayerSetSpawnEvent event) {
return;
}
Player player = event.getPlayer();
Location newSpawnLoc = event.getLocation();
if (newSpawnLoc == null) {
updatePlayerSpawn(player, null);
return;
}
if (event.getCause() == PlayerSetSpawnEvent.Cause.BED) {
updatePlayerSpawn(player, findBedFromRespawnLocation(event.getLocation()));
updatePlayerSpawn(player, new RespawnLocation(
findBedFromRespawnLocation(newSpawnLoc),
RespawnLocation.RespawnLocationType.BED
));
return;
}
if (event.getCause() == PlayerSetSpawnEvent.Cause.RESPAWN_ANCHOR) {
updatePlayerSpawn(player, findAnchorFromRespawnLocation(event.getLocation()));
updatePlayerSpawn(player, new RespawnLocation(
findAnchorFromRespawnLocation(newSpawnLoc),
RespawnLocation.RespawnLocationType.ANCHOR
));
return;
}
updatePlayerSpawn(player, event.getLocation());
updatePlayerSpawn(player, new RespawnLocation(newSpawnLoc, RespawnLocation.RespawnLocationType.UNKNOWN));
}
};
}
Expand All @@ -65,12 +77,19 @@ public void onEvent(PlayerSpawnChangeEvent event) {
return;
}
Player player = event.getPlayer();
Location newSpawnLoc = event.getNewSpawn();
if (event.getCause() == PlayerSpawnChangeEvent.Cause.BED) {
updatePlayerSpawn(player, findBedFromRespawnLocation(event.getNewSpawn()));
updatePlayerSpawn(player, new RespawnLocation(
findBedFromRespawnLocation(newSpawnLoc),
RespawnLocation.RespawnLocationType.BED
));
return;
}
if (event.getCause() == PlayerSpawnChangeEvent.Cause.RESPAWN_ANCHOR) {
updatePlayerSpawn(player, findAnchorFromRespawnLocation(event.getNewSpawn()));
updatePlayerSpawn(player, new RespawnLocation(
findAnchorFromRespawnLocation(newSpawnLoc),
RespawnLocation.RespawnLocationType.ANCHOR
));
return;
}
updatePlayerSpawn(player, event.getNewSpawn());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,15 @@
import org.bukkit.Location;
import org.mvplugins.multiverse.core.world.location.UnloadedWorldLocation;
import org.mvplugins.multiverse.inventories.util.LegacyParsers;
import org.mvplugins.multiverse.inventories.util.RespawnLocation;

import java.util.Map;

/**
* A simple {@link SharableSerializer} usable with {@link Location} which converts the {@link Location} to the string
* format that is used by default in Multiverse-Inventories.
* @deprecated Locations no longer need a special serializer because they are
* {@link org.bukkit.configuration.serialization.ConfigurationSerializable}. This remains to convert legacy data.
*/
@Deprecated
final class LocationSerializer implements SharableSerializer<Location> {
abstract class LocationSerializer implements SharableSerializer<Location> {

@Override
public Location deserialize(Object obj) {
Expand All @@ -30,7 +28,25 @@ public Location deserialize(Object obj) {
}

@Override
public Object serialize(Location location) {
return new UnloadedWorldLocation(location);
abstract public Location serialize(Location loc);

static final class UnloadedWorldLocationSerializer extends LocationSerializer {
@Override
public Location serialize(Location loc) {
if (loc != null && !(loc instanceof UnloadedWorldLocation)) {
return new UnloadedWorldLocation(loc);
}
return loc;
}
}

static final class RespawnLocationSerializer extends LocationSerializer {
@Override
public Location serialize(Location loc) {
if (loc != null && !(loc instanceof RespawnLocation)) {
return new RespawnLocation(loc, RespawnLocation.RespawnLocationType.UNKNOWN);
}
return loc;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.mvplugins.multiverse.inventories.util.RespawnLocation;

import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -612,11 +613,19 @@ public boolean updatePlayer(Player player, ProfileData profile) {
setSpawnLocation(player, player.getWorld().getSpawnLocation());
return false;
}
if (inventoriesConfig.getValidateBedAnchorRespawnLocation()
&& loc instanceof RespawnLocation respawnLocation
&& !respawnLocation.isValidRespawnLocation()) {
Logging.finer("Respawn location validation failed for respawn type: " + respawnLocation.getRespawnType());
setSpawnLocation(player, player.getWorld().getSpawnLocation());
return false;
}
setSpawnLocation(player, loc);
Logging.finer("updated respawn location: " + player.getBedSpawnLocation());
return true;
}
}).serializer(new ProfileEntry(false, DataStrings.PLAYER_BED_SPAWN_LOCATION), new LocationSerializer())
}).serializer(new ProfileEntry(false, DataStrings.PLAYER_BED_SPAWN_LOCATION),
new LocationSerializer.RespawnLocationSerializer())
.altName("bedspawn").altName("bed").altName("beds").altName("bedspawns").build();

// todo: handle this somewhere better
Expand Down Expand Up @@ -655,7 +664,8 @@ public boolean updatePlayer(Player player, ProfileData profile) {
safetyTeleporter.to(loc).checkSafety(false).teleport(player);
return true;
}
}).serializer(new ProfileEntry(false, DataStrings.PLAYER_LAST_LOCATION), new LocationSerializer())
}).serializer(new ProfileEntry(false, DataStrings.PLAYER_LAST_LOCATION),
new LocationSerializer.UnloadedWorldLocationSerializer())
.altName("loc").altName("location").altName("pos").altName("position").optional().build();

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.bukkit.block.data.type.Bed;
import org.bukkit.block.data.type.RespawnAnchor;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Contract;

import javax.annotation.Nullable;

Expand Down Expand Up @@ -39,6 +40,7 @@ public static ItemStack[] fillWithAir(ItemStack[] items) {
return items;
}

@Contract("null -> null; !null -> !null")
public static @Nullable Location findBedFromRespawnLocation(@Nullable Location respawnLocation) {
if (respawnLocation == null) {
return null;
Expand All @@ -60,6 +62,7 @@ public static ItemStack[] fillWithAir(ItemStack[] items) {
return respawnLocation;
}

@Contract("null -> null; !null -> !null")
public static @Nullable Location findAnchorFromRespawnLocation(@Nullable Location respawnLocation) {
if (respawnLocation == null) {
return null;
Expand Down
Loading