fix: more gracefully handle platform mismatches

feat/data-edit-commands
William 11 months ago
parent 07d0376dd6
commit 4dfbc0e32b
No known key found for this signature in database

@ -111,14 +111,14 @@ public class DataSnapshot {
@Nullable OffsetDateTime timestamp) throws IllegalStateException { @Nullable OffsetDateTime timestamp) throws IllegalStateException {
final DataSnapshot.Packed snapshot = plugin.getDataAdapter().fromBytes(data, DataSnapshot.Packed.class); final DataSnapshot.Packed snapshot = plugin.getDataAdapter().fromBytes(data, DataSnapshot.Packed.class);
if (snapshot.getMinecraftVersion().compareTo(plugin.getMinecraftVersion()) > 0) { if (snapshot.getMinecraftVersion().compareTo(plugin.getMinecraftVersion()) > 0) {
throw new IllegalStateException(String.format("Cannot set data for user because the Minecraft version of " + throw new IllegalStateException(String.format("Cannot deserialize data because the Minecraft version of " +
"their user data (%s) is newer than the server's Minecraft version (%s)." + "the data snapshot (%s) is newer than the server's Minecraft version (%s)." +
"Please ensure each server is running the same version of Minecraft.", "Please ensure each server is running the same version of Minecraft.",
snapshot.getMinecraftVersion(), plugin.getMinecraftVersion())); snapshot.getMinecraftVersion(), plugin.getMinecraftVersion()));
} }
if (snapshot.getFormatVersion() > CURRENT_FORMAT_VERSION) { if (snapshot.getFormatVersion() > CURRENT_FORMAT_VERSION) {
throw new IllegalStateException(String.format("Cannot set data for user because the format version of " + throw new IllegalStateException(String.format("Cannot deserialize data because the format version of " +
"their user data (%s) is newer than the current format version (%s). " + "the data snapshot (%s) is newer than the current format version (%s). " +
"Please ensure each server is running the latest version of HuskSync.", "Please ensure each server is running the latest version of HuskSync.",
snapshot.getFormatVersion(), CURRENT_FORMAT_VERSION)); snapshot.getFormatVersion(), CURRENT_FORMAT_VERSION));
} }
@ -135,8 +135,8 @@ public class DataSnapshot {
)); ));
} }
if (!snapshot.getPlatformType().equalsIgnoreCase(plugin.getPlatformType())) { if (!snapshot.getPlatformType().equalsIgnoreCase(plugin.getPlatformType())) {
throw new IllegalStateException(String.format("Cannot set data for user because the platform type of " + throw new IllegalStateException(String.format("Cannot deserialize data because the platform type of " +
"their user data (%s) is different to the server platform type (%s). " + "the data snapshot (%s) is different to the server platform type (%s). " +
"Please ensure each server is running the same platform type.", "Please ensure each server is running the same platform type.",
snapshot.getPlatformType(), plugin.getPlatformType())); snapshot.getPlatformType(), plugin.getPlatformType()));
} }

@ -158,10 +158,15 @@ public class RedisManager extends JedisPubSub {
final RedisMessage redisMessage = RedisMessage.fromJson(plugin, message); final RedisMessage redisMessage = RedisMessage.fromJson(plugin, message);
switch (messageType) { switch (messageType) {
case UPDATE_USER_DATA -> plugin.getOnlineUser(redisMessage.getTargetUuid()).ifPresent( case UPDATE_USER_DATA -> plugin.getOnlineUser(redisMessage.getTargetUuid()).ifPresent(
user -> user.applySnapshot( user -> {
DataSnapshot.deserialize(plugin, redisMessage.getPayload()), try {
DataSnapshot.UpdateCause.UPDATED final DataSnapshot.Packed data = DataSnapshot.deserialize(plugin, redisMessage.getPayload());
) user.applySnapshot(data, DataSnapshot.UpdateCause.UPDATED);
} catch (Throwable e) {
plugin.log(Level.SEVERE, "An exception occurred updating user data from Redis", e);
user.completeSync(false, DataSnapshot.UpdateCause.UPDATED, plugin);
}
}
); );
case REQUEST_USER_DATA -> plugin.getOnlineUser(redisMessage.getTargetUuid()).ifPresent( case REQUEST_USER_DATA -> plugin.getOnlineUser(redisMessage.getTargetUuid()).ifPresent(
user -> RedisMessage.create( user -> RedisMessage.create(
@ -174,7 +179,13 @@ public class RedisManager extends JedisPubSub {
redisMessage.getTargetUuid() redisMessage.getTargetUuid()
); );
if (future != null) { if (future != null) {
future.complete(Optional.of(DataSnapshot.deserialize(plugin, redisMessage.getPayload()))); try {
final DataSnapshot.Packed data = DataSnapshot.deserialize(plugin, redisMessage.getPayload());
future.complete(Optional.of(data));
} catch (Throwable e) {
plugin.log(Level.SEVERE, "An exception occurred returning user data from Redis", e);
future.complete(Optional.empty());
}
pendingRequests.remove(redisMessage.getTargetUuid()); pendingRequests.remove(redisMessage.getTargetUuid());
} }
} }

@ -38,6 +38,7 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.logging.Level;
/** /**
* Handles the synchronization of data when a player changes servers or logs in * Handles the synchronization of data when a player changes servers or logs in
@ -156,10 +157,15 @@ public abstract class DataSyncer {
// Set a user's data from the database, or set them as a new user // Set a user's data from the database, or set them as a new user
@ApiStatus.Internal @ApiStatus.Internal
protected void setUserFromDatabase(@NotNull OnlineUser user) { protected void setUserFromDatabase(@NotNull OnlineUser user) {
getDatabase().getLatestSnapshot(user).ifPresentOrElse( try {
snapshot -> user.applySnapshot(snapshot, DataSnapshot.UpdateCause.SYNCHRONIZED), getDatabase().getLatestSnapshot(user).ifPresentOrElse(
() -> user.completeSync(true, DataSnapshot.UpdateCause.NEW_USER, plugin) snapshot -> user.applySnapshot(snapshot, DataSnapshot.UpdateCause.SYNCHRONIZED),
); () -> user.completeSync(true, DataSnapshot.UpdateCause.NEW_USER, plugin)
);
} catch (Throwable e) {
plugin.log(Level.WARNING, "Failed to set %s's data from the database".formatted(user.getUsername()), e);
user.completeSync(false, DataSnapshot.UpdateCause.SYNCHRONIZED, plugin);
}
} }
// Continuously listen for data from Redis // Continuously listen for data from Redis

Loading…
Cancel
Save