Skip to content

Commit

Permalink
Fix flight state between world teleports
Browse files Browse the repository at this point in the history
Thanks to @electronicboy for the general fix
Fixes EssentialsX#4325

Co-authored-by: Shane Freeder <[email protected]>
  • Loading branch information
JRoy and electronicboy committed Jan 19, 2025
1 parent 803771e commit b37d1ee
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
import net.ess3.provider.providers.PaperRecipeBookListener;
import net.ess3.provider.providers.PaperSerializationProvider;
import net.ess3.provider.providers.PaperServerStateProvider;
import net.ess3.provider.providers.PaperTickCountProvider;
import net.ess3.provider.providers.PrehistoricPotionMetaProvider;
import net.essentialsx.api.v2.services.BalanceTop;
import net.essentialsx.api.v2.services.mail.MailService;
Expand Down Expand Up @@ -421,6 +422,9 @@ public void onEnable() {
// Biome Key Provider
providerFactory.registerProvider(PaperBiomeKeyProvider.class);

// Tick Count Provider
providerFactory.registerProvider(PaperTickCountProvider.class);

providerFactory.finalizeRegistration();

// Event Providers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import net.ess3.provider.FormattedCommandAliasProvider;
import net.ess3.provider.InventoryViewProvider;
import net.ess3.provider.KnownCommandsProvider;
import net.ess3.provider.TickCountProvider;
import net.ess3.provider.providers.BukkitCommandSendListenerProvider;
import net.ess3.provider.providers.PaperCommandSendListenerProvider;
import net.essentialsx.api.v2.events.AsyncUserDataLoadEvent;
Expand Down Expand Up @@ -588,6 +589,17 @@ public void onPlayerTeleport(final PlayerTeleportEvent event) {
if (ess.getSettings().isTeleportInvulnerability()) {
user.enableInvulnerabilityAfterTeleport();
}

// Mitigation for https://github.com/EssentialsX/Essentials/issues/4325
final TickCountProvider tickCountProvider = ess.provider(TickCountProvider.class);
if (tickCountProvider != null && ess.getSettings().isWorldChangePreserveFlying() && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_17_R01)) {
if (user.isAuthorized("essentials.fly")) {
//noinspection DataFlowIssue - not real
if (event.getFrom().getWorld() != event.getTo().getWorld() && player.isFlying()) {
user.setFlightTick(tickCountProvider.getTickCount());
}
}
}
}

@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
Expand Down Expand Up @@ -741,8 +753,7 @@ public void onPlayerChangedWorldFlyReset(final PlayerChangedWorldEvent event) {

if (ess.getSettings().isWorldChangeFlyResetEnabled()) {
if (user.getBase().getGameMode() != GameMode.CREATIVE
// COMPAT: String compare for 1.7.10
&& !user.getBase().getGameMode().name().equals("SPECTATOR")
&& user.getBase().getGameMode() != GameMode.SPECTATOR
&& !user.isAuthorized("essentials.fly")) {
user.getBase().setFallDistance(0f);
user.getBase().setAllowFlight(false);
Expand All @@ -765,6 +776,13 @@ public void onPlayerChangedWorldFlyReset(final PlayerChangedWorldEvent event) {
}
}
}

final TickCountProvider tickCountProvider = ess.provider(TickCountProvider.class);
if (tickCountProvider != null && user.getFlightTick() == tickCountProvider.getTickCount()) {
user.getBase().setAllowFlight(true);
user.getBase().setFlying(true);
}
user.setFlightTick(-1);
}

@EventHandler(priority = EventPriority.MONITOR)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,8 @@ public interface ISettings extends IConf {

boolean isWorldChangeFlyResetEnabled();

boolean isWorldChangePreserveFlying();

boolean isWorldChangeSpeedResetEnabled();

long getCommandCooldownMs(String label);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1919,6 +1919,11 @@ public boolean isWorldChangeFlyResetEnabled() {
return config.getBoolean("world-change-fly-reset", true);
}

@Override
public boolean isWorldChangePreserveFlying() {
return config.getBoolean("world-change-preserve-flying", true);
}

@Override
public boolean isWorldChangeSpeedResetEnabled() {
return config.getBoolean("world-change-speed-reset", true);
Expand Down
9 changes: 9 additions & 0 deletions Essentials/src/main/java/com/earth2me/essentials/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
// Misc
private transient final List<String> signCopy = Lists.newArrayList("", "", "", "");
private transient long lastVanishTime = System.currentTimeMillis();
private transient int flightTick = -1;
private String lastLocaleString;
private Locale playerLocale;

Expand Down Expand Up @@ -1299,4 +1300,12 @@ public boolean isToggleShout() {
}
return toggleShout == null ? toggleShout = ess.getSettings().isShoutDefault() : toggleShout;
}

public int getFlightTick() {
return flightTick;
}

public void setFlightTick(int flightTick) {
this.flightTick = flightTick;
}
}
5 changes: 5 additions & 0 deletions Essentials/src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,11 @@ socialspy-uses-displaynames: true
# This will disable flight if the player does not have essentials.fly.
world-change-fly-reset: true

# Starting in 1.17, Minecraft no longer preserves the abilities of a player when they change worlds.
# Setting this to true will make EssentialsX preserve if users flying when they change worlds.
# This will only work if the player has the essentials.fly permission.
world-change-preserve-flying: true

# When a player changes world, should we reset their speed according to their permissions?
# This resets the player's speed to the default if they don't have essentials.speed.
# If the player doesn't have essentials.speed.bypass, this resets their speed to the maximum specified above.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package net.ess3.provider;

import net.essentialsx.providers.NullableProvider;

@NullableProvider
public interface TickCountProvider extends Provider {
int getTickCount();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package net.ess3.provider.providers;

import net.ess3.provider.TickCountProvider;
import net.essentialsx.providers.ProviderData;
import net.essentialsx.providers.ProviderTest;
import org.bukkit.Bukkit;

@ProviderData(description = "Paper Tick Count Provider")
public class PaperTickCountProvider implements TickCountProvider {
@Override
public int getTickCount() {
return Bukkit.getCurrentTick();
}

@ProviderTest
public static boolean test() {
try {
Bukkit.class.getDeclaredMethod("getCurrentTick");
return true;
} catch (final NoSuchMethodException ignored) {
return false;
}
}
}

0 comments on commit b37d1ee

Please sign in to comment.