mirror of
https://github.com/PryPurity/WorldBorder.git
synced 2024-06-24 10:05:01 +02:00
Fix for problem in recent dev builds of CraftBukkit for Minecraft 1.6.1, which would lead to spammed errors in the log file and potentially a server crash sometimes when a person crossed the border. This problem occurred most when riding horses and boats.
This commit is contained in:
parent
5d745ca788
commit
fa23da50f3
|
@ -1,8 +1,11 @@
|
||||||
package com.wimbli.WorldBorder;
|
package com.wimbli.WorldBorder;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Effect;
|
|
||||||
import org.bukkit.entity.Boat;
|
import org.bukkit.entity.Boat;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
|
@ -15,6 +18,7 @@ import org.bukkit.World;
|
||||||
|
|
||||||
public class BorderCheckTask implements Runnable
|
public class BorderCheckTask implements Runnable
|
||||||
{
|
{
|
||||||
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
// if knockback is set to 0, simply return
|
// if knockback is set to 0, simply return
|
||||||
|
@ -28,6 +32,9 @@ public class BorderCheckTask implements Runnable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// track players who are being handled (moved back inside the border) already; needed since Bukkit is sometimes sending teleport events with the old (now incorrect) location still indicated, which can lead to a loop when we then teleport them thinking they're outside the border, triggering event again, etc.
|
||||||
|
private static Set<String> handlingPlayers = Collections.synchronizedSet(new LinkedHashSet<String>());
|
||||||
|
|
||||||
// set targetLoc only if not current player location; set returnLocationOnly to true to have new Location returned if they need to be moved to one, instead of directly handling it
|
// set targetLoc only if not current player location; set returnLocationOnly to true to have new Location returned if they need to be moved to one, instead of directly handling it
|
||||||
public static Location checkPlayer(Player player, Location targetLoc, boolean returnLocationOnly, boolean notify)
|
public static Location checkPlayer(Player player, Location targetLoc, boolean returnLocationOnly, boolean notify)
|
||||||
{
|
{
|
||||||
|
@ -44,10 +51,16 @@ public class BorderCheckTask implements Runnable
|
||||||
if (border.insideBorder(loc.getX(), loc.getZ(), Config.ShapeRound()))
|
if (border.insideBorder(loc.getX(), loc.getZ(), Config.ShapeRound()))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// if player is in bypass list (from bypass command), allow them beyond border
|
// if player is in bypass list (from bypass command), allow them beyond border; also ignore players currently being handled already
|
||||||
if (Config.isPlayerBypassing(player.getName()))
|
if (Config.isPlayerBypassing(player.getName()) || handlingPlayers.contains(player.getName().toLowerCase()))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
// tag this player as being handled so we can't get stuck in a loop due to Bukkit currently sometimes repeatedly providing incorrect location through teleport event
|
||||||
|
handlingPlayers.add(player.getName().toLowerCase());
|
||||||
|
|
||||||
|
Location newLoc = newLocation(player, loc, border, notify);
|
||||||
|
boolean handlingVehicle = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* since we need to forcibly eject players who are inside vehicles, that fires a teleport event (go figure) and
|
* since we need to forcibly eject players who are inside vehicles, that fires a teleport event (go figure) and
|
||||||
* so would effectively double trigger for us, so we need to handle it here to prevent sending two messages and
|
* so would effectively double trigger for us, so we need to handle it here to prevent sending two messages and
|
||||||
|
@ -57,44 +70,42 @@ public class BorderCheckTask implements Runnable
|
||||||
*/
|
*/
|
||||||
if (player.isInsideVehicle())
|
if (player.isInsideVehicle())
|
||||||
{
|
{
|
||||||
Location newLoc = newLocation(player, loc, border, false);
|
|
||||||
Entity ride = player.getVehicle();
|
Entity ride = player.getVehicle();
|
||||||
player.leaveVehicle();
|
player.leaveVehicle();
|
||||||
if (ride != null)
|
if (ride != null)
|
||||||
{ // vehicles need to be offset vertically and have velocity stopped
|
{ // vehicles need to be offset vertically and have velocity stopped
|
||||||
double vertOffset = (ride instanceof LivingEntity) ? 0 : ride.getLocation().getY() - loc.getY();
|
double vertOffset = (ride instanceof LivingEntity) ? 0 : ride.getLocation().getY() - loc.getY();
|
||||||
newLoc.setY(newLoc.getY() + vertOffset);
|
Location rideLoc = newLoc.clone();
|
||||||
|
rideLoc.setY(newLoc.getY() + vertOffset);
|
||||||
|
if (Config.Debug())
|
||||||
|
Config.LogWarn("Player was riding a \"" + ride.toString() + "\".");
|
||||||
if (ride instanceof Boat)
|
if (ride instanceof Boat)
|
||||||
{ // boats currently glitch on client when teleported, so crappy workaround is to remove it and spawn a new one
|
{ // boats currently glitch on client when teleported, so crappy workaround is to remove it and spawn a new one
|
||||||
ride.remove();
|
ride.remove();
|
||||||
ride = world.spawnEntity(newLoc, EntityType.BOAT);
|
ride = world.spawnEntity(rideLoc, EntityType.BOAT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ride.setVelocity(new Vector(0, 0, 0));
|
ride.setVelocity(new Vector(0, 0, 0));
|
||||||
ride.teleport(newLoc);
|
ride.teleport(rideLoc);
|
||||||
}
|
}
|
||||||
setPassengerDelayed(ride, player, 10);
|
setPassengerDelayed(ride, player, player.getName(), 10);
|
||||||
|
handlingVehicle = true;
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Location newLoc = newLocation(player, loc, border, notify);
|
// give some particle and sound effects where the player was beyond the border, if "whoosh effect" is enabled
|
||||||
|
Config.showWhooshEffect(loc);
|
||||||
|
|
||||||
if (Config.whooshEffect())
|
if (!returnLocationOnly)
|
||||||
{ // give some particle and sound effects where the player was beyond the border
|
player.teleport(newLoc);
|
||||||
world.playEffect(loc, Effect.ENDER_SIGNAL, 0);
|
|
||||||
world.playEffect(loc, Effect.ENDER_SIGNAL, 0);
|
if (!handlingVehicle)
|
||||||
world.playEffect(loc, Effect.SMOKE, 4);
|
handlingPlayers.remove(player.getName().toLowerCase());
|
||||||
world.playEffect(loc, Effect.SMOKE, 4);
|
|
||||||
world.playEffect(loc, Effect.SMOKE, 4);
|
|
||||||
world.playEffect(loc, Effect.GHAST_SHOOT, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (returnLocationOnly)
|
if (returnLocationOnly)
|
||||||
return newLoc;
|
return newLoc;
|
||||||
|
|
||||||
player.teleport(newLoc);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
public static Location checkPlayer(Player player, Location targetLoc, boolean returnLocationOnly)
|
public static Location checkPlayer(Player player, Location targetLoc, boolean returnLocationOnly)
|
||||||
|
@ -129,13 +140,17 @@ public class BorderCheckTask implements Runnable
|
||||||
return newLoc;
|
return newLoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setPassengerDelayed(final Entity vehicle, final Player player, long delay)
|
private static void setPassengerDelayed(final Entity vehicle, final Player player, final String playerName, long delay)
|
||||||
{
|
{
|
||||||
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(WorldBorder.plugin, new Runnable()
|
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(WorldBorder.plugin, new Runnable()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
|
handlingPlayers.remove(playerName.toLowerCase());
|
||||||
|
if (vehicle == null || player == null)
|
||||||
|
return;
|
||||||
|
|
||||||
vehicle.setPassenger(player);
|
vehicle.setPassenger(player);
|
||||||
}
|
}
|
||||||
}, delay);
|
}, delay);
|
||||||
|
|
|
@ -18,6 +18,9 @@ public class WBListener implements Listener
|
||||||
if (Config.KnockBack() == 0.0)
|
if (Config.KnockBack() == 0.0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (Config.Debug())
|
||||||
|
Config.LogWarn("Teleport cause: "+event.getCause().toString());
|
||||||
|
|
||||||
Location newLoc = BorderCheckTask.checkPlayer(event.getPlayer(), event.getTo(), true, true);
|
Location newLoc = BorderCheckTask.checkPlayer(event.getPlayer(), event.getTo(), true, true);
|
||||||
if (newLoc != null)
|
if (newLoc != null)
|
||||||
event.setTo(newLoc);
|
event.setTo(newLoc);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user