mirror of
https://github.com/WiIIiam278/HuskSync.git
synced 2025-12-28 11:09:11 +00:00
Fix wrong timestamp/UUID being used for legacy conversion (#167)
* Maintain legacy snapshot IDs when updating * Also maintain timestamps during conversion * Actually implement timestamp fix in LegacyConverter
This commit is contained in:
@@ -96,9 +96,11 @@ public class DataSnapshot {
|
||||
return new Builder(plugin);
|
||||
}
|
||||
|
||||
// Deserialize a DataSnapshot downloaded from the database (with an ID & Timestamp from the database)
|
||||
@NotNull
|
||||
@ApiStatus.Internal
|
||||
public static DataSnapshot.Packed deserialize(@NotNull HuskSync plugin, byte[] data) throws IllegalStateException {
|
||||
public static DataSnapshot.Packed deserialize(@NotNull HuskSync plugin, byte[] data, @Nullable UUID id,
|
||||
@Nullable OffsetDateTime timestamp) throws IllegalStateException {
|
||||
final DataSnapshot.Packed snapshot = plugin.getDataAdapter().fromBytes(data, DataSnapshot.Packed.class);
|
||||
if (snapshot.getMinecraftVersion().compareTo(plugin.getMinecraftVersion()) > 0) {
|
||||
throw new IllegalStateException(String.format("Cannot set data for user because the Minecraft version of " +
|
||||
@@ -114,7 +116,11 @@ public class DataSnapshot {
|
||||
}
|
||||
if (snapshot.getFormatVersion() < CURRENT_FORMAT_VERSION) {
|
||||
if (plugin.getLegacyConverter().isPresent()) {
|
||||
return plugin.getLegacyConverter().get().convert(data);
|
||||
return plugin.getLegacyConverter().get().convert(
|
||||
data,
|
||||
Objects.requireNonNull(id, "Attempted legacy conversion with null UUID!"),
|
||||
Objects.requireNonNull(timestamp, "Attempted legacy conversion with null timestamp!")
|
||||
);
|
||||
}
|
||||
throw new IllegalStateException(String.format(
|
||||
"No legacy converter to convert format version: %s", snapshot.getFormatVersion()
|
||||
@@ -129,6 +135,13 @@ public class DataSnapshot {
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
// Deserialize a DataSnapshot from a network message payload (without an ID)
|
||||
@NotNull
|
||||
@ApiStatus.Internal
|
||||
public static DataSnapshot.Packed deserialize(@NotNull HuskSync plugin, byte[] data) throws IllegalStateException {
|
||||
return deserialize(plugin, data, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ID of the snapshot
|
||||
*
|
||||
@@ -393,6 +406,7 @@ public class DataSnapshot {
|
||||
public static class Builder {
|
||||
|
||||
private final HuskSync plugin;
|
||||
private UUID id;
|
||||
private SaveCause saveCause;
|
||||
private boolean pinned;
|
||||
private OffsetDateTime timestamp;
|
||||
@@ -403,6 +417,19 @@ public class DataSnapshot {
|
||||
this.pinned = false;
|
||||
this.data = new HashMap<>();
|
||||
this.timestamp = OffsetDateTime.now();
|
||||
this.id = UUID.randomUUID();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link UUID unique ID} of the snapshot
|
||||
*
|
||||
* @param id The {@link UUID} of the snapshot
|
||||
* @return The builder
|
||||
*/
|
||||
@NotNull
|
||||
public Builder id(@NotNull UUID id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -661,7 +688,7 @@ public class DataSnapshot {
|
||||
throw new IllegalStateException("Cannot build DataSnapshot without a save cause");
|
||||
}
|
||||
return new Unpacked(
|
||||
UUID.randomUUID(),
|
||||
id,
|
||||
pinned || plugin.getSettings().doAutoPin(saveCause),
|
||||
timestamp,
|
||||
saveCause,
|
||||
|
||||
@@ -217,7 +217,7 @@ public class MySqlDatabase extends Database {
|
||||
public Optional<DataSnapshot.Packed> getLatestSnapshot(@NotNull User user) {
|
||||
try (Connection connection = getConnection()) {
|
||||
try (PreparedStatement statement = connection.prepareStatement(formatStatementTables("""
|
||||
SELECT `version_uuid`, `timestamp`, `save_cause`, `pinned`, `data`
|
||||
SELECT `version_uuid`, `timestamp`, `data`
|
||||
FROM `%user_data_table%`
|
||||
WHERE `player_uuid`=?
|
||||
ORDER BY `timestamp` DESC
|
||||
@@ -225,10 +225,14 @@ public class MySqlDatabase extends Database {
|
||||
statement.setString(1, user.getUuid().toString());
|
||||
final ResultSet resultSet = statement.executeQuery();
|
||||
if (resultSet.next()) {
|
||||
final UUID versionUuid = UUID.fromString(resultSet.getString("version_uuid"));
|
||||
final OffsetDateTime timestamp = OffsetDateTime.ofInstant(
|
||||
resultSet.getTimestamp("timestamp").toInstant(), TimeZone.getDefault().toZoneId()
|
||||
);
|
||||
final Blob blob = resultSet.getBlob("data");
|
||||
final byte[] dataByteArray = blob.getBytes(1, (int) blob.length());
|
||||
blob.free();
|
||||
return Optional.of(DataSnapshot.deserialize(plugin, dataByteArray));
|
||||
return Optional.of(DataSnapshot.deserialize(plugin, dataByteArray, versionUuid, timestamp));
|
||||
}
|
||||
}
|
||||
} catch (SQLException | DataAdapter.AdaptionException e) {
|
||||
@@ -244,17 +248,21 @@ public class MySqlDatabase extends Database {
|
||||
final List<DataSnapshot.Packed> retrievedData = new ArrayList<>();
|
||||
try (Connection connection = getConnection()) {
|
||||
try (PreparedStatement statement = connection.prepareStatement(formatStatementTables("""
|
||||
SELECT `version_uuid`, `timestamp`, `save_cause`, `pinned`, `data`
|
||||
SELECT `version_uuid`, `timestamp`, `data`
|
||||
FROM `%user_data_table%`
|
||||
WHERE `player_uuid`=?
|
||||
ORDER BY `timestamp` DESC;"""))) {
|
||||
statement.setString(1, user.getUuid().toString());
|
||||
final ResultSet resultSet = statement.executeQuery();
|
||||
while (resultSet.next()) {
|
||||
final UUID versionUuid = UUID.fromString(resultSet.getString("version_uuid"));
|
||||
final OffsetDateTime timestamp = OffsetDateTime.ofInstant(
|
||||
resultSet.getTimestamp("timestamp").toInstant(), TimeZone.getDefault().toZoneId()
|
||||
);
|
||||
final Blob blob = resultSet.getBlob("data");
|
||||
final byte[] dataByteArray = blob.getBytes(1, (int) blob.length());
|
||||
blob.free();
|
||||
retrievedData.add(DataSnapshot.deserialize(plugin, dataByteArray));
|
||||
retrievedData.add(DataSnapshot.deserialize(plugin, dataByteArray, versionUuid, timestamp));
|
||||
}
|
||||
return retrievedData;
|
||||
}
|
||||
@@ -269,7 +277,7 @@ public class MySqlDatabase extends Database {
|
||||
public Optional<DataSnapshot.Packed> getSnapshot(@NotNull User user, @NotNull UUID versionUuid) {
|
||||
try (Connection connection = getConnection()) {
|
||||
try (PreparedStatement statement = connection.prepareStatement(formatStatementTables("""
|
||||
SELECT `version_uuid`, `timestamp`, `save_cause`, `pinned`, `data`
|
||||
SELECT `version_uuid`, `timestamp`, `data`
|
||||
FROM `%user_data_table%`
|
||||
WHERE `player_uuid`=? AND `version_uuid`=?
|
||||
ORDER BY `timestamp` DESC
|
||||
@@ -279,9 +287,12 @@ public class MySqlDatabase extends Database {
|
||||
final ResultSet resultSet = statement.executeQuery();
|
||||
if (resultSet.next()) {
|
||||
final Blob blob = resultSet.getBlob("data");
|
||||
final OffsetDateTime timestamp = OffsetDateTime.ofInstant(
|
||||
resultSet.getTimestamp("timestamp").toInstant(), TimeZone.getDefault().toZoneId()
|
||||
);
|
||||
final byte[] dataByteArray = blob.getBytes(1, (int) blob.length());
|
||||
blob.free();
|
||||
return Optional.of(DataSnapshot.deserialize(plugin, dataByteArray));
|
||||
return Optional.of(DataSnapshot.deserialize(plugin, dataByteArray, versionUuid, timestamp));
|
||||
}
|
||||
}
|
||||
} catch (SQLException | DataAdapter.AdaptionException e) {
|
||||
|
||||
@@ -24,6 +24,9 @@ import net.william278.husksync.adapter.DataAdapter;
|
||||
import net.william278.husksync.data.DataSnapshot;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class LegacyConverter {
|
||||
|
||||
protected final HuskSync plugin;
|
||||
@@ -33,6 +36,7 @@ public abstract class LegacyConverter {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract DataSnapshot.Packed convert(@NotNull byte[] data) throws DataAdapter.AdaptionException;
|
||||
public abstract DataSnapshot.Packed convert(@NotNull byte[] data, @NotNull UUID id,
|
||||
@NotNull OffsetDateTime timestamp) throws DataAdapter.AdaptionException;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user