Fix login gamemode
This commit is contained in:
@@ -30,6 +30,10 @@ public final class DimensionGameModeManager {
|
||||
|
||||
private final Map<String, String> configured = new LinkedHashMap<>();
|
||||
private final Map<UUID, String> lastDimension = new ConcurrentHashMap<>();
|
||||
private final Map<UUID, Integer> joinEnforcementTicks = new ConcurrentHashMap<>();
|
||||
|
||||
private static final int JOIN_ENFORCEMENT_DURATION_TICKS = 100; // 5 detik
|
||||
private static final int JOIN_ENFORCEMENT_INTERVAL_TICKS = 5; // 0.25 detik
|
||||
|
||||
public boolean load() {
|
||||
if (!Files.exists(PATH)) {
|
||||
@@ -77,14 +81,37 @@ public final class DimensionGameModeManager {
|
||||
|
||||
public void tick(MinecraftServer server) {
|
||||
for (ServerPlayer player : server.getPlayerList().getPlayers()) {
|
||||
UUID uuid = player.getUUID();
|
||||
String dimension = player.level().dimension().identifier().toString();
|
||||
String previous = lastDimension.put(player.getUUID(), dimension);
|
||||
String previous = lastDimension.put(uuid, dimension);
|
||||
if (!dimension.equals(previous)) {
|
||||
applyConfiguredMode(player, dimension, true);
|
||||
}
|
||||
|
||||
Integer remaining = joinEnforcementTicks.get(uuid);
|
||||
if (remaining != null) {
|
||||
if (remaining <= 0) {
|
||||
joinEnforcementTicks.remove(uuid);
|
||||
} else {
|
||||
if (remaining % JOIN_ENFORCEMENT_INTERVAL_TICKS == 0) {
|
||||
applyConfiguredMode(player, dimension, true);
|
||||
}
|
||||
joinEnforcementTicks.put(uuid, remaining - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Selama beberapa detik pertama setelah login, gamemode dikoreksi berulang.
|
||||
* Ini sengaja dibuat sebagai stabilization window karena vanilla player-data
|
||||
* maupun mod lain dapat menerapkan state player sedikit lebih lambat dari event JOIN.
|
||||
* Setelah window selesai, player tidak terus-menerus dipaksa kecuali berpindah dimension.
|
||||
*/
|
||||
public void beginJoinEnforcement(UUID uuid) {
|
||||
joinEnforcementTicks.put(uuid, JOIN_ENFORCEMENT_DURATION_TICKS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Memaksa gamemode yang dikonfigurasi untuk dimension player saat ini.
|
||||
* Dipakai setelah teleport agar join/reconnect tidak bergantung hanya pada
|
||||
@@ -99,6 +126,7 @@ public final class DimensionGameModeManager {
|
||||
|
||||
public void onDisconnect(UUID uuid) {
|
||||
lastDimension.remove(uuid);
|
||||
joinEnforcementTicks.remove(uuid);
|
||||
}
|
||||
|
||||
public String get(String dimension) {
|
||||
|
||||
@@ -134,6 +134,13 @@ public final class LobbySystemsMod implements ModInitializer {
|
||||
server.execute(() -> {
|
||||
POSITIONS.captureCurrent(player);
|
||||
TELEPORTS.scheduleJoinToLobby(player);
|
||||
if (CONFIG.get().manageDimensionGamemode) {
|
||||
// Terapkan segera pada state player yang sudah dimuat, lalu pertahankan
|
||||
// stabilization window agar state login yang diterapkan terlambat oleh
|
||||
// vanilla/mod lain tidak mengalahkan konfigurasi Lobby Systems.
|
||||
DIMENSION_GAMEMODES.applyForPlayer(player, true);
|
||||
DIMENSION_GAMEMODES.beginJoinEnforcement(player.getUUID());
|
||||
}
|
||||
LobbyLog.state(
|
||||
"PLAYER JOIN",
|
||||
"Player: " + player.getName().getString(),
|
||||
|
||||
Reference in New Issue
Block a user