Skip to content

Instantly share code, notes, and snippets.

@ProgrammerDan
Forked from aadnk/TeleportFix.java
Created November 11, 2016 15:25
Show Gist options
  • Save ProgrammerDan/42e3bd930bd7ca1e7ef1380fc8955ce7 to your computer and use it in GitHub Desktop.
Save ProgrammerDan/42e3bd930bd7ca1e7ef1380fc8955ce7 to your computer and use it in GitHub Desktop.
Bukkit Teleport Invisibility Fix
package com.comphenix.example;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.server.EntityPlayer;
import net.minecraft.server.EntityTracker;
import net.minecraft.server.EntityTrackerEntry;
import net.minecraft.server.WorldServer;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.plugin.Plugin;
public class TeleportFix implements Listener {
private Server server;
private Plugin plugin;
// Try increasing this. May be dependent on lag.
private final int TELEPORT_FIX_DELAY = 15; // ticks
public TeleportFix(Plugin plugin, Server server) {
this.plugin = plugin;
this.server = server;
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerTeleport(PlayerTeleportEvent event) {
final Player player = event.getPlayer();
final int visibleDistance = server.getViewDistance() * 16;
// Fix the visibility issue one tick later
server.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
// Refresh nearby clients
updateEntities(getPlayersWithin(player, visibleDistance));
System.out.println("Applying fix ... " + visibleDistance);
}
}, TELEPORT_FIX_DELAY);
}
public void updateEntities(List<Player> observers) {
// Refresh every single player
for (Player player : observers) {
updateEntity(player, observers);
}
}
@SuppressWarnings("unchecked")
public void updateEntity(Entity entity, List<Player> observers) {
World world = entity.getWorld();
WorldServer worldServer = ((CraftWorld) world).getHandle();
EntityTracker tracker = worldServer.tracker;
EntityTrackerEntry entry = (EntityTrackerEntry) tracker.trackedEntities
.get(entity.getEntityId());
List<EntityPlayer> nmsPlayers = getNmsPlayers(observers);
// Force Minecraft to resend packets to the affected clients
entry.trackedPlayers.removeAll(nmsPlayers);
entry.scanPlayers(nmsPlayers);
}
private List<EntityPlayer> getNmsPlayers(List<Player> players) {
List<EntityPlayer> nsmPlayers = new ArrayList<EntityPlayer>();
for (Player bukkitPlayer : players) {
CraftPlayer craftPlayer = (CraftPlayer) bukkitPlayer;
nsmPlayers.add(craftPlayer.getHandle());
}
return nsmPlayers;
}
private List<Player> getPlayersWithin(Player player, int distance) {
List<Player> res = new ArrayList<Player>();
int d2 = distance * distance;
for (Player p : server.getOnlinePlayers()) {
if (p.getWorld() == player.getWorld()
&& p.getLocation().distanceSquared(player.getLocation()) <= d2) {
res.add(p);
}
}
return res;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment