9
0
mirror of https://github.com/WiIIiam278/HuskSync.git synced 2025-12-19 14:59:21 +00:00

feat: improve data syncing with checkin petitions

This improves data fetching speed in cases where a user logs out during sync application; when they log back in, the server will petition the server they are checked out on to check them out.

We also now unlock users after saving sync on a server to accommodate this, and track user disconnection status to avoid inconsistencies with what platforms return for `isOnline`
This commit is contained in:
William278
2025-03-23 16:15:00 +00:00
parent ef7b3c4f32
commit 937ea9bc8e
17 changed files with 223 additions and 85 deletions

View File

@@ -54,7 +54,6 @@ import net.william278.husksync.database.PostgresDatabase;
import net.william278.husksync.event.FabricEventDispatcher;
import net.william278.husksync.event.ModLoadedCallback;
import net.william278.husksync.hook.PlanHook;
import net.william278.husksync.listener.EventListener;
import net.william278.husksync.listener.FabricEventListener;
import net.william278.husksync.listener.LockedHandler;
import net.william278.husksync.migrator.Migrator;
@@ -109,6 +108,7 @@ public class FabricHuskSync implements DedicatedServerModInitializer, HuskSync,
private final Map<String, Boolean> permissions = Maps.newHashMap();
private final List<Migrator> availableMigrators = Lists.newArrayList();
private final Set<UUID> lockedPlayers = Sets.newConcurrentHashSet();
private final Set<UUID> disconnectingPlayers = Sets.newConcurrentHashSet();
private final Map<UUID, FabricUser> playerMap = Maps.newConcurrentMap();
private Logger logger;

View File

@@ -34,29 +34,31 @@ public interface FabricUserDataHolder extends UserDataHolder {
@Override
default Optional<? extends Data> getData(@NotNull Identifier id) {
if (!id.isCustom()) {
try {
return switch (id.getKeyValue()) {
case "inventory" -> getInventory();
case "ender_chest" -> getEnderChest();
case "potion_effects" -> getPotionEffects();
case "advancements" -> getAdvancements();
case "location" -> getLocation();
case "statistics" -> getStatistics();
case "health" -> getHealth();
case "hunger" -> getHunger();
case "attributes" -> getAttributes();
case "experience" -> getExperience();
case "game_mode" -> getGameMode();
case "flight_status" -> getFlightStatus();
case "persistent_data" -> getPersistentData();
default -> throw new IllegalStateException(String.format("Unexpected data type: %s", id));
};
} catch (Throwable e) {
getPlugin().debug("Failed to get data for key: " + id.getKeyValue(), e);
}
if (id.isCustom()) {
return Optional.ofNullable(getCustomDataStore().get(id));
}
try {
return switch (id.getKeyValue()) {
case "inventory" -> getInventory();
case "ender_chest" -> getEnderChest();
case "potion_effects" -> getPotionEffects();
case "advancements" -> getAdvancements();
case "location" -> getLocation();
case "statistics" -> getStatistics();
case "health" -> getHealth();
case "hunger" -> getHunger();
case "attributes" -> getAttributes();
case "experience" -> getExperience();
case "game_mode" -> getGameMode();
case "flight_status" -> getFlightStatus();
case "persistent_data" -> getPersistentData();
default -> throw new IllegalStateException(String.format("Unexpected data type: %s", id));
};
} catch (Throwable e) {
getPlugin().debug("Failed to get data for key: " + id.asMinimalString(), e);
return Optional.empty();
}
return Optional.ofNullable(getCustomDataStore().get(id));
}
@Override

View File

@@ -64,8 +64,9 @@ public class FabricUser extends OnlineUser implements FabricUserDataHolder {
}
@Override
public boolean isOffline() {
return player == null || player.isDisconnected();
public boolean hasDisconnected() {
return getPlugin().getDisconnectingPlayers().contains(getUuid())
|| player == null || player.isDisconnected();
}
@NotNull
@@ -79,7 +80,7 @@ public class FabricUser extends OnlineUser implements FabricUserDataHolder {
public void sendToast(@NotNull MineDown title, @NotNull MineDown description, @NotNull String iconMaterial,
@NotNull String backgroundType) {
plugin.log(Level.WARNING, "Toast notifications are deprecated. " +
"Please change your notification display slot to CHAT, ACTION_BAR or NONE.");
"Please change your notification display slot to CHAT, ACTION_BAR or NONE.");
this.sendActionBar(title);
}