Skip to content

Commit

Permalink
fix: make World Gson-safe
Browse files Browse the repository at this point in the history
  • Loading branch information
WiIIiam278 committed Nov 5, 2024
1 parent 5ea12b9 commit 6f96c0a
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,11 @@ public static org.bukkit.World adapt(@NotNull World world) {

@NotNull
public static World adapt(@NotNull org.bukkit.World world) {
return World.from(world.getName(), world.getUID(), World.Environment.match(world.getEnvironment().name()));
return World.from(
world.getName(),
world.getUID(),
World.Environment.match(world.getEnvironment().name())
);
}

}
Expand Down
48 changes: 24 additions & 24 deletions bukkit/src/main/java/net/william278/huskhomes/user/BukkitUser.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@
public class BukkitUser extends OnlineUser {

private final NamespacedKey INVULNERABLE_KEY = new NamespacedKey((BukkitHuskHomes) plugin, "invulnerable");
private final Player player;
private final Player bukkitPlayer;

private BukkitUser(@NotNull Player player, @NotNull BukkitHuskHomes plugin) {
super(player.getUniqueId(), player.getName(), plugin);
this.player = player;
private BukkitUser(@NotNull Player bukkitPlayer, @NotNull BukkitHuskHomes plugin) {
super(bukkitPlayer.getUniqueId(), bukkitPlayer.getName(), plugin);
this.bukkitPlayer = bukkitPlayer;
}

@NotNull
Expand All @@ -60,35 +60,35 @@ public static BukkitUser adapt(@NotNull Player player, @NotNull BukkitHuskHomes

@NotNull
public Player getPlayer() {
return player;
return bukkitPlayer;
}

@Override
public Position getPosition() {
return BukkitHuskHomes.Adapter.adapt(player.getLocation(), plugin.getServerName());
return BukkitHuskHomes.Adapter.adapt(bukkitPlayer.getLocation(), plugin.getServerName());
}

@Override
public Optional<Position> getBedSpawnPosition() {
return Optional.ofNullable(player.getBedSpawnLocation())
return Optional.ofNullable(bukkitPlayer.getBedSpawnLocation())
.map(loc -> BukkitHuskHomes.Adapter.adapt(loc, plugin.getServerName()));
}

@Override
public double getHealth() {
return player.getHealth();
return bukkitPlayer.getHealth();
}

@Override
public boolean hasPermission(@NotNull String node) {
return player.hasPermission(node);
return bukkitPlayer.hasPermission(node);
}


@Override
@NotNull
public Map<String, Boolean> getPermissions() {
return player.getEffectivePermissions().stream()
return bukkitPlayer.getEffectivePermissions().stream()
.collect(Collectors.toMap(
PermissionAttachmentInfo::getPermission,
PermissionAttachmentInfo::getValue, (a, b) -> b
Expand All @@ -99,8 +99,8 @@ public Map<String, Boolean> getPermissions() {
public CompletableFuture<Void> dismount() {
final CompletableFuture<Void> future = new CompletableFuture<>();
plugin.runSync(() -> {
player.leaveVehicle();
player.eject();
bukkitPlayer.leaveVehicle();
bukkitPlayer.eject();
future.complete(null);
}, this);
return future;
Expand All @@ -119,29 +119,29 @@ public void teleportLocally(@NotNull Location target, boolean async) throws Tele

// Run on the appropriate thread scheduler for this platform
plugin.runSync(() -> {
player.leaveVehicle();
player.eject();
bukkitPlayer.leaveVehicle();
bukkitPlayer.eject();
if (async || ((BukkitHuskHomes) plugin).getScheduler().isUsingFolia()) {
PaperLib.teleportAsync(player, location, PlayerTeleportEvent.TeleportCause.PLUGIN);
PaperLib.teleportAsync(bukkitPlayer, location, PlayerTeleportEvent.TeleportCause.PLUGIN);
return;
}
player.teleport(location, PlayerTeleportEvent.TeleportCause.PLUGIN);
bukkitPlayer.teleport(location, PlayerTeleportEvent.TeleportCause.PLUGIN);
}, this);
}

@Override
public boolean isMoving() {
return player.getVelocity().length() >= 0.1;
return bukkitPlayer.getVelocity().length() >= 0.1;
}

@Override
public void sendPluginMessage(byte[] message) {
player.sendPluginMessage((BukkitHuskHomes) plugin, PluginMessageBroker.BUNGEE_CHANNEL_ID, message);
bukkitPlayer.sendPluginMessage((BukkitHuskHomes) plugin, PluginMessageBroker.BUNGEE_CHANNEL_ID, message);
}

@Override
public boolean isVanished() {
return player.getMetadata("vanished")
return bukkitPlayer.getMetadata("vanished")
.stream()
.map(MetadataValue::asBoolean)
.findFirst()
Expand All @@ -150,7 +150,7 @@ public boolean isVanished() {

@Override
public boolean hasInvulnerability() {
return player.getPersistentDataContainer().has(INVULNERABLE_KEY, PersistentDataType.INTEGER);
return bukkitPlayer.getPersistentDataContainer().has(INVULNERABLE_KEY, PersistentDataType.INTEGER);
}

@Override
Expand All @@ -159,17 +159,17 @@ public void handleInvulnerability() {
if (invulnerableTicks <= 0) {
return;
}
player.getPersistentDataContainer().set(INVULNERABLE_KEY, PersistentDataType.INTEGER, 1);
player.setInvulnerable(true);
bukkitPlayer.getPersistentDataContainer().set(INVULNERABLE_KEY, PersistentDataType.INTEGER, 1);
bukkitPlayer.setInvulnerable(true);
plugin.runSyncDelayed(this::removeInvulnerabilityIfPermitted, this, invulnerableTicks);
}

@Override
public void removeInvulnerabilityIfPermitted() {
if (this.hasInvulnerability()) {
player.setInvulnerable(false);
bukkitPlayer.setInvulnerable(false);
}
player.getPersistentDataContainer().remove(INVULNERABLE_KEY);
bukkitPlayer.getPersistentDataContainer().remove(INVULNERABLE_KEY);
}

}
1 change: 1 addition & 0 deletions common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ dependencies {
api 'commons-io:commons-io:2.17.0'
api 'org.apache.commons:commons-text:1.12.0'
api 'com.google.code.gson:gson:2.11.0'
api 'com.fatboyindustrial.gson-javatime-serialisers:gson-javatime-serialisers:1.1.2'
api 'com.github.Exlll.ConfigLib:configlib-yaml:v4.5.0'
api('com.zaxxer:HikariCP:6.0.0') {
exclude module: 'slf4j-api'
Expand Down
10 changes: 2 additions & 8 deletions common/src/main/java/net/william278/huskhomes/HuskHomes.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@

package net.william278.huskhomes;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import net.kyori.adventure.key.Key;
import net.william278.huskhomes.api.BaseHuskHomesAPI;
import net.william278.huskhomes.command.Command;
Expand Down Expand Up @@ -57,7 +55,8 @@
*/
public interface HuskHomes extends Task.Supplier, EventDispatcher, SavePositionProvider, TransactionResolver,
ConfigProvider, DatabaseProvider, BrokerProvider, MetaProvider, HookProvider, RandomTeleportProvider,
AudiencesProvider, UserProvider, TextValidator, ManagerProvider, ListenerProvider, CommandProvider {
AudiencesProvider, UserProvider, TextValidator, ManagerProvider, ListenerProvider, CommandProvider,
GsonProvider {

int BSTATS_BUKKIT_PLUGIN_ID = 8430;

Expand Down Expand Up @@ -252,9 +251,4 @@ default Key getKey(@NotNull String... data) {
return Key.key("huskhomes", joined);
}

@NotNull
default Gson getGson() {
return new GsonBuilder().create();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import net.william278.huskhomes.position.Position;
import net.william278.huskhomes.position.World;
Expand All @@ -35,7 +36,7 @@
/**
* Represents a payload sent in a cross-server {@link Message}.
*/
@NoArgsConstructor
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class Payload {

@Nullable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,20 @@ public class PluginMessageBroker extends Broker {
/**
* The name of BungeeCord's provided plugin channel.
*
* <p>Internally, this is <a href="https://wiki.vg/Plugin_channels#bungeecord:main">{@code bungeecord:main}</a>,
* but Spigot remaps {@code BungeeCord} automatically to the new one (hence BungeeCord is kept for back-compat).
* @implNote Technically, the effective identifier of this channel is {@code bungeecord:main}, but Spigot remaps
* {@code BungeeCord} automatically to the new one (<a href="https://wiki.vg/Plugin_channels#bungeecord:main">source</a>).
* Spigot's <a href="https://www.spigotmc.org/wiki/bukkit-bungee-plugin-messaging-channel/">official documentation</a>
* still instructs usage of {@code BungeeCord} as the name to use, however. It's all a bit inconsistent, so just in case
* it's best to leave it how it is for to maintain backwards compatibility.
*/
public static final String BUNGEE_CHANNEL_ID = "BungeeCord";

public PluginMessageBroker(@NotNull HuskHomes plugin) {
protected PluginMessageBroker(@NotNull HuskHomes plugin) {
super(plugin);
}

@Override
public void initialize() throws IllegalStateException {
public void initialize() throws RuntimeException {
plugin.setupPluginMessagingChannels();
}

Expand All @@ -70,16 +73,14 @@ public final void onReceive(@NotNull String channel, @NotNull OnlineUser user, b
inputStream.readFully(messageBody);

try (final DataInputStream messageReader = new DataInputStream(new ByteArrayInputStream(messageBody))) {
super.handle(user, plugin.getGson().fromJson(messageReader.readUTF(), Message.class));
super.handle(user, plugin.getMessageFromJson(messageReader.readUTF()));
} catch (IOException e) {
plugin.log(Level.SEVERE, "Failed to fully read plugin message", e);
}
}

@Override
protected void send(@NotNull Message message, @Nullable OnlineUser sender) {
Preconditions.checkNotNull(sender, "Sender cannot be null with a Plugin Message broker");

protected void send(@NotNull Message message, @NotNull OnlineUser sender) {
final ByteArrayDataOutput messageWriter = ByteStreams.newDataOutput();
messageWriter.writeUTF(message.getTargetType().getPluginMessageChannel());
messageWriter.writeUTF(message.getTarget());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ private void onThreadUnlock(@NotNull Throwable t) {
public void onMessage(@NotNull String channel, @NotNull String encoded) {
final Message message;
try {
message = broker.plugin.getGson().fromJson(encoded, Message.class);
message = broker.plugin.getMessageFromJson(encoded);
} catch (Exception e) {
broker.plugin.log(Level.WARNING, "Failed to decode message from Redis: " + e.getMessage());
return;
Expand Down
65 changes: 15 additions & 50 deletions common/src/main/java/net/william278/huskhomes/position/World.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,78 +19,41 @@

package net.william278.huskhomes.position;

import lombok.NoArgsConstructor;
import com.google.gson.annotations.Expose;
import lombok.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Locale;
import java.util.Optional;
import java.util.UUID;

/**
* Represents a world on a server.
*/
@Getter
@Setter
@AllArgsConstructor(staticName = "from")
@NoArgsConstructor
public class World {

@Expose
private String name;
@Expose
private UUID uuid;
@Expose
@Nullable
private Environment environment;

private World(@NotNull String name, @NotNull UUID uuid, @Nullable Environment environment) {
this.setName(name);
this.setUuid(uuid);
this.setEnvironment(environment);
}

@NotNull
public static World from(@NotNull String name, @NotNull UUID uuid, @NotNull Environment environment) {
return new World(name, uuid, environment);
}
@Getter(AccessLevel.NONE)
private Environment environment = null;

@NotNull
public static World from(@NotNull String name, @NotNull UUID uuid) {
return new World(name, uuid, null);
}

/**
* The name of this world, as defined by the world directory name.
*/
@NotNull
public String getName() {
return name;
}

public void setName(@NotNull String name) {
this.name = name;
}

/**
* UUID of this world, as defined by the {@code uid.dat} file in the world directory.
*/
@NotNull
public UUID getUuid() {
return uuid;
}

public void setUuid(@NotNull UUID uuid) {
this.uuid = uuid;
}

/**
* Environment of the world ({@link Environment#OVERWORLD}, {@link Environment#NETHER}, {@link Environment#THE_END},
* or {@link Environment#CUSTOM}).
*
* <p>Will return {@link Environment#OVERWORLD} if the environment is null
*/
@NotNull
@SuppressWarnings("unused")
public Environment getEnvironment() {
return Optional.ofNullable(environment).orElse(Environment.OVERWORLD);
}

public void setEnvironment(@Nullable Environment environment) {
this.environment = environment;
return environment == null ? Environment.OVERWORLD : environment;
}

/**
Expand All @@ -102,6 +65,7 @@ public enum Environment {
THE_END,
CUSTOM;

@NotNull
public static Environment match(@NotNull String name) {
return switch (name.toLowerCase(Locale.ENGLISH)) {
case "overworld" -> OVERWORLD;
Expand All @@ -115,8 +79,9 @@ public static Environment match(@NotNull String name) {
@Override
public boolean equals(@NotNull Object obj) {
if (obj instanceof World world) {
return world.getUuid().equals(getUuid());
return this.uuid.equals(world.uuid);
}
return super.equals(obj);
}

}
Loading

0 comments on commit 6f96c0a

Please sign in to comment.