when redstone torches or TNT were attempted to be placed in protected territory but prevented, it could previously still trigger a TNT explosion due to a longstanding unfixed CraftBukkit exploit. A workaround is now in place to prevent this, and any such attempts are logged and announced to everyone on the server.
For reference: https://bukkit.atlassian.net/browse/BUKKIT-89 also, added missed new java file for chat spy
This commit is contained in:
parent
fb32fc7f51
commit
336edd85be
40
src/com/massivecraft/factions/cmd/CmdChatSpy.java
Normal file
40
src/com/massivecraft/factions/cmd/CmdChatSpy.java
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package com.massivecraft.factions.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.factions.P;
|
||||||
|
import com.massivecraft.factions.struct.Permission;
|
||||||
|
|
||||||
|
public class CmdChatSpy extends FCommand
|
||||||
|
{
|
||||||
|
public CmdChatSpy()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
this.aliases.add("chatspy");
|
||||||
|
|
||||||
|
this.optionalArgs.put("on/off", "flip");
|
||||||
|
|
||||||
|
this.permission = Permission.CHATSPY.node;
|
||||||
|
this.disableOnLock = false;
|
||||||
|
|
||||||
|
senderMustBePlayer = true;
|
||||||
|
senderMustBeMember = false;
|
||||||
|
senderMustBeModerator = false;
|
||||||
|
senderMustBeAdmin = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform()
|
||||||
|
{
|
||||||
|
fme.setSpyingChat(this.argAsBool(0, ! fme.isSpyingChat()));
|
||||||
|
|
||||||
|
if ( fme.isSpyingChat())
|
||||||
|
{
|
||||||
|
fme.msg("<i>You have enabled chat spying mode.");
|
||||||
|
P.p.log(fme.getName() + " has ENABLED chat spying mode.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fme.msg("<i>You have disabled chat spying mode.");
|
||||||
|
P.p.log(fme.getName() + " DISABLED chat spying mode.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -45,6 +45,13 @@ public class FactionsBlockListener extends BlockListener
|
|||||||
if ( ! playerCanBuildDestroyBlock(event.getPlayer(), event.getBlock().getLocation(), "build", false))
|
if ( ! playerCanBuildDestroyBlock(event.getPlayer(), event.getBlock().getLocation(), "build", false))
|
||||||
{
|
{
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
|
|
||||||
|
Material handItem = event.getPlayer().getItemInHand().getType();
|
||||||
|
if (handItem == Material.TNT || handItem == Material.REDSTONE_TORCH_ON)
|
||||||
|
{
|
||||||
|
Faction targetFaction = Board.getFactionAt(new FLocation(event.getBlock()));
|
||||||
|
FactionsEntityListener.trackPotentialExplosionExploit(event.getPlayer().getName(), targetFaction, handItem, event.getBlock().getLocation());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,13 +50,13 @@ public class FactionsChatEarlyListener extends PlayerListener
|
|||||||
String message = String.format(Conf.factionChatFormat, me.describeTo(myFaction), msg);
|
String message = String.format(Conf.factionChatFormat, me.describeTo(myFaction), msg);
|
||||||
myFaction.sendMessage(message);
|
myFaction.sendMessage(message);
|
||||||
|
|
||||||
P.p.log(Level.INFO, ChatColor.stripColor("FactionChat "+me.getFaction().getTag()+": "+message));
|
P.p.log(Level.INFO, ChatColor.stripColor("FactionChat "+myFaction.getTag()+": "+message));
|
||||||
|
|
||||||
//Send to any players who are spying chat
|
//Send to any players who are spying chat
|
||||||
for (FPlayer fplayer : FPlayers.i.getOnline())
|
for (FPlayer fplayer : FPlayers.i.getOnline())
|
||||||
{
|
{
|
||||||
if(fplayer.isSpyingChat() && fplayer.getFaction() != myFaction)
|
if(fplayer.isSpyingChat() && fplayer.getFaction() != myFaction)
|
||||||
fplayer.sendMessage("[FCspy] "+me.getFaction().getTag()+": "+message);
|
fplayer.sendMessage("[FCspy] "+myFaction.getTag()+": "+message);
|
||||||
}
|
}
|
||||||
|
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
package com.massivecraft.factions.listeners;
|
package com.massivecraft.factions.listeners;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Creeper;
|
import org.bukkit.entity.Creeper;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Fireball;
|
import org.bukkit.entity.Fireball;
|
||||||
@ -40,6 +43,8 @@ public class FactionsEntityListener extends EntityListener
|
|||||||
this.p = p;
|
this.p = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ArrayList<PotentialExplosionExploit> exploitExplosions = new ArrayList<PotentialExplosionExploit>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEntityDeath(EntityDeathEvent event)
|
public void onEntityDeath(EntityDeathEvent event)
|
||||||
{
|
{
|
||||||
@ -164,39 +169,76 @@ public class FactionsEntityListener extends EntityListener
|
|||||||
// ghast fireball which needs prevention
|
// ghast fireball which needs prevention
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
else if
|
else
|
||||||
(
|
{ // TNT
|
||||||
|
if (exploitExplosions.size() > 0)
|
||||||
|
{ // make sure this isn't a TNT explosion exploit attempt
|
||||||
|
int locX = event.getLocation().getBlockX();
|
||||||
|
int locZ = event.getLocation().getBlockZ();
|
||||||
|
|
||||||
|
for (int i = exploitExplosions.size() - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
PotentialExplosionExploit ex = exploitExplosions.get(i);
|
||||||
|
|
||||||
|
// remove anything from the list older than 10 seconds (TNT takes 4 seconds to trigger; provide some leeway)
|
||||||
|
if (ex.timeMillis + 10000 < System.currentTimeMillis())
|
||||||
|
{
|
||||||
|
exploitExplosions.remove(i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int absX = Math.abs(ex.X - locX);
|
||||||
|
int absZ = Math.abs(ex.Z - locZ);
|
||||||
|
if (absX < 5 && absZ < 5)
|
||||||
|
{ // it sure looks like an exploit attempt
|
||||||
|
// let's tattle on him to everyone
|
||||||
|
String msg = "NOTICE: Player \""+ex.playerName+"\" attempted to exploit a TNT bug in the territory of \""+ex.faction.getTag()+"\" at "+ex.X+","+ex.Z+" (X,Z) using "+ex.item.name();
|
||||||
|
P.p.log(Level.WARNING, msg);
|
||||||
|
for (FPlayer fplayer : FPlayers.i.getOnline())
|
||||||
|
{
|
||||||
|
fplayer.sendMessage(msg);
|
||||||
|
}
|
||||||
|
event.setCancelled(true);
|
||||||
|
exploitExplosions.remove(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if
|
||||||
(
|
(
|
||||||
faction.isNone()
|
|
||||||
&&
|
|
||||||
Conf.wildernessBlockTNT
|
|
||||||
&&
|
|
||||||
! Conf.worldsNoWildernessProtection.contains(loc.getWorld().getName())
|
|
||||||
)
|
|
||||||
||
|
|
||||||
(
|
|
||||||
faction.isNormal()
|
|
||||||
&&
|
|
||||||
(
|
(
|
||||||
online ? Conf.territoryBlockTNT : Conf.territoryBlockTNTWhenOffline
|
faction.isNone()
|
||||||
|
&&
|
||||||
|
Conf.wildernessBlockTNT
|
||||||
|
&&
|
||||||
|
! Conf.worldsNoWildernessProtection.contains(loc.getWorld().getName())
|
||||||
|
)
|
||||||
|
||
|
||||||
|
(
|
||||||
|
faction.isNormal()
|
||||||
|
&&
|
||||||
|
(
|
||||||
|
online ? Conf.territoryBlockTNT : Conf.territoryBlockTNTWhenOffline
|
||||||
|
)
|
||||||
|
)
|
||||||
|
||
|
||||||
|
(
|
||||||
|
faction.isWarZone()
|
||||||
|
&&
|
||||||
|
Conf.warZoneBlockTNT
|
||||||
|
)
|
||||||
|
||
|
||||||
|
(
|
||||||
|
faction.isSafeZone()
|
||||||
|
&&
|
||||||
|
Conf.safeZoneBlockTNT
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
||
|
{
|
||||||
(
|
// we'll assume it's TNT, which needs prevention
|
||||||
faction.isWarZone()
|
event.setCancelled(true);
|
||||||
&&
|
}
|
||||||
Conf.warZoneBlockTNT
|
|
||||||
)
|
|
||||||
||
|
|
||||||
(
|
|
||||||
faction.isSafeZone()
|
|
||||||
&&
|
|
||||||
Conf.safeZoneBlockTNT
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// we'll assume it's TNT, which needs prevention
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,4 +548,38 @@ public class FactionsEntityListener extends EntityListener
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Since the Bukkit team still don't seem to be in any hurry to fix the problem after at least half a year,
|
||||||
|
* we'll track potential explosion exploits ourselves and try to prevent them
|
||||||
|
* For reference, canceled TNT placement next to redstone power is bugged and triggers a free explosion
|
||||||
|
* Same thing happens for canceled redstone torch placement next to existing TNT
|
||||||
|
* https://bukkit.atlassian.net/browse/BUKKIT-89
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static void trackPotentialExplosionExploit(String playerName, Faction faction, Material item, Location location)
|
||||||
|
{
|
||||||
|
exploitExplosions.add(new PotentialExplosionExploit(playerName, faction, item, location));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PotentialExplosionExploit
|
||||||
|
{
|
||||||
|
public String playerName;
|
||||||
|
public Faction faction;
|
||||||
|
public Material item;
|
||||||
|
public long timeMillis;
|
||||||
|
public int X;
|
||||||
|
public int Z;
|
||||||
|
|
||||||
|
public PotentialExplosionExploit(String playerName, Faction faction, Material item, Location location)
|
||||||
|
{
|
||||||
|
this.playerName = playerName;
|
||||||
|
this.faction = faction;
|
||||||
|
this.item = item;
|
||||||
|
this.timeMillis = System.currentTimeMillis();
|
||||||
|
this.X = location.getBlockX();
|
||||||
|
this.Z = location.getBlockZ();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user